| 1 | /*
|
|---|
| 2 | * Store and retrieve mechanism.
|
|---|
| 3 | *
|
|---|
| 4 | * Copyright (c) 1995-2000, Raphael Manfredi
|
|---|
| 5 | *
|
|---|
| 6 | * You may redistribute only under the same terms as Perl 5, as specified
|
|---|
| 7 | * in the README file that comes with the distribution.
|
|---|
| 8 | *
|
|---|
| 9 | */
|
|---|
| 10 |
|
|---|
| 11 | #define PERL_NO_GET_CONTEXT /* we want efficiency */
|
|---|
| 12 | #include <EXTERN.h>
|
|---|
| 13 | #include <perl.h>
|
|---|
| 14 | #include <XSUB.h>
|
|---|
| 15 |
|
|---|
| 16 | #ifndef PATCHLEVEL
|
|---|
| 17 | #include <patchlevel.h> /* Perl's one, needed since 5.6 */
|
|---|
| 18 | #endif
|
|---|
| 19 |
|
|---|
| 20 | #if !defined(PERL_VERSION) || PERL_VERSION < 8
|
|---|
| 21 | #include "ppport.h" /* handle old perls */
|
|---|
| 22 | #endif
|
|---|
| 23 |
|
|---|
| 24 | #if 0
|
|---|
| 25 | #define DEBUGME /* Debug mode, turns assertions on as well */
|
|---|
| 26 | #define DASSERT /* Assertion mode */
|
|---|
| 27 | #endif
|
|---|
| 28 |
|
|---|
| 29 | /*
|
|---|
| 30 | * Pre PerlIO time when none of USE_PERLIO and PERLIO_IS_STDIO is defined
|
|---|
| 31 | * Provide them with the necessary defines so they can build with pre-5.004.
|
|---|
| 32 | */
|
|---|
| 33 | #ifndef USE_PERLIO
|
|---|
| 34 | #ifndef PERLIO_IS_STDIO
|
|---|
| 35 | #define PerlIO FILE
|
|---|
| 36 | #define PerlIO_getc(x) getc(x)
|
|---|
| 37 | #define PerlIO_putc(f,x) putc(x,f)
|
|---|
| 38 | #define PerlIO_read(x,y,z) fread(y,1,z,x)
|
|---|
| 39 | #define PerlIO_write(x,y,z) fwrite(y,1,z,x)
|
|---|
| 40 | #define PerlIO_stdoutf printf
|
|---|
| 41 | #endif /* PERLIO_IS_STDIO */
|
|---|
| 42 | #endif /* USE_PERLIO */
|
|---|
| 43 |
|
|---|
| 44 | /*
|
|---|
| 45 | * Earlier versions of perl might be used, we can't assume they have the latest!
|
|---|
| 46 | */
|
|---|
| 47 |
|
|---|
| 48 | #ifndef PERL_VERSION /* For perls < 5.6 */
|
|---|
| 49 | #define PERL_VERSION PATCHLEVEL
|
|---|
| 50 | #ifndef newRV_noinc
|
|---|
| 51 | #define newRV_noinc(sv) ((Sv = newRV(sv)), --SvREFCNT(SvRV(Sv)), Sv)
|
|---|
| 52 | #endif
|
|---|
| 53 | #if (PATCHLEVEL <= 4) /* Older perls (<= 5.004) lack PL_ namespace */
|
|---|
| 54 | #define PL_sv_yes sv_yes
|
|---|
| 55 | #define PL_sv_no sv_no
|
|---|
| 56 | #define PL_sv_undef sv_undef
|
|---|
| 57 | #if (SUBVERSION <= 4) /* 5.004_04 has been reported to lack newSVpvn */
|
|---|
| 58 | #define newSVpvn newSVpv
|
|---|
| 59 | #endif
|
|---|
| 60 | #endif /* PATCHLEVEL <= 4 */
|
|---|
| 61 | #ifndef HvSHAREKEYS_off
|
|---|
| 62 | #define HvSHAREKEYS_off(hv) /* Ignore */
|
|---|
| 63 | #endif
|
|---|
| 64 | #ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */
|
|---|
| 65 | #define AvFILLp AvFILL
|
|---|
| 66 | #endif
|
|---|
| 67 | typedef double NV; /* Older perls lack the NV type */
|
|---|
| 68 | #define IVdf "ld" /* Various printf formats for Perl types */
|
|---|
| 69 | #define UVuf "lu"
|
|---|
| 70 | #define UVof "lo"
|
|---|
| 71 | #define UVxf "lx"
|
|---|
| 72 | #define INT2PTR(t,v) (t)(IV)(v)
|
|---|
| 73 | #define PTR2UV(v) (unsigned long)(v)
|
|---|
| 74 | #endif /* PERL_VERSION -- perls < 5.6 */
|
|---|
| 75 |
|
|---|
| 76 | #ifndef NVef /* The following were not part of perl 5.6 */
|
|---|
| 77 | #if defined(USE_LONG_DOUBLE) && \
|
|---|
| 78 | defined(HAS_LONG_DOUBLE) && defined(PERL_PRIfldbl)
|
|---|
| 79 | #define NVef PERL_PRIeldbl
|
|---|
| 80 | #define NVff PERL_PRIfldbl
|
|---|
| 81 | #define NVgf PERL_PRIgldbl
|
|---|
| 82 | #else
|
|---|
| 83 | #define NVef "e"
|
|---|
| 84 | #define NVff "f"
|
|---|
| 85 | #define NVgf "g"
|
|---|
| 86 | #endif
|
|---|
| 87 | #endif
|
|---|
| 88 |
|
|---|
| 89 | #ifndef SvRV_set
|
|---|
| 90 | #define SvRV_set(sv, val) \
|
|---|
| 91 | STMT_START { \
|
|---|
| 92 | assert(SvTYPE(sv) >= SVt_RV); \
|
|---|
| 93 | (((XRV*)SvANY(sv))->xrv_rv = (val)); \
|
|---|
| 94 | } STMT_END
|
|---|
| 95 | #endif
|
|---|
| 96 |
|
|---|
| 97 | #ifndef PERL_UNUSED_DECL
|
|---|
| 98 | # ifdef HASATTRIBUTE
|
|---|
| 99 | # if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER)
|
|---|
| 100 | # define PERL_UNUSED_DECL
|
|---|
| 101 | # else
|
|---|
| 102 | # define PERL_UNUSED_DECL __attribute__((unused))
|
|---|
| 103 | # endif
|
|---|
| 104 | # else
|
|---|
| 105 | # define PERL_UNUSED_DECL
|
|---|
| 106 | # endif
|
|---|
| 107 | #endif
|
|---|
| 108 |
|
|---|
| 109 | #ifndef dNOOP
|
|---|
| 110 | #define dNOOP extern int Perl___notused PERL_UNUSED_DECL
|
|---|
| 111 | #endif
|
|---|
| 112 |
|
|---|
| 113 | #ifndef dVAR
|
|---|
| 114 | #define dVAR dNOOP
|
|---|
| 115 | #endif
|
|---|
| 116 |
|
|---|
| 117 | #ifndef HvRITER_set
|
|---|
| 118 | # define HvRITER_set(hv,r) (HvRITER(hv) = r)
|
|---|
| 119 | #endif
|
|---|
| 120 | #ifndef HvEITER_set
|
|---|
| 121 | # define HvEITER_set(hv,r) (HvEITER(hv) = r)
|
|---|
| 122 | #endif
|
|---|
| 123 |
|
|---|
| 124 | #ifndef HvRITER_get
|
|---|
| 125 | # define HvRITER_get HvRITER
|
|---|
| 126 | #endif
|
|---|
| 127 | #ifndef HvEITER_get
|
|---|
| 128 | # define HvEITER_get HvEITER
|
|---|
| 129 | #endif
|
|---|
| 130 |
|
|---|
| 131 | #ifndef HvNAME_get
|
|---|
| 132 | #define HvNAME_get HvNAME
|
|---|
| 133 | #endif
|
|---|
| 134 |
|
|---|
| 135 | #ifndef HvPLACEHOLDERS_get
|
|---|
| 136 | # define HvPLACEHOLDERS_get HvPLACEHOLDERS
|
|---|
| 137 | #endif
|
|---|
| 138 |
|
|---|
| 139 | #ifdef DEBUGME
|
|---|
| 140 |
|
|---|
| 141 | #ifndef DASSERT
|
|---|
| 142 | #define DASSERT
|
|---|
| 143 | #endif
|
|---|
| 144 |
|
|---|
| 145 | /*
|
|---|
| 146 | * TRACEME() will only output things when the $Storable::DEBUGME is true.
|
|---|
| 147 | */
|
|---|
| 148 |
|
|---|
| 149 | #define TRACEME(x) \
|
|---|
| 150 | STMT_START { \
|
|---|
| 151 | if (SvTRUE(perl_get_sv("Storable::DEBUGME", TRUE))) \
|
|---|
| 152 | { PerlIO_stdoutf x; PerlIO_stdoutf("\n"); } \
|
|---|
| 153 | } STMT_END
|
|---|
| 154 | #else
|
|---|
| 155 | #define TRACEME(x)
|
|---|
| 156 | #endif /* DEBUGME */
|
|---|
| 157 |
|
|---|
| 158 | #ifdef DASSERT
|
|---|
| 159 | #define ASSERT(x,y) \
|
|---|
| 160 | STMT_START { \
|
|---|
| 161 | if (!(x)) { \
|
|---|
| 162 | PerlIO_stdoutf("ASSERT FAILED (\"%s\", line %d): ", \
|
|---|
| 163 | __FILE__, __LINE__); \
|
|---|
| 164 | PerlIO_stdoutf y; PerlIO_stdoutf("\n"); \
|
|---|
| 165 | } \
|
|---|
| 166 | } STMT_END
|
|---|
| 167 | #else
|
|---|
| 168 | #define ASSERT(x,y)
|
|---|
| 169 | #endif
|
|---|
| 170 |
|
|---|
| 171 | /*
|
|---|
| 172 | * Type markers.
|
|---|
| 173 | */
|
|---|
| 174 |
|
|---|
| 175 | #define C(x) ((char) (x)) /* For markers with dynamic retrieval handling */
|
|---|
| 176 |
|
|---|
| 177 | #define SX_OBJECT C(0) /* Already stored object */
|
|---|
| 178 | #define SX_LSCALAR C(1) /* Scalar (large binary) follows (length, data) */
|
|---|
| 179 | #define SX_ARRAY C(2) /* Array forthcominng (size, item list) */
|
|---|
| 180 | #define SX_HASH C(3) /* Hash forthcoming (size, key/value pair list) */
|
|---|
| 181 | #define SX_REF C(4) /* Reference to object forthcoming */
|
|---|
| 182 | #define SX_UNDEF C(5) /* Undefined scalar */
|
|---|
| 183 | #define SX_INTEGER C(6) /* Integer forthcoming */
|
|---|
| 184 | #define SX_DOUBLE C(7) /* Double forthcoming */
|
|---|
| 185 | #define SX_BYTE C(8) /* (signed) byte forthcoming */
|
|---|
| 186 | #define SX_NETINT C(9) /* Integer in network order forthcoming */
|
|---|
| 187 | #define SX_SCALAR C(10) /* Scalar (binary, small) follows (length, data) */
|
|---|
| 188 | #define SX_TIED_ARRAY C(11) /* Tied array forthcoming */
|
|---|
| 189 | #define SX_TIED_HASH C(12) /* Tied hash forthcoming */
|
|---|
| 190 | #define SX_TIED_SCALAR C(13) /* Tied scalar forthcoming */
|
|---|
| 191 | #define SX_SV_UNDEF C(14) /* Perl's immortal PL_sv_undef */
|
|---|
| 192 | #define SX_SV_YES C(15) /* Perl's immortal PL_sv_yes */
|
|---|
| 193 | #define SX_SV_NO C(16) /* Perl's immortal PL_sv_no */
|
|---|
| 194 | #define SX_BLESS C(17) /* Object is blessed */
|
|---|
| 195 | #define SX_IX_BLESS C(18) /* Object is blessed, classname given by index */
|
|---|
| 196 | #define SX_HOOK C(19) /* Stored via hook, user-defined */
|
|---|
| 197 | #define SX_OVERLOAD C(20) /* Overloaded reference */
|
|---|
| 198 | #define SX_TIED_KEY C(21) /* Tied magic key forthcoming */
|
|---|
| 199 | #define SX_TIED_IDX C(22) /* Tied magic index forthcoming */
|
|---|
| 200 | #define SX_UTF8STR C(23) /* UTF-8 string forthcoming (small) */
|
|---|
| 201 | #define SX_LUTF8STR C(24) /* UTF-8 string forthcoming (large) */
|
|---|
| 202 | #define SX_FLAG_HASH C(25) /* Hash with flags forthcoming (size, flags, key/flags/value triplet list) */
|
|---|
| 203 | #define SX_CODE C(26) /* Code references as perl source code */
|
|---|
| 204 | #define SX_WEAKREF C(27) /* Weak reference to object forthcoming */
|
|---|
| 205 | #define SX_WEAKOVERLOAD C(28) /* Overloaded weak reference */
|
|---|
| 206 | #define SX_ERROR C(29) /* Error */
|
|---|
| 207 |
|
|---|
| 208 | /*
|
|---|
| 209 | * Those are only used to retrieve "old" pre-0.6 binary images.
|
|---|
| 210 | */
|
|---|
| 211 | #define SX_ITEM 'i' /* An array item introducer */
|
|---|
| 212 | #define SX_IT_UNDEF 'I' /* Undefined array item */
|
|---|
| 213 | #define SX_KEY 'k' /* A hash key introducer */
|
|---|
| 214 | #define SX_VALUE 'v' /* A hash value introducer */
|
|---|
| 215 | #define SX_VL_UNDEF 'V' /* Undefined hash value */
|
|---|
| 216 |
|
|---|
| 217 | /*
|
|---|
| 218 | * Those are only used to retrieve "old" pre-0.7 binary images
|
|---|
| 219 | */
|
|---|
| 220 |
|
|---|
| 221 | #define SX_CLASS 'b' /* Object is blessed, class name length <255 */
|
|---|
| 222 | #define SX_LG_CLASS 'B' /* Object is blessed, class name length >255 */
|
|---|
| 223 | #define SX_STORED 'X' /* End of object */
|
|---|
| 224 |
|
|---|
| 225 | /*
|
|---|
| 226 | * Limits between short/long length representation.
|
|---|
| 227 | */
|
|---|
| 228 |
|
|---|
| 229 | #define LG_SCALAR 255 /* Large scalar length limit */
|
|---|
| 230 | #define LG_BLESS 127 /* Large classname bless limit */
|
|---|
| 231 |
|
|---|
| 232 | /*
|
|---|
| 233 | * Operation types
|
|---|
| 234 | */
|
|---|
| 235 |
|
|---|
| 236 | #define ST_STORE 0x1 /* Store operation */
|
|---|
| 237 | #define ST_RETRIEVE 0x2 /* Retrieval operation */
|
|---|
| 238 | #define ST_CLONE 0x4 /* Deep cloning operation */
|
|---|
| 239 |
|
|---|
| 240 | /*
|
|---|
| 241 | * The following structure is used for hash table key retrieval. Since, when
|
|---|
| 242 | * retrieving objects, we'll be facing blessed hash references, it's best
|
|---|
| 243 | * to pre-allocate that buffer once and resize it as the need arises, never
|
|---|
| 244 | * freeing it (keys will be saved away someplace else anyway, so even large
|
|---|
| 245 | * keys are not enough a motivation to reclaim that space).
|
|---|
| 246 | *
|
|---|
| 247 | * This structure is also used for memory store/retrieve operations which
|
|---|
| 248 | * happen in a fixed place before being malloc'ed elsewhere if persistency
|
|---|
| 249 | * is required. Hence the aptr pointer.
|
|---|
| 250 | */
|
|---|
| 251 | struct extendable {
|
|---|
| 252 | char *arena; /* Will hold hash key strings, resized as needed */
|
|---|
| 253 | STRLEN asiz; /* Size of aforementionned buffer */
|
|---|
| 254 | char *aptr; /* Arena pointer, for in-place read/write ops */
|
|---|
| 255 | char *aend; /* First invalid address */
|
|---|
| 256 | };
|
|---|
| 257 |
|
|---|
| 258 | /*
|
|---|
| 259 | * At store time:
|
|---|
| 260 | * A hash table records the objects which have already been stored.
|
|---|
| 261 | * Those are referred to as SX_OBJECT in the file, and their "tag" (i.e.
|
|---|
| 262 | * an arbitrary sequence number) is used to identify them.
|
|---|
| 263 | *
|
|---|
| 264 | * At retrieve time:
|
|---|
| 265 | * An array table records the objects which have already been retrieved,
|
|---|
| 266 | * as seen by the tag determind by counting the objects themselves. The
|
|---|
| 267 | * reference to that retrieved object is kept in the table, and is returned
|
|---|
| 268 | * when an SX_OBJECT is found bearing that same tag.
|
|---|
| 269 | *
|
|---|
| 270 | * The same processing is used to record "classname" for blessed objects:
|
|---|
| 271 | * indexing by a hash at store time, and via an array at retrieve time.
|
|---|
| 272 | */
|
|---|
| 273 |
|
|---|
| 274 | typedef unsigned long stag_t; /* Used by pre-0.6 binary format */
|
|---|
| 275 |
|
|---|
| 276 | /*
|
|---|
| 277 | * The following "thread-safe" related defines were contributed by
|
|---|
| 278 | * Murray Nesbitt <[email protected]> and integrated by RAM, who
|
|---|
| 279 | * only renamed things a little bit to ensure consistency with surrounding
|
|---|
| 280 | * code. -- RAM, 14/09/1999
|
|---|
| 281 | *
|
|---|
| 282 | * The original patch suffered from the fact that the stcxt_t structure
|
|---|
| 283 | * was global. Murray tried to minimize the impact on the code as much as
|
|---|
| 284 | * possible.
|
|---|
| 285 | *
|
|---|
| 286 | * Starting with 0.7, Storable can be re-entrant, via the STORABLE_xxx hooks
|
|---|
| 287 | * on objects. Therefore, the notion of context needs to be generalized,
|
|---|
| 288 | * threading or not.
|
|---|
| 289 | */
|
|---|
| 290 |
|
|---|
| 291 | #define MY_VERSION "Storable(" XS_VERSION ")"
|
|---|
| 292 |
|
|---|
| 293 |
|
|---|
| 294 | /*
|
|---|
| 295 | * Conditional UTF8 support.
|
|---|
| 296 | *
|
|---|
| 297 | */
|
|---|
| 298 | #ifdef SvUTF8_on
|
|---|
| 299 | #define STORE_UTF8STR(pv, len) STORE_PV_LEN(pv, len, SX_UTF8STR, SX_LUTF8STR)
|
|---|
| 300 | #define HAS_UTF8_SCALARS
|
|---|
| 301 | #ifdef HeKUTF8
|
|---|
| 302 | #define HAS_UTF8_HASHES
|
|---|
| 303 | #define HAS_UTF8_ALL
|
|---|
| 304 | #else
|
|---|
| 305 | /* 5.6 perl has utf8 scalars but not hashes */
|
|---|
| 306 | #endif
|
|---|
| 307 | #else
|
|---|
| 308 | #define SvUTF8(sv) 0
|
|---|
| 309 | #define STORE_UTF8STR(pv, len) CROAK(("panic: storing UTF8 in non-UTF8 perl"))
|
|---|
| 310 | #endif
|
|---|
| 311 | #ifndef HAS_UTF8_ALL
|
|---|
| 312 | #define UTF8_CROAK() CROAK(("Cannot retrieve UTF8 data in non-UTF8 perl"))
|
|---|
| 313 | #endif
|
|---|
| 314 | #ifndef SvWEAKREF
|
|---|
| 315 | #define WEAKREF_CROAK() CROAK(("Cannot retrieve weak references in this perl"))
|
|---|
| 316 | #endif
|
|---|
| 317 |
|
|---|
| 318 | #ifdef HvPLACEHOLDERS
|
|---|
| 319 | #define HAS_RESTRICTED_HASHES
|
|---|
| 320 | #else
|
|---|
| 321 | #define HVhek_PLACEHOLD 0x200
|
|---|
| 322 | #define RESTRICTED_HASH_CROAK() CROAK(("Cannot retrieve restricted hash"))
|
|---|
| 323 | #endif
|
|---|
| 324 |
|
|---|
| 325 | #ifdef HvHASKFLAGS
|
|---|
| 326 | #define HAS_HASH_KEY_FLAGS
|
|---|
| 327 | #endif
|
|---|
| 328 |
|
|---|
| 329 | #ifdef ptr_table_new
|
|---|
| 330 | #define USE_PTR_TABLE
|
|---|
| 331 | #endif
|
|---|
| 332 |
|
|---|
| 333 | /*
|
|---|
| 334 | * Fields s_tainted and s_dirty are prefixed with s_ because Perl's include
|
|---|
| 335 | * files remap tainted and dirty when threading is enabled. That's bad for
|
|---|
| 336 | * perl to remap such common words. -- RAM, 29/09/00
|
|---|
| 337 | */
|
|---|
| 338 |
|
|---|
| 339 | struct stcxt;
|
|---|
| 340 | typedef struct stcxt {
|
|---|
| 341 | int entry; /* flags recursion */
|
|---|
| 342 | int optype; /* type of traversal operation */
|
|---|
| 343 | /* which objects have been seen, store time.
|
|---|
| 344 | tags are numbers, which are cast to (SV *) and stored directly */
|
|---|
| 345 | #ifdef USE_PTR_TABLE
|
|---|
| 346 | /* use pseen if we have ptr_tables. We have to store tag+1, because
|
|---|
| 347 | tag numbers start at 0, and we can't store (SV *) 0 in a ptr_table
|
|---|
| 348 | without it being confused for a fetch lookup failure. */
|
|---|
| 349 | struct ptr_tbl *pseen;
|
|---|
| 350 | /* Still need hseen for the 0.6 file format code. */
|
|---|
| 351 | #endif
|
|---|
| 352 | HV *hseen;
|
|---|
| 353 | AV *hook_seen; /* which SVs were returned by STORABLE_freeze() */
|
|---|
| 354 | AV *aseen; /* which objects have been seen, retrieve time */
|
|---|
| 355 | IV where_is_undef; /* index in aseen of PL_sv_undef */
|
|---|
| 356 | HV *hclass; /* which classnames have been seen, store time */
|
|---|
| 357 | AV *aclass; /* which classnames have been seen, retrieve time */
|
|---|
| 358 | HV *hook; /* cache for hook methods per class name */
|
|---|
| 359 | IV tagnum; /* incremented at store time for each seen object */
|
|---|
| 360 | IV classnum; /* incremented at store time for each seen classname */
|
|---|
| 361 | int netorder; /* true if network order used */
|
|---|
| 362 | int s_tainted; /* true if input source is tainted, at retrieve time */
|
|---|
| 363 | int forgive_me; /* whether to be forgiving... */
|
|---|
| 364 | int deparse; /* whether to deparse code refs */
|
|---|
| 365 | SV *eval; /* whether to eval source code */
|
|---|
| 366 | int canonical; /* whether to store hashes sorted by key */
|
|---|
| 367 | #ifndef HAS_RESTRICTED_HASHES
|
|---|
| 368 | int derestrict; /* whether to downgrade restrcted hashes */
|
|---|
| 369 | #endif
|
|---|
| 370 | #ifndef HAS_UTF8_ALL
|
|---|
| 371 | int use_bytes; /* whether to bytes-ify utf8 */
|
|---|
| 372 | #endif
|
|---|
| 373 | int accept_future_minor; /* croak immediately on future minor versions? */
|
|---|
| 374 | int s_dirty; /* context is dirty due to CROAK() -- can be cleaned */
|
|---|
| 375 | int membuf_ro; /* true means membuf is read-only and msaved is rw */
|
|---|
| 376 | struct extendable keybuf; /* for hash key retrieval */
|
|---|
| 377 | struct extendable membuf; /* for memory store/retrieve operations */
|
|---|
| 378 | struct extendable msaved; /* where potentially valid mbuf is saved */
|
|---|
| 379 | PerlIO *fio; /* where I/O are performed, NULL for memory */
|
|---|
| 380 | int ver_major; /* major of version for retrieved object */
|
|---|
| 381 | int ver_minor; /* minor of version for retrieved object */
|
|---|
| 382 | SV *(**retrieve_vtbl)(pTHX_ struct stcxt *, char *); /* retrieve dispatch table */
|
|---|
| 383 | SV *prev; /* contexts chained backwards in real recursion */
|
|---|
| 384 | SV *my_sv; /* the blessed scalar who's SvPVX() I am */
|
|---|
| 385 | } stcxt_t;
|
|---|
| 386 |
|
|---|
| 387 | #define NEW_STORABLE_CXT_OBJ(cxt) \
|
|---|
| 388 | STMT_START { \
|
|---|
| 389 | SV *self = newSV(sizeof(stcxt_t) - 1); \
|
|---|
| 390 | SV *my_sv = newRV_noinc(self); \
|
|---|
| 391 | sv_bless(my_sv, gv_stashpv("Storable::Cxt", TRUE)); \
|
|---|
| 392 | cxt = (stcxt_t *)SvPVX(self); \
|
|---|
| 393 | Zero(cxt, 1, stcxt_t); \
|
|---|
| 394 | cxt->my_sv = my_sv; \
|
|---|
| 395 | } STMT_END
|
|---|
| 396 |
|
|---|
| 397 | #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || defined(PERL_CAPI)
|
|---|
| 398 |
|
|---|
| 399 | #if (PATCHLEVEL <= 4) && (SUBVERSION < 68)
|
|---|
| 400 | #define dSTCXT_SV \
|
|---|
| 401 | SV *perinterp_sv = perl_get_sv(MY_VERSION, FALSE)
|
|---|
| 402 | #else /* >= perl5.004_68 */
|
|---|
| 403 | #define dSTCXT_SV \
|
|---|
| 404 | SV *perinterp_sv = *hv_fetch(PL_modglobal, \
|
|---|
| 405 | MY_VERSION, sizeof(MY_VERSION)-1, TRUE)
|
|---|
| 406 | #endif /* < perl5.004_68 */
|
|---|
| 407 |
|
|---|
| 408 | #define dSTCXT_PTR(T,name) \
|
|---|
| 409 | T name = ((perinterp_sv && SvIOK(perinterp_sv) && SvIVX(perinterp_sv) \
|
|---|
| 410 | ? (T)SvPVX(SvRV(INT2PTR(SV*,SvIVX(perinterp_sv)))) : (T) 0))
|
|---|
| 411 | #define dSTCXT \
|
|---|
| 412 | dSTCXT_SV; \
|
|---|
| 413 | dSTCXT_PTR(stcxt_t *, cxt)
|
|---|
| 414 |
|
|---|
| 415 | #define INIT_STCXT \
|
|---|
| 416 | dSTCXT; \
|
|---|
| 417 | NEW_STORABLE_CXT_OBJ(cxt); \
|
|---|
| 418 | sv_setiv(perinterp_sv, PTR2IV(cxt->my_sv))
|
|---|
| 419 |
|
|---|
| 420 | #define SET_STCXT(x) \
|
|---|
| 421 | STMT_START { \
|
|---|
| 422 | dSTCXT_SV; \
|
|---|
| 423 | sv_setiv(perinterp_sv, PTR2IV(x->my_sv)); \
|
|---|
| 424 | } STMT_END
|
|---|
| 425 |
|
|---|
| 426 | #else /* !MULTIPLICITY && !PERL_OBJECT && !PERL_CAPI */
|
|---|
| 427 |
|
|---|
| 428 | static stcxt_t *Context_ptr = NULL;
|
|---|
| 429 | #define dSTCXT stcxt_t *cxt = Context_ptr
|
|---|
| 430 | #define SET_STCXT(x) Context_ptr = x
|
|---|
| 431 | #define INIT_STCXT \
|
|---|
| 432 | dSTCXT; \
|
|---|
| 433 | NEW_STORABLE_CXT_OBJ(cxt); \
|
|---|
| 434 | SET_STCXT(cxt)
|
|---|
| 435 |
|
|---|
| 436 |
|
|---|
| 437 | #endif /* MULTIPLICITY || PERL_OBJECT || PERL_CAPI */
|
|---|
| 438 |
|
|---|
| 439 | /*
|
|---|
| 440 | * KNOWN BUG:
|
|---|
| 441 | * Croaking implies a memory leak, since we don't use setjmp/longjmp
|
|---|
| 442 | * to catch the exit and free memory used during store or retrieve
|
|---|
| 443 | * operations. This is not too difficult to fix, but I need to understand
|
|---|
| 444 | * how Perl does it, and croaking is exceptional anyway, so I lack the
|
|---|
| 445 | * motivation to do it.
|
|---|
| 446 | *
|
|---|
| 447 | * The current workaround is to mark the context as dirty when croaking,
|
|---|
| 448 | * so that data structures can be freed whenever we renter Storable code
|
|---|
| 449 | * (but only *then*: it's a workaround, not a fix).
|
|---|
| 450 | *
|
|---|
| 451 | * This is also imperfect, because we don't really know how far they trapped
|
|---|
| 452 | * the croak(), and when we were recursing, we won't be able to clean anything
|
|---|
| 453 | * but the topmost context stacked.
|
|---|
| 454 | */
|
|---|
| 455 |
|
|---|
| 456 | #define CROAK(x) STMT_START { cxt->s_dirty = 1; croak x; } STMT_END
|
|---|
| 457 |
|
|---|
| 458 | /*
|
|---|
| 459 | * End of "thread-safe" related definitions.
|
|---|
| 460 | */
|
|---|
| 461 |
|
|---|
| 462 | /*
|
|---|
| 463 | * LOW_32BITS
|
|---|
| 464 | *
|
|---|
| 465 | * Keep only the low 32 bits of a pointer (used for tags, which are not
|
|---|
| 466 | * really pointers).
|
|---|
| 467 | */
|
|---|
| 468 |
|
|---|
| 469 | #if PTRSIZE <= 4
|
|---|
| 470 | #define LOW_32BITS(x) ((I32) (x))
|
|---|
| 471 | #else
|
|---|
| 472 | #define LOW_32BITS(x) ((I32) ((unsigned long) (x) & 0xffffffffUL))
|
|---|
| 473 | #endif
|
|---|
| 474 |
|
|---|
| 475 | /*
|
|---|
| 476 | * oI, oS, oC
|
|---|
| 477 | *
|
|---|
| 478 | * Hack for Crays, where sizeof(I32) == 8, and which are big-endians.
|
|---|
| 479 | * Used in the WLEN and RLEN macros.
|
|---|
| 480 | */
|
|---|
| 481 |
|
|---|
| 482 | #if INTSIZE > 4
|
|---|
| 483 | #define oI(x) ((I32 *) ((char *) (x) + 4))
|
|---|
| 484 | #define oS(x) ((x) - 4)
|
|---|
| 485 | #define oC(x) (x = 0)
|
|---|
| 486 | #define CRAY_HACK
|
|---|
| 487 | #else
|
|---|
| 488 | #define oI(x) (x)
|
|---|
| 489 | #define oS(x) (x)
|
|---|
| 490 | #define oC(x)
|
|---|
| 491 | #endif
|
|---|
| 492 |
|
|---|
| 493 | /*
|
|---|
| 494 | * key buffer handling
|
|---|
| 495 | */
|
|---|
| 496 | #define kbuf (cxt->keybuf).arena
|
|---|
| 497 | #define ksiz (cxt->keybuf).asiz
|
|---|
| 498 | #define KBUFINIT() \
|
|---|
| 499 | STMT_START { \
|
|---|
| 500 | if (!kbuf) { \
|
|---|
| 501 | TRACEME(("** allocating kbuf of 128 bytes")); \
|
|---|
| 502 | New(10003, kbuf, 128, char); \
|
|---|
| 503 | ksiz = 128; \
|
|---|
| 504 | } \
|
|---|
| 505 | } STMT_END
|
|---|
| 506 | #define KBUFCHK(x) \
|
|---|
| 507 | STMT_START { \
|
|---|
| 508 | if (x >= ksiz) { \
|
|---|
| 509 | TRACEME(("** extending kbuf to %d bytes (had %d)", x+1, ksiz)); \
|
|---|
| 510 | Renew(kbuf, x+1, char); \
|
|---|
| 511 | ksiz = x+1; \
|
|---|
| 512 | } \
|
|---|
| 513 | } STMT_END
|
|---|
| 514 |
|
|---|
| 515 | /*
|
|---|
| 516 | * memory buffer handling
|
|---|
| 517 | */
|
|---|
| 518 | #define mbase (cxt->membuf).arena
|
|---|
| 519 | #define msiz (cxt->membuf).asiz
|
|---|
| 520 | #define mptr (cxt->membuf).aptr
|
|---|
| 521 | #define mend (cxt->membuf).aend
|
|---|
| 522 |
|
|---|
| 523 | #define MGROW (1 << 13)
|
|---|
| 524 | #define MMASK (MGROW - 1)
|
|---|
| 525 |
|
|---|
| 526 | #define round_mgrow(x) \
|
|---|
| 527 | ((unsigned long) (((unsigned long) (x) + MMASK) & ~MMASK))
|
|---|
| 528 | #define trunc_int(x) \
|
|---|
| 529 | ((unsigned long) ((unsigned long) (x) & ~(sizeof(int)-1)))
|
|---|
| 530 | #define int_aligned(x) \
|
|---|
| 531 | ((unsigned long) (x) == trunc_int(x))
|
|---|
| 532 |
|
|---|
| 533 | #define MBUF_INIT(x) \
|
|---|
| 534 | STMT_START { \
|
|---|
| 535 | if (!mbase) { \
|
|---|
| 536 | TRACEME(("** allocating mbase of %d bytes", MGROW)); \
|
|---|
| 537 | New(10003, mbase, MGROW, char); \
|
|---|
| 538 | msiz = (STRLEN)MGROW; \
|
|---|
| 539 | } \
|
|---|
| 540 | mptr = mbase; \
|
|---|
| 541 | if (x) \
|
|---|
| 542 | mend = mbase + x; \
|
|---|
| 543 | else \
|
|---|
| 544 | mend = mbase + msiz; \
|
|---|
| 545 | } STMT_END
|
|---|
| 546 |
|
|---|
| 547 | #define MBUF_TRUNC(x) mptr = mbase + x
|
|---|
| 548 | #define MBUF_SIZE() (mptr - mbase)
|
|---|
| 549 |
|
|---|
| 550 | /*
|
|---|
| 551 | * MBUF_SAVE_AND_LOAD
|
|---|
| 552 | * MBUF_RESTORE
|
|---|
| 553 | *
|
|---|
| 554 | * Those macros are used in do_retrieve() to save the current memory
|
|---|
| 555 | * buffer into cxt->msaved, before MBUF_LOAD() can be used to retrieve
|
|---|
| 556 | * data from a string.
|
|---|
| 557 | */
|
|---|
| 558 | #define MBUF_SAVE_AND_LOAD(in) \
|
|---|
| 559 | STMT_START { \
|
|---|
| 560 | ASSERT(!cxt->membuf_ro, ("mbase not already saved")); \
|
|---|
| 561 | cxt->membuf_ro = 1; \
|
|---|
| 562 | TRACEME(("saving mbuf")); \
|
|---|
| 563 | StructCopy(&cxt->membuf, &cxt->msaved, struct extendable); \
|
|---|
| 564 | MBUF_LOAD(in); \
|
|---|
| 565 | } STMT_END
|
|---|
| 566 |
|
|---|
| 567 | #define MBUF_RESTORE() \
|
|---|
| 568 | STMT_START { \
|
|---|
| 569 | ASSERT(cxt->membuf_ro, ("mbase is read-only")); \
|
|---|
| 570 | cxt->membuf_ro = 0; \
|
|---|
| 571 | TRACEME(("restoring mbuf")); \
|
|---|
| 572 | StructCopy(&cxt->msaved, &cxt->membuf, struct extendable); \
|
|---|
| 573 | } STMT_END
|
|---|
| 574 |
|
|---|
| 575 | /*
|
|---|
| 576 | * Use SvPOKp(), because SvPOK() fails on tainted scalars.
|
|---|
| 577 | * See store_scalar() for other usage of this workaround.
|
|---|
| 578 | */
|
|---|
| 579 | #define MBUF_LOAD(v) \
|
|---|
| 580 | STMT_START { \
|
|---|
| 581 | ASSERT(cxt->membuf_ro, ("mbase is read-only")); \
|
|---|
| 582 | if (!SvPOKp(v)) \
|
|---|
| 583 | CROAK(("Not a scalar string")); \
|
|---|
| 584 | mptr = mbase = SvPV(v, msiz); \
|
|---|
| 585 | mend = mbase + msiz; \
|
|---|
| 586 | } STMT_END
|
|---|
| 587 |
|
|---|
| 588 | #define MBUF_XTEND(x) \
|
|---|
| 589 | STMT_START { \
|
|---|
| 590 | int nsz = (int) round_mgrow((x)+msiz); \
|
|---|
| 591 | int offset = mptr - mbase; \
|
|---|
| 592 | ASSERT(!cxt->membuf_ro, ("mbase is not read-only")); \
|
|---|
| 593 | TRACEME(("** extending mbase from %d to %d bytes (wants %d new)", \
|
|---|
| 594 | msiz, nsz, (x))); \
|
|---|
| 595 | Renew(mbase, nsz, char); \
|
|---|
| 596 | msiz = nsz; \
|
|---|
| 597 | mptr = mbase + offset; \
|
|---|
| 598 | mend = mbase + nsz; \
|
|---|
| 599 | } STMT_END
|
|---|
| 600 |
|
|---|
| 601 | #define MBUF_CHK(x) \
|
|---|
| 602 | STMT_START { \
|
|---|
| 603 | if ((mptr + (x)) > mend) \
|
|---|
| 604 | MBUF_XTEND(x); \
|
|---|
| 605 | } STMT_END
|
|---|
| 606 |
|
|---|
| 607 | #define MBUF_GETC(x) \
|
|---|
| 608 | STMT_START { \
|
|---|
| 609 | if (mptr < mend) \
|
|---|
| 610 | x = (int) (unsigned char) *mptr++; \
|
|---|
| 611 | else \
|
|---|
| 612 | return (SV *) 0; \
|
|---|
| 613 | } STMT_END
|
|---|
| 614 |
|
|---|
| 615 | #ifdef CRAY_HACK
|
|---|
| 616 | #define MBUF_GETINT(x) \
|
|---|
| 617 | STMT_START { \
|
|---|
| 618 | oC(x); \
|
|---|
| 619 | if ((mptr + 4) <= mend) { \
|
|---|
| 620 | memcpy(oI(&x), mptr, 4); \
|
|---|
| 621 | mptr += 4; \
|
|---|
| 622 | } else \
|
|---|
| 623 | return (SV *) 0; \
|
|---|
| 624 | } STMT_END
|
|---|
| 625 | #else
|
|---|
| 626 | #define MBUF_GETINT(x) \
|
|---|
| 627 | STMT_START { \
|
|---|
| 628 | if ((mptr + sizeof(int)) <= mend) { \
|
|---|
| 629 | if (int_aligned(mptr)) \
|
|---|
| 630 | x = *(int *) mptr; \
|
|---|
| 631 | else \
|
|---|
| 632 | memcpy(&x, mptr, sizeof(int)); \
|
|---|
| 633 | mptr += sizeof(int); \
|
|---|
| 634 | } else \
|
|---|
| 635 | return (SV *) 0; \
|
|---|
| 636 | } STMT_END
|
|---|
| 637 | #endif
|
|---|
| 638 |
|
|---|
| 639 | #define MBUF_READ(x,s) \
|
|---|
| 640 | STMT_START { \
|
|---|
| 641 | if ((mptr + (s)) <= mend) { \
|
|---|
| 642 | memcpy(x, mptr, s); \
|
|---|
| 643 | mptr += s; \
|
|---|
| 644 | } else \
|
|---|
| 645 | return (SV *) 0; \
|
|---|
| 646 | } STMT_END
|
|---|
| 647 |
|
|---|
| 648 | #define MBUF_SAFEREAD(x,s,z) \
|
|---|
| 649 | STMT_START { \
|
|---|
| 650 | if ((mptr + (s)) <= mend) { \
|
|---|
| 651 | memcpy(x, mptr, s); \
|
|---|
| 652 | mptr += s; \
|
|---|
| 653 | } else { \
|
|---|
| 654 | sv_free(z); \
|
|---|
| 655 | return (SV *) 0; \
|
|---|
| 656 | } \
|
|---|
| 657 | } STMT_END
|
|---|
| 658 |
|
|---|
| 659 | #define MBUF_PUTC(c) \
|
|---|
| 660 | STMT_START { \
|
|---|
| 661 | if (mptr < mend) \
|
|---|
| 662 | *mptr++ = (char) c; \
|
|---|
| 663 | else { \
|
|---|
| 664 | MBUF_XTEND(1); \
|
|---|
| 665 | *mptr++ = (char) c; \
|
|---|
| 666 | } \
|
|---|
| 667 | } STMT_END
|
|---|
| 668 |
|
|---|
| 669 | #ifdef CRAY_HACK
|
|---|
| 670 | #define MBUF_PUTINT(i) \
|
|---|
| 671 | STMT_START { \
|
|---|
| 672 | MBUF_CHK(4); \
|
|---|
| 673 | memcpy(mptr, oI(&i), 4); \
|
|---|
| 674 | mptr += 4; \
|
|---|
| 675 | } STMT_END
|
|---|
| 676 | #else
|
|---|
| 677 | #define MBUF_PUTINT(i) \
|
|---|
| 678 | STMT_START { \
|
|---|
| 679 | MBUF_CHK(sizeof(int)); \
|
|---|
| 680 | if (int_aligned(mptr)) \
|
|---|
| 681 | *(int *) mptr = i; \
|
|---|
| 682 | else \
|
|---|
| 683 | memcpy(mptr, &i, sizeof(int)); \
|
|---|
| 684 | mptr += sizeof(int); \
|
|---|
| 685 | } STMT_END
|
|---|
| 686 | #endif
|
|---|
| 687 |
|
|---|
| 688 | #define MBUF_WRITE(x,s) \
|
|---|
| 689 | STMT_START { \
|
|---|
| 690 | MBUF_CHK(s); \
|
|---|
| 691 | memcpy(mptr, x, s); \
|
|---|
| 692 | mptr += s; \
|
|---|
| 693 | } STMT_END
|
|---|
| 694 |
|
|---|
| 695 | /*
|
|---|
| 696 | * Possible return values for sv_type().
|
|---|
| 697 | */
|
|---|
| 698 |
|
|---|
| 699 | #define svis_REF 0
|
|---|
| 700 | #define svis_SCALAR 1
|
|---|
| 701 | #define svis_ARRAY 2
|
|---|
| 702 | #define svis_HASH 3
|
|---|
| 703 | #define svis_TIED 4
|
|---|
| 704 | #define svis_TIED_ITEM 5
|
|---|
| 705 | #define svis_CODE 6
|
|---|
| 706 | #define svis_OTHER 7
|
|---|
| 707 |
|
|---|
| 708 | /*
|
|---|
| 709 | * Flags for SX_HOOK.
|
|---|
| 710 | */
|
|---|
| 711 |
|
|---|
| 712 | #define SHF_TYPE_MASK 0x03
|
|---|
| 713 | #define SHF_LARGE_CLASSLEN 0x04
|
|---|
| 714 | #define SHF_LARGE_STRLEN 0x08
|
|---|
| 715 | #define SHF_LARGE_LISTLEN 0x10
|
|---|
| 716 | #define SHF_IDX_CLASSNAME 0x20
|
|---|
| 717 | #define SHF_NEED_RECURSE 0x40
|
|---|
| 718 | #define SHF_HAS_LIST 0x80
|
|---|
| 719 |
|
|---|
| 720 | /*
|
|---|
| 721 | * Types for SX_HOOK (last 2 bits in flags).
|
|---|
| 722 | */
|
|---|
| 723 |
|
|---|
| 724 | #define SHT_SCALAR 0
|
|---|
| 725 | #define SHT_ARRAY 1
|
|---|
| 726 | #define SHT_HASH 2
|
|---|
| 727 | #define SHT_EXTRA 3 /* Read extra byte for type */
|
|---|
| 728 |
|
|---|
| 729 | /*
|
|---|
| 730 | * The following are held in the "extra byte"...
|
|---|
| 731 | */
|
|---|
| 732 |
|
|---|
| 733 | #define SHT_TSCALAR 4 /* 4 + 0 -- tied scalar */
|
|---|
| 734 | #define SHT_TARRAY 5 /* 4 + 1 -- tied array */
|
|---|
| 735 | #define SHT_THASH 6 /* 4 + 2 -- tied hash */
|
|---|
| 736 |
|
|---|
| 737 | /*
|
|---|
| 738 | * per hash flags for flagged hashes
|
|---|
| 739 | */
|
|---|
| 740 |
|
|---|
| 741 | #define SHV_RESTRICTED 0x01
|
|---|
| 742 |
|
|---|
| 743 | /*
|
|---|
| 744 | * per key flags for flagged hashes
|
|---|
| 745 | */
|
|---|
| 746 |
|
|---|
| 747 | #define SHV_K_UTF8 0x01
|
|---|
| 748 | #define SHV_K_WASUTF8 0x02
|
|---|
| 749 | #define SHV_K_LOCKED 0x04
|
|---|
| 750 | #define SHV_K_ISSV 0x08
|
|---|
| 751 | #define SHV_K_PLACEHOLDER 0x10
|
|---|
| 752 |
|
|---|
| 753 | /*
|
|---|
| 754 | * Before 0.6, the magic string was "perl-store" (binary version number 0).
|
|---|
| 755 | *
|
|---|
| 756 | * Since 0.6 introduced many binary incompatibilities, the magic string has
|
|---|
| 757 | * been changed to "pst0" to allow an old image to be properly retrieved by
|
|---|
| 758 | * a newer Storable, but ensure a newer image cannot be retrieved with an
|
|---|
| 759 | * older version.
|
|---|
| 760 | *
|
|---|
| 761 | * At 0.7, objects are given the ability to serialize themselves, and the
|
|---|
| 762 | * set of markers is extended, backward compatibility is not jeopardized,
|
|---|
| 763 | * so the binary version number could have remained unchanged. To correctly
|
|---|
| 764 | * spot errors if a file making use of 0.7-specific extensions is given to
|
|---|
| 765 | * 0.6 for retrieval, the binary version was moved to "2". And I'm introducing
|
|---|
| 766 | * a "minor" version, to better track this kind of evolution from now on.
|
|---|
| 767 | *
|
|---|
| 768 | */
|
|---|
| 769 | static const char old_magicstr[] = "perl-store"; /* Magic number before 0.6 */
|
|---|
| 770 | static const char magicstr[] = "pst0"; /* Used as a magic number */
|
|---|
| 771 |
|
|---|
| 772 | #define MAGICSTR_BYTES 'p','s','t','0'
|
|---|
| 773 | #define OLDMAGICSTR_BYTES 'p','e','r','l','-','s','t','o','r','e'
|
|---|
| 774 |
|
|---|
| 775 | /* 5.6.x introduced the ability to have IVs as long long.
|
|---|
| 776 | However, Configure still defined BYTEORDER based on the size of a long.
|
|---|
| 777 | Storable uses the BYTEORDER value as part of the header, but doesn't
|
|---|
| 778 | explicity store sizeof(IV) anywhere in the header. Hence on 5.6.x built
|
|---|
| 779 | with IV as long long on a platform that uses Configure (ie most things
|
|---|
| 780 | except VMS and Windows) headers are identical for the different IV sizes,
|
|---|
| 781 | despite the files containing some fields based on sizeof(IV)
|
|---|
| 782 | Erk. Broken-ness.
|
|---|
| 783 | 5.8 is consistent - the following redifinition kludge is only needed on
|
|---|
| 784 | 5.6.x, but the interwork is needed on 5.8 while data survives in files
|
|---|
| 785 | with the 5.6 header.
|
|---|
| 786 |
|
|---|
| 787 | */
|
|---|
| 788 |
|
|---|
| 789 | #if defined (IVSIZE) && (IVSIZE == 8) && (LONGSIZE == 4)
|
|---|
| 790 | #ifndef NO_56_INTERWORK_KLUDGE
|
|---|
| 791 | #define USE_56_INTERWORK_KLUDGE
|
|---|
| 792 | #endif
|
|---|
| 793 | #if BYTEORDER == 0x1234
|
|---|
| 794 | #undef BYTEORDER
|
|---|
| 795 | #define BYTEORDER 0x12345678
|
|---|
| 796 | #else
|
|---|
| 797 | #if BYTEORDER == 0x4321
|
|---|
| 798 | #undef BYTEORDER
|
|---|
| 799 | #define BYTEORDER 0x87654321
|
|---|
| 800 | #endif
|
|---|
| 801 | #endif
|
|---|
| 802 | #endif
|
|---|
| 803 |
|
|---|
| 804 | #if BYTEORDER == 0x1234
|
|---|
| 805 | #define BYTEORDER_BYTES '1','2','3','4'
|
|---|
| 806 | #else
|
|---|
| 807 | #if BYTEORDER == 0x12345678
|
|---|
| 808 | #define BYTEORDER_BYTES '1','2','3','4','5','6','7','8'
|
|---|
| 809 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 810 | #define BYTEORDER_BYTES_56 '1','2','3','4'
|
|---|
| 811 | #endif
|
|---|
| 812 | #else
|
|---|
| 813 | #if BYTEORDER == 0x87654321
|
|---|
| 814 | #define BYTEORDER_BYTES '8','7','6','5','4','3','2','1'
|
|---|
| 815 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 816 | #define BYTEORDER_BYTES_56 '4','3','2','1'
|
|---|
| 817 | #endif
|
|---|
| 818 | #else
|
|---|
| 819 | #if BYTEORDER == 0x4321
|
|---|
| 820 | #define BYTEORDER_BYTES '4','3','2','1'
|
|---|
| 821 | #else
|
|---|
| 822 | #error Unknown byteorder. Please append your byteorder to Storable.xs
|
|---|
| 823 | #endif
|
|---|
| 824 | #endif
|
|---|
| 825 | #endif
|
|---|
| 826 | #endif
|
|---|
| 827 |
|
|---|
| 828 | static const char byteorderstr[] = {BYTEORDER_BYTES, 0};
|
|---|
| 829 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 830 | static const char byteorderstr_56[] = {BYTEORDER_BYTES_56, 0};
|
|---|
| 831 | #endif
|
|---|
| 832 |
|
|---|
| 833 | #define STORABLE_BIN_MAJOR 2 /* Binary major "version" */
|
|---|
| 834 | #define STORABLE_BIN_MINOR 7 /* Binary minor "version" */
|
|---|
| 835 |
|
|---|
| 836 | #if (PATCHLEVEL <= 5)
|
|---|
| 837 | #define STORABLE_BIN_WRITE_MINOR 4
|
|---|
| 838 | #else
|
|---|
| 839 | /*
|
|---|
| 840 | * Perl 5.6.0 onwards can do weak references.
|
|---|
| 841 | */
|
|---|
| 842 | #define STORABLE_BIN_WRITE_MINOR 7
|
|---|
| 843 | #endif /* (PATCHLEVEL <= 5) */
|
|---|
| 844 |
|
|---|
| 845 | #if (PATCHLEVEL < 8 || (PATCHLEVEL == 8 && SUBVERSION < 1))
|
|---|
| 846 | #define PL_sv_placeholder PL_sv_undef
|
|---|
| 847 | #endif
|
|---|
| 848 |
|
|---|
| 849 | /*
|
|---|
| 850 | * Useful store shortcuts...
|
|---|
| 851 | */
|
|---|
| 852 |
|
|---|
| 853 | /*
|
|---|
| 854 | * Note that if you put more than one mark for storing a particular
|
|---|
| 855 | * type of thing, *and* in the retrieve_foo() function you mark both
|
|---|
| 856 | * the thingy's you get off with SEEN(), you *must* increase the
|
|---|
| 857 | * tagnum with cxt->tagnum++ along with this macro!
|
|---|
| 858 | * - samv 20Jan04
|
|---|
| 859 | */
|
|---|
| 860 | #define PUTMARK(x) \
|
|---|
| 861 | STMT_START { \
|
|---|
| 862 | if (!cxt->fio) \
|
|---|
| 863 | MBUF_PUTC(x); \
|
|---|
| 864 | else if (PerlIO_putc(cxt->fio, x) == EOF) \
|
|---|
| 865 | return -1; \
|
|---|
| 866 | } STMT_END
|
|---|
| 867 |
|
|---|
| 868 | #define WRITE_I32(x) \
|
|---|
| 869 | STMT_START { \
|
|---|
| 870 | ASSERT(sizeof(x) == sizeof(I32), ("writing an I32")); \
|
|---|
| 871 | if (!cxt->fio) \
|
|---|
| 872 | MBUF_PUTINT(x); \
|
|---|
| 873 | else if (PerlIO_write(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x))) \
|
|---|
| 874 | return -1; \
|
|---|
| 875 | } STMT_END
|
|---|
| 876 |
|
|---|
| 877 | #ifdef HAS_HTONL
|
|---|
| 878 | #define WLEN(x) \
|
|---|
| 879 | STMT_START { \
|
|---|
| 880 | if (cxt->netorder) { \
|
|---|
| 881 | int y = (int) htonl(x); \
|
|---|
| 882 | if (!cxt->fio) \
|
|---|
| 883 | MBUF_PUTINT(y); \
|
|---|
| 884 | else if (PerlIO_write(cxt->fio,oI(&y),oS(sizeof(y))) != oS(sizeof(y))) \
|
|---|
| 885 | return -1; \
|
|---|
| 886 | } else { \
|
|---|
| 887 | if (!cxt->fio) \
|
|---|
| 888 | MBUF_PUTINT(x); \
|
|---|
| 889 | else if (PerlIO_write(cxt->fio,oI(&x),oS(sizeof(x))) != oS(sizeof(x))) \
|
|---|
| 890 | return -1; \
|
|---|
| 891 | } \
|
|---|
| 892 | } STMT_END
|
|---|
| 893 | #else
|
|---|
| 894 | #define WLEN(x) WRITE_I32(x)
|
|---|
| 895 | #endif
|
|---|
| 896 |
|
|---|
| 897 | #define WRITE(x,y) \
|
|---|
| 898 | STMT_START { \
|
|---|
| 899 | if (!cxt->fio) \
|
|---|
| 900 | MBUF_WRITE(x,y); \
|
|---|
| 901 | else if (PerlIO_write(cxt->fio, x, y) != y) \
|
|---|
| 902 | return -1; \
|
|---|
| 903 | } STMT_END
|
|---|
| 904 |
|
|---|
| 905 | #define STORE_PV_LEN(pv, len, small, large) \
|
|---|
| 906 | STMT_START { \
|
|---|
| 907 | if (len <= LG_SCALAR) { \
|
|---|
| 908 | unsigned char clen = (unsigned char) len; \
|
|---|
| 909 | PUTMARK(small); \
|
|---|
| 910 | PUTMARK(clen); \
|
|---|
| 911 | if (len) \
|
|---|
| 912 | WRITE(pv, len); \
|
|---|
| 913 | } else { \
|
|---|
| 914 | PUTMARK(large); \
|
|---|
| 915 | WLEN(len); \
|
|---|
| 916 | WRITE(pv, len); \
|
|---|
| 917 | } \
|
|---|
| 918 | } STMT_END
|
|---|
| 919 |
|
|---|
| 920 | #define STORE_SCALAR(pv, len) STORE_PV_LEN(pv, len, SX_SCALAR, SX_LSCALAR)
|
|---|
| 921 |
|
|---|
| 922 | /*
|
|---|
| 923 | * Store &PL_sv_undef in arrays without recursing through store().
|
|---|
| 924 | */
|
|---|
| 925 | #define STORE_SV_UNDEF() \
|
|---|
| 926 | STMT_START { \
|
|---|
| 927 | cxt->tagnum++; \
|
|---|
| 928 | PUTMARK(SX_SV_UNDEF); \
|
|---|
| 929 | } STMT_END
|
|---|
| 930 |
|
|---|
| 931 | /*
|
|---|
| 932 | * Useful retrieve shortcuts...
|
|---|
| 933 | */
|
|---|
| 934 |
|
|---|
| 935 | #define GETCHAR() \
|
|---|
| 936 | (cxt->fio ? PerlIO_getc(cxt->fio) : (mptr >= mend ? EOF : (int) *mptr++))
|
|---|
| 937 |
|
|---|
| 938 | #define GETMARK(x) \
|
|---|
| 939 | STMT_START { \
|
|---|
| 940 | if (!cxt->fio) \
|
|---|
| 941 | MBUF_GETC(x); \
|
|---|
| 942 | else if ((int) (x = PerlIO_getc(cxt->fio)) == EOF) \
|
|---|
| 943 | return (SV *) 0; \
|
|---|
| 944 | } STMT_END
|
|---|
| 945 |
|
|---|
| 946 | #define READ_I32(x) \
|
|---|
| 947 | STMT_START { \
|
|---|
| 948 | ASSERT(sizeof(x) == sizeof(I32), ("reading an I32")); \
|
|---|
| 949 | oC(x); \
|
|---|
| 950 | if (!cxt->fio) \
|
|---|
| 951 | MBUF_GETINT(x); \
|
|---|
| 952 | else if (PerlIO_read(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x))) \
|
|---|
| 953 | return (SV *) 0; \
|
|---|
| 954 | } STMT_END
|
|---|
| 955 |
|
|---|
| 956 | #ifdef HAS_NTOHL
|
|---|
| 957 | #define RLEN(x) \
|
|---|
| 958 | STMT_START { \
|
|---|
| 959 | oC(x); \
|
|---|
| 960 | if (!cxt->fio) \
|
|---|
| 961 | MBUF_GETINT(x); \
|
|---|
| 962 | else if (PerlIO_read(cxt->fio, oI(&x), oS(sizeof(x))) != oS(sizeof(x))) \
|
|---|
| 963 | return (SV *) 0; \
|
|---|
| 964 | if (cxt->netorder) \
|
|---|
| 965 | x = (int) ntohl(x); \
|
|---|
| 966 | } STMT_END
|
|---|
| 967 | #else
|
|---|
| 968 | #define RLEN(x) READ_I32(x)
|
|---|
| 969 | #endif
|
|---|
| 970 |
|
|---|
| 971 | #define READ(x,y) \
|
|---|
| 972 | STMT_START { \
|
|---|
| 973 | if (!cxt->fio) \
|
|---|
| 974 | MBUF_READ(x, y); \
|
|---|
| 975 | else if (PerlIO_read(cxt->fio, x, y) != y) \
|
|---|
| 976 | return (SV *) 0; \
|
|---|
| 977 | } STMT_END
|
|---|
| 978 |
|
|---|
| 979 | #define SAFEREAD(x,y,z) \
|
|---|
| 980 | STMT_START { \
|
|---|
| 981 | if (!cxt->fio) \
|
|---|
| 982 | MBUF_SAFEREAD(x,y,z); \
|
|---|
| 983 | else if (PerlIO_read(cxt->fio, x, y) != y) { \
|
|---|
| 984 | sv_free(z); \
|
|---|
| 985 | return (SV *) 0; \
|
|---|
| 986 | } \
|
|---|
| 987 | } STMT_END
|
|---|
| 988 |
|
|---|
| 989 | /*
|
|---|
| 990 | * This macro is used at retrieve time, to remember where object 'y', bearing a
|
|---|
| 991 | * given tag 'tagnum', has been retrieved. Next time we see an SX_OBJECT marker,
|
|---|
| 992 | * we'll therefore know where it has been retrieved and will be able to
|
|---|
| 993 | * share the same reference, as in the original stored memory image.
|
|---|
| 994 | *
|
|---|
| 995 | * We also need to bless objects ASAP for hooks (which may compute "ref $x"
|
|---|
| 996 | * on the objects given to STORABLE_thaw and expect that to be defined), and
|
|---|
| 997 | * also for overloaded objects (for which we might not find the stash if the
|
|---|
| 998 | * object is not blessed yet--this might occur for overloaded objects that
|
|---|
| 999 | * refer to themselves indirectly: if we blessed upon return from a sub
|
|---|
| 1000 | * retrieve(), the SX_OBJECT marker we'd found could not have overloading
|
|---|
| 1001 | * restored on it because the underlying object would not be blessed yet!).
|
|---|
| 1002 | *
|
|---|
| 1003 | * To achieve that, the class name of the last retrieved object is passed down
|
|---|
| 1004 | * recursively, and the first SEEN() call for which the class name is not NULL
|
|---|
| 1005 | * will bless the object.
|
|---|
| 1006 | *
|
|---|
| 1007 | * i should be true iff sv is immortal (ie PL_sv_yes, PL_sv_no or PL_sv_undef)
|
|---|
| 1008 | */
|
|---|
| 1009 | #define SEEN(y,c,i) \
|
|---|
| 1010 | STMT_START { \
|
|---|
| 1011 | if (!y) \
|
|---|
| 1012 | return (SV *) 0; \
|
|---|
| 1013 | if (av_store(cxt->aseen, cxt->tagnum++, i ? (SV*)(y) : SvREFCNT_inc(y)) == 0) \
|
|---|
| 1014 | return (SV *) 0; \
|
|---|
| 1015 | TRACEME(("aseen(#%d) = 0x%"UVxf" (refcnt=%d)", cxt->tagnum-1, \
|
|---|
| 1016 | PTR2UV(y), SvREFCNT(y)-1)); \
|
|---|
| 1017 | if (c) \
|
|---|
| 1018 | BLESS((SV *) (y), c); \
|
|---|
| 1019 | } STMT_END
|
|---|
| 1020 |
|
|---|
| 1021 | /*
|
|---|
| 1022 | * Bless `s' in `p', via a temporary reference, required by sv_bless().
|
|---|
| 1023 | */
|
|---|
| 1024 | #define BLESS(s,p) \
|
|---|
| 1025 | STMT_START { \
|
|---|
| 1026 | SV *ref; \
|
|---|
| 1027 | HV *stash; \
|
|---|
| 1028 | TRACEME(("blessing 0x%"UVxf" in %s", PTR2UV(s), (p))); \
|
|---|
| 1029 | stash = gv_stashpv((p), TRUE); \
|
|---|
| 1030 | ref = newRV_noinc(s); \
|
|---|
| 1031 | (void) sv_bless(ref, stash); \
|
|---|
| 1032 | SvRV_set(ref, NULL); \
|
|---|
| 1033 | SvREFCNT_dec(ref); \
|
|---|
| 1034 | } STMT_END
|
|---|
| 1035 | /*
|
|---|
| 1036 | * sort (used in store_hash) - conditionally use qsort when
|
|---|
| 1037 | * sortsv is not available ( <= 5.6.1 ).
|
|---|
| 1038 | */
|
|---|
| 1039 |
|
|---|
| 1040 | #if (PATCHLEVEL <= 6)
|
|---|
| 1041 |
|
|---|
| 1042 | #if defined(USE_ITHREADS)
|
|---|
| 1043 |
|
|---|
| 1044 | #define STORE_HASH_SORT \
|
|---|
| 1045 | ENTER; { \
|
|---|
| 1046 | PerlInterpreter *orig_perl = PERL_GET_CONTEXT; \
|
|---|
| 1047 | SAVESPTR(orig_perl); \
|
|---|
| 1048 | PERL_SET_CONTEXT(aTHX); \
|
|---|
| 1049 | qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp); \
|
|---|
| 1050 | } LEAVE;
|
|---|
| 1051 |
|
|---|
| 1052 | #else /* ! USE_ITHREADS */
|
|---|
| 1053 |
|
|---|
| 1054 | #define STORE_HASH_SORT \
|
|---|
| 1055 | qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp);
|
|---|
| 1056 |
|
|---|
| 1057 | #endif /* USE_ITHREADS */
|
|---|
| 1058 |
|
|---|
| 1059 | #else /* PATCHLEVEL > 6 */
|
|---|
| 1060 |
|
|---|
| 1061 | #define STORE_HASH_SORT \
|
|---|
| 1062 | sortsv(AvARRAY(av), len, Perl_sv_cmp);
|
|---|
| 1063 |
|
|---|
| 1064 | #endif /* PATCHLEVEL <= 6 */
|
|---|
| 1065 |
|
|---|
| 1066 | static int store(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1067 | static SV *retrieve(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1068 |
|
|---|
| 1069 | /*
|
|---|
| 1070 | * Dynamic dispatching table for SV store.
|
|---|
| 1071 | */
|
|---|
| 1072 |
|
|---|
| 1073 | static int store_ref(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1074 | static int store_scalar(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1075 | static int store_array(pTHX_ stcxt_t *cxt, AV *av);
|
|---|
| 1076 | static int store_hash(pTHX_ stcxt_t *cxt, HV *hv);
|
|---|
| 1077 | static int store_tied(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1078 | static int store_tied_item(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1079 | static int store_code(pTHX_ stcxt_t *cxt, CV *cv);
|
|---|
| 1080 | static int store_other(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1081 | static int store_blessed(pTHX_ stcxt_t *cxt, SV *sv, int type, HV *pkg);
|
|---|
| 1082 |
|
|---|
| 1083 | typedef int (*sv_store_t)(pTHX_ stcxt_t *cxt, SV *sv);
|
|---|
| 1084 |
|
|---|
| 1085 | static sv_store_t sv_store[] = {
|
|---|
| 1086 | (sv_store_t)store_ref, /* svis_REF */
|
|---|
| 1087 | (sv_store_t)store_scalar, /* svis_SCALAR */
|
|---|
| 1088 | (sv_store_t)store_array, /* svis_ARRAY */
|
|---|
| 1089 | (sv_store_t)store_hash, /* svis_HASH */
|
|---|
| 1090 | (sv_store_t)store_tied, /* svis_TIED */
|
|---|
| 1091 | (sv_store_t)store_tied_item, /* svis_TIED_ITEM */
|
|---|
| 1092 | (sv_store_t)store_code, /* svis_CODE */
|
|---|
| 1093 | (sv_store_t)store_other, /* svis_OTHER */
|
|---|
| 1094 | };
|
|---|
| 1095 |
|
|---|
| 1096 | #define SV_STORE(x) (*sv_store[x])
|
|---|
| 1097 |
|
|---|
| 1098 | /*
|
|---|
| 1099 | * Dynamic dispatching tables for SV retrieval.
|
|---|
| 1100 | */
|
|---|
| 1101 |
|
|---|
| 1102 | static SV *retrieve_lscalar(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1103 | static SV *retrieve_lutf8str(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1104 | static SV *old_retrieve_array(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1105 | static SV *old_retrieve_hash(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1106 | static SV *retrieve_ref(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1107 | static SV *retrieve_undef(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1108 | static SV *retrieve_integer(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1109 | static SV *retrieve_double(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1110 | static SV *retrieve_byte(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1111 | static SV *retrieve_netint(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1112 | static SV *retrieve_scalar(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1113 | static SV *retrieve_utf8str(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1114 | static SV *retrieve_tied_array(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1115 | static SV *retrieve_tied_hash(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1116 | static SV *retrieve_tied_scalar(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1117 | static SV *retrieve_other(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1118 |
|
|---|
| 1119 | typedef SV* (*sv_retrieve_t)(pTHX_ stcxt_t *cxt, char *name);
|
|---|
| 1120 |
|
|---|
| 1121 | static const sv_retrieve_t sv_old_retrieve[] = {
|
|---|
| 1122 | 0, /* SX_OBJECT -- entry unused dynamically */
|
|---|
| 1123 | (sv_retrieve_t)retrieve_lscalar, /* SX_LSCALAR */
|
|---|
| 1124 | (sv_retrieve_t)old_retrieve_array, /* SX_ARRAY -- for pre-0.6 binaries */
|
|---|
| 1125 | (sv_retrieve_t)old_retrieve_hash, /* SX_HASH -- for pre-0.6 binaries */
|
|---|
| 1126 | (sv_retrieve_t)retrieve_ref, /* SX_REF */
|
|---|
| 1127 | (sv_retrieve_t)retrieve_undef, /* SX_UNDEF */
|
|---|
| 1128 | (sv_retrieve_t)retrieve_integer, /* SX_INTEGER */
|
|---|
| 1129 | (sv_retrieve_t)retrieve_double, /* SX_DOUBLE */
|
|---|
| 1130 | (sv_retrieve_t)retrieve_byte, /* SX_BYTE */
|
|---|
| 1131 | (sv_retrieve_t)retrieve_netint, /* SX_NETINT */
|
|---|
| 1132 | (sv_retrieve_t)retrieve_scalar, /* SX_SCALAR */
|
|---|
| 1133 | (sv_retrieve_t)retrieve_tied_array, /* SX_ARRAY */
|
|---|
| 1134 | (sv_retrieve_t)retrieve_tied_hash, /* SX_HASH */
|
|---|
| 1135 | (sv_retrieve_t)retrieve_tied_scalar, /* SX_SCALAR */
|
|---|
| 1136 | (sv_retrieve_t)retrieve_other, /* SX_SV_UNDEF not supported */
|
|---|
| 1137 | (sv_retrieve_t)retrieve_other, /* SX_SV_YES not supported */
|
|---|
| 1138 | (sv_retrieve_t)retrieve_other, /* SX_SV_NO not supported */
|
|---|
| 1139 | (sv_retrieve_t)retrieve_other, /* SX_BLESS not supported */
|
|---|
| 1140 | (sv_retrieve_t)retrieve_other, /* SX_IX_BLESS not supported */
|
|---|
| 1141 | (sv_retrieve_t)retrieve_other, /* SX_HOOK not supported */
|
|---|
| 1142 | (sv_retrieve_t)retrieve_other, /* SX_OVERLOADED not supported */
|
|---|
| 1143 | (sv_retrieve_t)retrieve_other, /* SX_TIED_KEY not supported */
|
|---|
| 1144 | (sv_retrieve_t)retrieve_other, /* SX_TIED_IDX not supported */
|
|---|
| 1145 | (sv_retrieve_t)retrieve_other, /* SX_UTF8STR not supported */
|
|---|
| 1146 | (sv_retrieve_t)retrieve_other, /* SX_LUTF8STR not supported */
|
|---|
| 1147 | (sv_retrieve_t)retrieve_other, /* SX_FLAG_HASH not supported */
|
|---|
| 1148 | (sv_retrieve_t)retrieve_other, /* SX_CODE not supported */
|
|---|
| 1149 | (sv_retrieve_t)retrieve_other, /* SX_WEAKREF not supported */
|
|---|
| 1150 | (sv_retrieve_t)retrieve_other, /* SX_WEAKOVERLOAD not supported */
|
|---|
| 1151 | (sv_retrieve_t)retrieve_other, /* SX_ERROR */
|
|---|
| 1152 | };
|
|---|
| 1153 |
|
|---|
| 1154 | static SV *retrieve_array(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1155 | static SV *retrieve_hash(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1156 | static SV *retrieve_sv_undef(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1157 | static SV *retrieve_sv_yes(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1158 | static SV *retrieve_sv_no(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1159 | static SV *retrieve_blessed(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1160 | static SV *retrieve_idx_blessed(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1161 | static SV *retrieve_hook(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1162 | static SV *retrieve_overloaded(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1163 | static SV *retrieve_tied_key(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1164 | static SV *retrieve_tied_idx(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1165 | static SV *retrieve_flag_hash(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1166 | static SV *retrieve_code(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1167 | static SV *retrieve_weakref(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1168 | static SV *retrieve_weakoverloaded(pTHX_ stcxt_t *cxt, char *cname);
|
|---|
| 1169 |
|
|---|
| 1170 | static const sv_retrieve_t sv_retrieve[] = {
|
|---|
| 1171 | 0, /* SX_OBJECT -- entry unused dynamically */
|
|---|
| 1172 | (sv_retrieve_t)retrieve_lscalar, /* SX_LSCALAR */
|
|---|
| 1173 | (sv_retrieve_t)retrieve_array, /* SX_ARRAY */
|
|---|
| 1174 | (sv_retrieve_t)retrieve_hash, /* SX_HASH */
|
|---|
| 1175 | (sv_retrieve_t)retrieve_ref, /* SX_REF */
|
|---|
| 1176 | (sv_retrieve_t)retrieve_undef, /* SX_UNDEF */
|
|---|
| 1177 | (sv_retrieve_t)retrieve_integer, /* SX_INTEGER */
|
|---|
| 1178 | (sv_retrieve_t)retrieve_double, /* SX_DOUBLE */
|
|---|
| 1179 | (sv_retrieve_t)retrieve_byte, /* SX_BYTE */
|
|---|
| 1180 | (sv_retrieve_t)retrieve_netint, /* SX_NETINT */
|
|---|
| 1181 | (sv_retrieve_t)retrieve_scalar, /* SX_SCALAR */
|
|---|
| 1182 | (sv_retrieve_t)retrieve_tied_array, /* SX_ARRAY */
|
|---|
| 1183 | (sv_retrieve_t)retrieve_tied_hash, /* SX_HASH */
|
|---|
| 1184 | (sv_retrieve_t)retrieve_tied_scalar, /* SX_SCALAR */
|
|---|
| 1185 | (sv_retrieve_t)retrieve_sv_undef, /* SX_SV_UNDEF */
|
|---|
| 1186 | (sv_retrieve_t)retrieve_sv_yes, /* SX_SV_YES */
|
|---|
| 1187 | (sv_retrieve_t)retrieve_sv_no, /* SX_SV_NO */
|
|---|
| 1188 | (sv_retrieve_t)retrieve_blessed, /* SX_BLESS */
|
|---|
| 1189 | (sv_retrieve_t)retrieve_idx_blessed, /* SX_IX_BLESS */
|
|---|
| 1190 | (sv_retrieve_t)retrieve_hook, /* SX_HOOK */
|
|---|
| 1191 | (sv_retrieve_t)retrieve_overloaded, /* SX_OVERLOAD */
|
|---|
| 1192 | (sv_retrieve_t)retrieve_tied_key, /* SX_TIED_KEY */
|
|---|
| 1193 | (sv_retrieve_t)retrieve_tied_idx, /* SX_TIED_IDX */
|
|---|
| 1194 | (sv_retrieve_t)retrieve_utf8str, /* SX_UTF8STR */
|
|---|
| 1195 | (sv_retrieve_t)retrieve_lutf8str, /* SX_LUTF8STR */
|
|---|
| 1196 | (sv_retrieve_t)retrieve_flag_hash, /* SX_HASH */
|
|---|
| 1197 | (sv_retrieve_t)retrieve_code, /* SX_CODE */
|
|---|
| 1198 | (sv_retrieve_t)retrieve_weakref, /* SX_WEAKREF */
|
|---|
| 1199 | (sv_retrieve_t)retrieve_weakoverloaded, /* SX_WEAKOVERLOAD */
|
|---|
| 1200 | (sv_retrieve_t)retrieve_other, /* SX_ERROR */
|
|---|
| 1201 | };
|
|---|
| 1202 |
|
|---|
| 1203 | #define RETRIEVE(c,x) (*(c)->retrieve_vtbl[(x) >= SX_ERROR ? SX_ERROR : (x)])
|
|---|
| 1204 |
|
|---|
| 1205 | static SV *mbuf2sv(pTHX);
|
|---|
| 1206 |
|
|---|
| 1207 | /***
|
|---|
| 1208 | *** Context management.
|
|---|
| 1209 | ***/
|
|---|
| 1210 |
|
|---|
| 1211 | /*
|
|---|
| 1212 | * init_perinterp
|
|---|
| 1213 | *
|
|---|
| 1214 | * Called once per "thread" (interpreter) to initialize some global context.
|
|---|
| 1215 | */
|
|---|
| 1216 | static void init_perinterp(pTHX)
|
|---|
| 1217 | {
|
|---|
| 1218 | INIT_STCXT;
|
|---|
| 1219 |
|
|---|
| 1220 | cxt->netorder = 0; /* true if network order used */
|
|---|
| 1221 | cxt->forgive_me = -1; /* whether to be forgiving... */
|
|---|
| 1222 | cxt->accept_future_minor = -1; /* would otherwise occur too late */
|
|---|
| 1223 | }
|
|---|
| 1224 |
|
|---|
| 1225 | /*
|
|---|
| 1226 | * reset_context
|
|---|
| 1227 | *
|
|---|
| 1228 | * Called at the end of every context cleaning, to perform common reset
|
|---|
| 1229 | * operations.
|
|---|
| 1230 | */
|
|---|
| 1231 | static void reset_context(stcxt_t *cxt)
|
|---|
| 1232 | {
|
|---|
| 1233 | cxt->entry = 0;
|
|---|
| 1234 | cxt->s_dirty = 0;
|
|---|
| 1235 | cxt->optype &= ~(ST_STORE|ST_RETRIEVE); /* Leave ST_CLONE alone */
|
|---|
| 1236 | }
|
|---|
| 1237 |
|
|---|
| 1238 | /*
|
|---|
| 1239 | * init_store_context
|
|---|
| 1240 | *
|
|---|
| 1241 | * Initialize a new store context for real recursion.
|
|---|
| 1242 | */
|
|---|
| 1243 | static void init_store_context(
|
|---|
| 1244 | pTHX_
|
|---|
| 1245 | stcxt_t *cxt,
|
|---|
| 1246 | PerlIO *f,
|
|---|
| 1247 | int optype,
|
|---|
| 1248 | int network_order)
|
|---|
| 1249 | {
|
|---|
| 1250 | TRACEME(("init_store_context"));
|
|---|
| 1251 |
|
|---|
| 1252 | cxt->netorder = network_order;
|
|---|
| 1253 | cxt->forgive_me = -1; /* Fetched from perl if needed */
|
|---|
| 1254 | cxt->deparse = -1; /* Idem */
|
|---|
| 1255 | cxt->eval = NULL; /* Idem */
|
|---|
| 1256 | cxt->canonical = -1; /* Idem */
|
|---|
| 1257 | cxt->tagnum = -1; /* Reset tag numbers */
|
|---|
| 1258 | cxt->classnum = -1; /* Reset class numbers */
|
|---|
| 1259 | cxt->fio = f; /* Where I/O are performed */
|
|---|
| 1260 | cxt->optype = optype; /* A store, or a deep clone */
|
|---|
| 1261 | cxt->entry = 1; /* No recursion yet */
|
|---|
| 1262 |
|
|---|
| 1263 | /*
|
|---|
| 1264 | * The `hseen' table is used to keep track of each SV stored and their
|
|---|
| 1265 | * associated tag numbers is special. It is "abused" because the
|
|---|
| 1266 | * values stored are not real SV, just integers cast to (SV *),
|
|---|
| 1267 | * which explains the freeing below.
|
|---|
| 1268 | *
|
|---|
| 1269 | * It is also one possible bottlneck to achieve good storing speed,
|
|---|
| 1270 | * so the "shared keys" optimization is turned off (unlikely to be
|
|---|
| 1271 | * of any use here), and the hash table is "pre-extended". Together,
|
|---|
| 1272 | * those optimizations increase the throughput by 12%.
|
|---|
| 1273 | */
|
|---|
| 1274 |
|
|---|
| 1275 | #ifdef USE_PTR_TABLE
|
|---|
| 1276 | cxt->pseen = ptr_table_new();
|
|---|
| 1277 | cxt->hseen = 0;
|
|---|
| 1278 | #else
|
|---|
| 1279 | cxt->hseen = newHV(); /* Table where seen objects are stored */
|
|---|
| 1280 | HvSHAREKEYS_off(cxt->hseen);
|
|---|
| 1281 | #endif
|
|---|
| 1282 | /*
|
|---|
| 1283 | * The following does not work well with perl5.004_04, and causes
|
|---|
| 1284 | * a core dump later on, in a completely unrelated spot, which
|
|---|
| 1285 | * makes me think there is a memory corruption going on.
|
|---|
| 1286 | *
|
|---|
| 1287 | * Calling hv_ksplit(hseen, HBUCKETS) instead of manually hacking
|
|---|
| 1288 | * it below does not make any difference. It seems to work fine
|
|---|
| 1289 | * with perl5.004_68 but given the probable nature of the bug,
|
|---|
| 1290 | * that does not prove anything.
|
|---|
| 1291 | *
|
|---|
| 1292 | * It's a shame because increasing the amount of buckets raises
|
|---|
| 1293 | * store() throughput by 5%, but until I figure this out, I can't
|
|---|
| 1294 | * allow for this to go into production.
|
|---|
| 1295 | *
|
|---|
| 1296 | * It is reported fixed in 5.005, hence the #if.
|
|---|
| 1297 | */
|
|---|
| 1298 | #if PERL_VERSION >= 5
|
|---|
| 1299 | #define HBUCKETS 4096 /* Buckets for %hseen */
|
|---|
| 1300 | #ifndef USE_PTR_TABLE
|
|---|
| 1301 | HvMAX(cxt->hseen) = HBUCKETS - 1; /* keys %hseen = $HBUCKETS; */
|
|---|
| 1302 | #endif
|
|---|
| 1303 | #endif
|
|---|
| 1304 |
|
|---|
| 1305 | /*
|
|---|
| 1306 | * The `hclass' hash uses the same settings as `hseen' above, but it is
|
|---|
| 1307 | * used to assign sequential tags (numbers) to class names for blessed
|
|---|
| 1308 | * objects.
|
|---|
| 1309 | *
|
|---|
| 1310 | * We turn the shared key optimization on.
|
|---|
| 1311 | */
|
|---|
| 1312 |
|
|---|
| 1313 | cxt->hclass = newHV(); /* Where seen classnames are stored */
|
|---|
| 1314 |
|
|---|
| 1315 | #if PERL_VERSION >= 5
|
|---|
| 1316 | HvMAX(cxt->hclass) = HBUCKETS - 1; /* keys %hclass = $HBUCKETS; */
|
|---|
| 1317 | #endif
|
|---|
| 1318 |
|
|---|
| 1319 | /*
|
|---|
| 1320 | * The `hook' hash table is used to keep track of the references on
|
|---|
| 1321 | * the STORABLE_freeze hook routines, when found in some class name.
|
|---|
| 1322 | *
|
|---|
| 1323 | * It is assumed that the inheritance tree will not be changed during
|
|---|
| 1324 | * storing, and that no new method will be dynamically created by the
|
|---|
| 1325 | * hooks.
|
|---|
| 1326 | */
|
|---|
| 1327 |
|
|---|
| 1328 | cxt->hook = newHV(); /* Table where hooks are cached */
|
|---|
| 1329 |
|
|---|
| 1330 | /*
|
|---|
| 1331 | * The `hook_seen' array keeps track of all the SVs returned by
|
|---|
| 1332 | * STORABLE_freeze hooks for us to serialize, so that they are not
|
|---|
| 1333 | * reclaimed until the end of the serialization process. Each SV is
|
|---|
| 1334 | * only stored once, the first time it is seen.
|
|---|
| 1335 | */
|
|---|
| 1336 |
|
|---|
| 1337 | cxt->hook_seen = newAV(); /* Lists SVs returned by STORABLE_freeze */
|
|---|
| 1338 | }
|
|---|
| 1339 |
|
|---|
| 1340 | /*
|
|---|
| 1341 | * clean_store_context
|
|---|
| 1342 | *
|
|---|
| 1343 | * Clean store context by
|
|---|
| 1344 | */
|
|---|
| 1345 | static void clean_store_context(pTHX_ stcxt_t *cxt)
|
|---|
| 1346 | {
|
|---|
| 1347 | HE *he;
|
|---|
| 1348 |
|
|---|
| 1349 | TRACEME(("clean_store_context"));
|
|---|
| 1350 |
|
|---|
| 1351 | ASSERT(cxt->optype & ST_STORE, ("was performing a store()"));
|
|---|
| 1352 |
|
|---|
| 1353 | /*
|
|---|
| 1354 | * Insert real values into hashes where we stored faked pointers.
|
|---|
| 1355 | */
|
|---|
| 1356 |
|
|---|
| 1357 | #ifndef USE_PTR_TABLE
|
|---|
| 1358 | if (cxt->hseen) {
|
|---|
| 1359 | hv_iterinit(cxt->hseen);
|
|---|
| 1360 | while ((he = hv_iternext(cxt->hseen))) /* Extra () for -Wall, grr.. */
|
|---|
| 1361 | HeVAL(he) = &PL_sv_undef;
|
|---|
| 1362 | }
|
|---|
| 1363 | #endif
|
|---|
| 1364 |
|
|---|
| 1365 | if (cxt->hclass) {
|
|---|
| 1366 | hv_iterinit(cxt->hclass);
|
|---|
| 1367 | while ((he = hv_iternext(cxt->hclass))) /* Extra () for -Wall, grr.. */
|
|---|
| 1368 | HeVAL(he) = &PL_sv_undef;
|
|---|
| 1369 | }
|
|---|
| 1370 |
|
|---|
| 1371 | /*
|
|---|
| 1372 | * And now dispose of them...
|
|---|
| 1373 | *
|
|---|
| 1374 | * The surrounding if() protection has been added because there might be
|
|---|
| 1375 | * some cases where this routine is called more than once, during
|
|---|
| 1376 | * exceptionnal events. This was reported by Marc Lehmann when Storable
|
|---|
| 1377 | * is executed from mod_perl, and the fix was suggested by him.
|
|---|
| 1378 | * -- RAM, 20/12/2000
|
|---|
| 1379 | */
|
|---|
| 1380 |
|
|---|
| 1381 | #ifdef USE_PTR_TABLE
|
|---|
| 1382 | if (cxt->pseen) {
|
|---|
| 1383 | struct ptr_tbl *pseen = cxt->pseen;
|
|---|
| 1384 | cxt->pseen = 0;
|
|---|
| 1385 | ptr_table_free(pseen);
|
|---|
| 1386 | }
|
|---|
| 1387 | assert(!cxt->hseen);
|
|---|
| 1388 | #else
|
|---|
| 1389 | if (cxt->hseen) {
|
|---|
| 1390 | HV *hseen = cxt->hseen;
|
|---|
| 1391 | cxt->hseen = 0;
|
|---|
| 1392 | hv_undef(hseen);
|
|---|
| 1393 | sv_free((SV *) hseen);
|
|---|
| 1394 | }
|
|---|
| 1395 | #endif
|
|---|
| 1396 |
|
|---|
| 1397 | if (cxt->hclass) {
|
|---|
| 1398 | HV *hclass = cxt->hclass;
|
|---|
| 1399 | cxt->hclass = 0;
|
|---|
| 1400 | hv_undef(hclass);
|
|---|
| 1401 | sv_free((SV *) hclass);
|
|---|
| 1402 | }
|
|---|
| 1403 |
|
|---|
| 1404 | if (cxt->hook) {
|
|---|
| 1405 | HV *hook = cxt->hook;
|
|---|
| 1406 | cxt->hook = 0;
|
|---|
| 1407 | hv_undef(hook);
|
|---|
| 1408 | sv_free((SV *) hook);
|
|---|
| 1409 | }
|
|---|
| 1410 |
|
|---|
| 1411 | if (cxt->hook_seen) {
|
|---|
| 1412 | AV *hook_seen = cxt->hook_seen;
|
|---|
| 1413 | cxt->hook_seen = 0;
|
|---|
| 1414 | av_undef(hook_seen);
|
|---|
| 1415 | sv_free((SV *) hook_seen);
|
|---|
| 1416 | }
|
|---|
| 1417 |
|
|---|
| 1418 | cxt->forgive_me = -1; /* Fetched from perl if needed */
|
|---|
| 1419 | cxt->deparse = -1; /* Idem */
|
|---|
| 1420 | if (cxt->eval) {
|
|---|
| 1421 | SvREFCNT_dec(cxt->eval);
|
|---|
| 1422 | }
|
|---|
| 1423 | cxt->eval = NULL; /* Idem */
|
|---|
| 1424 | cxt->canonical = -1; /* Idem */
|
|---|
| 1425 |
|
|---|
| 1426 | reset_context(cxt);
|
|---|
| 1427 | }
|
|---|
| 1428 |
|
|---|
| 1429 | /*
|
|---|
| 1430 | * init_retrieve_context
|
|---|
| 1431 | *
|
|---|
| 1432 | * Initialize a new retrieve context for real recursion.
|
|---|
| 1433 | */
|
|---|
| 1434 | static void init_retrieve_context(pTHX_ stcxt_t *cxt, int optype, int is_tainted)
|
|---|
| 1435 | {
|
|---|
| 1436 | TRACEME(("init_retrieve_context"));
|
|---|
| 1437 |
|
|---|
| 1438 | /*
|
|---|
| 1439 | * The hook hash table is used to keep track of the references on
|
|---|
| 1440 | * the STORABLE_thaw hook routines, when found in some class name.
|
|---|
| 1441 | *
|
|---|
| 1442 | * It is assumed that the inheritance tree will not be changed during
|
|---|
| 1443 | * storing, and that no new method will be dynamically created by the
|
|---|
| 1444 | * hooks.
|
|---|
| 1445 | */
|
|---|
| 1446 |
|
|---|
| 1447 | cxt->hook = newHV(); /* Caches STORABLE_thaw */
|
|---|
| 1448 |
|
|---|
| 1449 | #ifdef USE_PTR_TABLE
|
|---|
| 1450 | cxt->pseen = 0;
|
|---|
| 1451 | #endif
|
|---|
| 1452 |
|
|---|
| 1453 | /*
|
|---|
| 1454 | * If retrieving an old binary version, the cxt->retrieve_vtbl variable
|
|---|
| 1455 | * was set to sv_old_retrieve. We'll need a hash table to keep track of
|
|---|
| 1456 | * the correspondance between the tags and the tag number used by the
|
|---|
| 1457 | * new retrieve routines.
|
|---|
| 1458 | */
|
|---|
| 1459 |
|
|---|
| 1460 | cxt->hseen = (((void*)cxt->retrieve_vtbl == (void*)sv_old_retrieve)
|
|---|
| 1461 | ? newHV() : 0);
|
|---|
| 1462 |
|
|---|
| 1463 | cxt->aseen = newAV(); /* Where retrieved objects are kept */
|
|---|
| 1464 | cxt->where_is_undef = -1; /* Special case for PL_sv_undef */
|
|---|
| 1465 | cxt->aclass = newAV(); /* Where seen classnames are kept */
|
|---|
| 1466 | cxt->tagnum = 0; /* Have to count objects... */
|
|---|
| 1467 | cxt->classnum = 0; /* ...and class names as well */
|
|---|
| 1468 | cxt->optype = optype;
|
|---|
| 1469 | cxt->s_tainted = is_tainted;
|
|---|
| 1470 | cxt->entry = 1; /* No recursion yet */
|
|---|
| 1471 | #ifndef HAS_RESTRICTED_HASHES
|
|---|
| 1472 | cxt->derestrict = -1; /* Fetched from perl if needed */
|
|---|
| 1473 | #endif
|
|---|
| 1474 | #ifndef HAS_UTF8_ALL
|
|---|
| 1475 | cxt->use_bytes = -1; /* Fetched from perl if needed */
|
|---|
| 1476 | #endif
|
|---|
| 1477 | cxt->accept_future_minor = -1; /* Fetched from perl if needed */
|
|---|
| 1478 | }
|
|---|
| 1479 |
|
|---|
| 1480 | /*
|
|---|
| 1481 | * clean_retrieve_context
|
|---|
| 1482 | *
|
|---|
| 1483 | * Clean retrieve context by
|
|---|
| 1484 | */
|
|---|
| 1485 | static void clean_retrieve_context(pTHX_ stcxt_t *cxt)
|
|---|
| 1486 | {
|
|---|
| 1487 | TRACEME(("clean_retrieve_context"));
|
|---|
| 1488 |
|
|---|
| 1489 | ASSERT(cxt->optype & ST_RETRIEVE, ("was performing a retrieve()"));
|
|---|
| 1490 |
|
|---|
| 1491 | if (cxt->aseen) {
|
|---|
| 1492 | AV *aseen = cxt->aseen;
|
|---|
| 1493 | cxt->aseen = 0;
|
|---|
| 1494 | av_undef(aseen);
|
|---|
| 1495 | sv_free((SV *) aseen);
|
|---|
| 1496 | }
|
|---|
| 1497 | cxt->where_is_undef = -1;
|
|---|
| 1498 |
|
|---|
| 1499 | if (cxt->aclass) {
|
|---|
| 1500 | AV *aclass = cxt->aclass;
|
|---|
| 1501 | cxt->aclass = 0;
|
|---|
| 1502 | av_undef(aclass);
|
|---|
| 1503 | sv_free((SV *) aclass);
|
|---|
| 1504 | }
|
|---|
| 1505 |
|
|---|
| 1506 | if (cxt->hook) {
|
|---|
| 1507 | HV *hook = cxt->hook;
|
|---|
| 1508 | cxt->hook = 0;
|
|---|
| 1509 | hv_undef(hook);
|
|---|
| 1510 | sv_free((SV *) hook);
|
|---|
| 1511 | }
|
|---|
| 1512 |
|
|---|
| 1513 | if (cxt->hseen) {
|
|---|
| 1514 | HV *hseen = cxt->hseen;
|
|---|
| 1515 | cxt->hseen = 0;
|
|---|
| 1516 | hv_undef(hseen);
|
|---|
| 1517 | sv_free((SV *) hseen); /* optional HV, for backward compat. */
|
|---|
| 1518 | }
|
|---|
| 1519 |
|
|---|
| 1520 | #ifndef HAS_RESTRICTED_HASHES
|
|---|
| 1521 | cxt->derestrict = -1; /* Fetched from perl if needed */
|
|---|
| 1522 | #endif
|
|---|
| 1523 | #ifndef HAS_UTF8_ALL
|
|---|
| 1524 | cxt->use_bytes = -1; /* Fetched from perl if needed */
|
|---|
| 1525 | #endif
|
|---|
| 1526 | cxt->accept_future_minor = -1; /* Fetched from perl if needed */
|
|---|
| 1527 |
|
|---|
| 1528 | reset_context(cxt);
|
|---|
| 1529 | }
|
|---|
| 1530 |
|
|---|
| 1531 | /*
|
|---|
| 1532 | * clean_context
|
|---|
| 1533 | *
|
|---|
| 1534 | * A workaround for the CROAK bug: cleanup the last context.
|
|---|
| 1535 | */
|
|---|
| 1536 | static void clean_context(pTHX_ stcxt_t *cxt)
|
|---|
| 1537 | {
|
|---|
| 1538 | TRACEME(("clean_context"));
|
|---|
| 1539 |
|
|---|
| 1540 | ASSERT(cxt->s_dirty, ("dirty context"));
|
|---|
| 1541 |
|
|---|
| 1542 | if (cxt->membuf_ro)
|
|---|
| 1543 | MBUF_RESTORE();
|
|---|
| 1544 |
|
|---|
| 1545 | ASSERT(!cxt->membuf_ro, ("mbase is not read-only"));
|
|---|
| 1546 |
|
|---|
| 1547 | if (cxt->optype & ST_RETRIEVE)
|
|---|
| 1548 | clean_retrieve_context(aTHX_ cxt);
|
|---|
| 1549 | else if (cxt->optype & ST_STORE)
|
|---|
| 1550 | clean_store_context(aTHX_ cxt);
|
|---|
| 1551 | else
|
|---|
| 1552 | reset_context(cxt);
|
|---|
| 1553 |
|
|---|
| 1554 | ASSERT(!cxt->s_dirty, ("context is clean"));
|
|---|
| 1555 | ASSERT(cxt->entry == 0, ("context is reset"));
|
|---|
| 1556 | }
|
|---|
| 1557 |
|
|---|
| 1558 | /*
|
|---|
| 1559 | * allocate_context
|
|---|
| 1560 | *
|
|---|
| 1561 | * Allocate a new context and push it on top of the parent one.
|
|---|
| 1562 | * This new context is made globally visible via SET_STCXT().
|
|---|
| 1563 | */
|
|---|
| 1564 | static stcxt_t *allocate_context(pTHX_ stcxt_t *parent_cxt)
|
|---|
| 1565 | {
|
|---|
| 1566 | stcxt_t *cxt;
|
|---|
| 1567 |
|
|---|
| 1568 | TRACEME(("allocate_context"));
|
|---|
| 1569 |
|
|---|
| 1570 | ASSERT(!parent_cxt->s_dirty, ("parent context clean"));
|
|---|
| 1571 |
|
|---|
| 1572 | NEW_STORABLE_CXT_OBJ(cxt);
|
|---|
| 1573 | cxt->prev = parent_cxt->my_sv;
|
|---|
| 1574 | SET_STCXT(cxt);
|
|---|
| 1575 |
|
|---|
| 1576 | ASSERT(!cxt->s_dirty, ("clean context"));
|
|---|
| 1577 |
|
|---|
| 1578 | return cxt;
|
|---|
| 1579 | }
|
|---|
| 1580 |
|
|---|
| 1581 | /*
|
|---|
| 1582 | * free_context
|
|---|
| 1583 | *
|
|---|
| 1584 | * Free current context, which cannot be the "root" one.
|
|---|
| 1585 | * Make the context underneath globally visible via SET_STCXT().
|
|---|
| 1586 | */
|
|---|
| 1587 | static void free_context(pTHX_ stcxt_t *cxt)
|
|---|
| 1588 | {
|
|---|
| 1589 | stcxt_t *prev = (stcxt_t *)(cxt->prev ? SvPVX(SvRV(cxt->prev)) : 0);
|
|---|
| 1590 |
|
|---|
| 1591 | TRACEME(("free_context"));
|
|---|
| 1592 |
|
|---|
| 1593 | ASSERT(!cxt->s_dirty, ("clean context"));
|
|---|
| 1594 | ASSERT(prev, ("not freeing root context"));
|
|---|
| 1595 |
|
|---|
| 1596 | SvREFCNT_dec(cxt->my_sv);
|
|---|
| 1597 | SET_STCXT(prev);
|
|---|
| 1598 |
|
|---|
| 1599 | ASSERT(cxt, ("context not void"));
|
|---|
| 1600 | }
|
|---|
| 1601 |
|
|---|
| 1602 | /***
|
|---|
| 1603 | *** Predicates.
|
|---|
| 1604 | ***/
|
|---|
| 1605 |
|
|---|
| 1606 | /*
|
|---|
| 1607 | * is_storing
|
|---|
| 1608 | *
|
|---|
| 1609 | * Tells whether we're in the middle of a store operation.
|
|---|
| 1610 | */
|
|---|
| 1611 | int is_storing(pTHX)
|
|---|
| 1612 | {
|
|---|
| 1613 | dSTCXT;
|
|---|
| 1614 |
|
|---|
| 1615 | return cxt->entry && (cxt->optype & ST_STORE);
|
|---|
| 1616 | }
|
|---|
| 1617 |
|
|---|
| 1618 | /*
|
|---|
| 1619 | * is_retrieving
|
|---|
| 1620 | *
|
|---|
| 1621 | * Tells whether we're in the middle of a retrieve operation.
|
|---|
| 1622 | */
|
|---|
| 1623 | int is_retrieving(pTHX)
|
|---|
| 1624 | {
|
|---|
| 1625 | dSTCXT;
|
|---|
| 1626 |
|
|---|
| 1627 | return cxt->entry && (cxt->optype & ST_RETRIEVE);
|
|---|
| 1628 | }
|
|---|
| 1629 |
|
|---|
| 1630 | /*
|
|---|
| 1631 | * last_op_in_netorder
|
|---|
| 1632 | *
|
|---|
| 1633 | * Returns whether last operation was made using network order.
|
|---|
| 1634 | *
|
|---|
| 1635 | * This is typically out-of-band information that might prove useful
|
|---|
| 1636 | * to people wishing to convert native to network order data when used.
|
|---|
| 1637 | */
|
|---|
| 1638 | int last_op_in_netorder(pTHX)
|
|---|
| 1639 | {
|
|---|
| 1640 | dSTCXT;
|
|---|
| 1641 |
|
|---|
| 1642 | return cxt->netorder;
|
|---|
| 1643 | }
|
|---|
| 1644 |
|
|---|
| 1645 | /***
|
|---|
| 1646 | *** Hook lookup and calling routines.
|
|---|
| 1647 | ***/
|
|---|
| 1648 |
|
|---|
| 1649 | /*
|
|---|
| 1650 | * pkg_fetchmeth
|
|---|
| 1651 | *
|
|---|
| 1652 | * A wrapper on gv_fetchmethod_autoload() which caches results.
|
|---|
| 1653 | *
|
|---|
| 1654 | * Returns the routine reference as an SV*, or null if neither the package
|
|---|
| 1655 | * nor its ancestors know about the method.
|
|---|
| 1656 | */
|
|---|
| 1657 | static SV *pkg_fetchmeth(
|
|---|
| 1658 | pTHX_
|
|---|
| 1659 | HV *cache,
|
|---|
| 1660 | HV *pkg,
|
|---|
| 1661 | char *method)
|
|---|
| 1662 | {
|
|---|
| 1663 | GV *gv;
|
|---|
| 1664 | SV *sv;
|
|---|
| 1665 | const char *hvname = HvNAME_get(pkg);
|
|---|
| 1666 |
|
|---|
| 1667 |
|
|---|
| 1668 | /*
|
|---|
| 1669 | * The following code is the same as the one performed by UNIVERSAL::can
|
|---|
| 1670 | * in the Perl core.
|
|---|
| 1671 | */
|
|---|
| 1672 |
|
|---|
| 1673 | gv = gv_fetchmethod_autoload(pkg, method, FALSE);
|
|---|
| 1674 | if (gv && isGV(gv)) {
|
|---|
| 1675 | sv = newRV((SV*) GvCV(gv));
|
|---|
| 1676 | TRACEME(("%s->%s: 0x%"UVxf, hvname, method, PTR2UV(sv)));
|
|---|
| 1677 | } else {
|
|---|
| 1678 | sv = newSVsv(&PL_sv_undef);
|
|---|
| 1679 | TRACEME(("%s->%s: not found", hvname, method));
|
|---|
| 1680 | }
|
|---|
| 1681 |
|
|---|
| 1682 | /*
|
|---|
| 1683 | * Cache the result, ignoring failure: if we can't store the value,
|
|---|
| 1684 | * it just won't be cached.
|
|---|
| 1685 | */
|
|---|
| 1686 |
|
|---|
| 1687 | (void) hv_store(cache, hvname, strlen(hvname), sv, 0);
|
|---|
| 1688 |
|
|---|
| 1689 | return SvOK(sv) ? sv : (SV *) 0;
|
|---|
| 1690 | }
|
|---|
| 1691 |
|
|---|
| 1692 | /*
|
|---|
| 1693 | * pkg_hide
|
|---|
| 1694 | *
|
|---|
| 1695 | * Force cached value to be undef: hook ignored even if present.
|
|---|
| 1696 | */
|
|---|
| 1697 | static void pkg_hide(
|
|---|
| 1698 | pTHX_
|
|---|
| 1699 | HV *cache,
|
|---|
| 1700 | HV *pkg,
|
|---|
| 1701 | char *method)
|
|---|
| 1702 | {
|
|---|
| 1703 | const char *hvname = HvNAME_get(pkg);
|
|---|
| 1704 | (void) hv_store(cache,
|
|---|
| 1705 | hvname, strlen(hvname), newSVsv(&PL_sv_undef), 0);
|
|---|
| 1706 | }
|
|---|
| 1707 |
|
|---|
| 1708 | /*
|
|---|
| 1709 | * pkg_uncache
|
|---|
| 1710 | *
|
|---|
| 1711 | * Discard cached value: a whole fetch loop will be retried at next lookup.
|
|---|
| 1712 | */
|
|---|
| 1713 | static void pkg_uncache(
|
|---|
| 1714 | pTHX_
|
|---|
| 1715 | HV *cache,
|
|---|
| 1716 | HV *pkg,
|
|---|
| 1717 | char *method)
|
|---|
| 1718 | {
|
|---|
| 1719 | const char *hvname = HvNAME_get(pkg);
|
|---|
| 1720 | (void) hv_delete(cache, hvname, strlen(hvname), G_DISCARD);
|
|---|
| 1721 | }
|
|---|
| 1722 |
|
|---|
| 1723 | /*
|
|---|
| 1724 | * pkg_can
|
|---|
| 1725 | *
|
|---|
| 1726 | * Our own "UNIVERSAL::can", which caches results.
|
|---|
| 1727 | *
|
|---|
| 1728 | * Returns the routine reference as an SV*, or null if the object does not
|
|---|
| 1729 | * know about the method.
|
|---|
| 1730 | */
|
|---|
| 1731 | static SV *pkg_can(
|
|---|
| 1732 | pTHX_
|
|---|
| 1733 | HV *cache,
|
|---|
| 1734 | HV *pkg,
|
|---|
| 1735 | char *method)
|
|---|
| 1736 | {
|
|---|
| 1737 | SV **svh;
|
|---|
| 1738 | SV *sv;
|
|---|
| 1739 | const char *hvname = HvNAME_get(pkg);
|
|---|
| 1740 |
|
|---|
| 1741 | TRACEME(("pkg_can for %s->%s", hvname, method));
|
|---|
| 1742 |
|
|---|
| 1743 | /*
|
|---|
| 1744 | * Look into the cache to see whether we already have determined
|
|---|
| 1745 | * where the routine was, if any.
|
|---|
| 1746 | *
|
|---|
| 1747 | * NOTA BENE: we don't use `method' at all in our lookup, since we know
|
|---|
| 1748 | * that only one hook (i.e. always the same) is cached in a given cache.
|
|---|
| 1749 | */
|
|---|
| 1750 |
|
|---|
| 1751 | svh = hv_fetch(cache, hvname, strlen(hvname), FALSE);
|
|---|
| 1752 | if (svh) {
|
|---|
| 1753 | sv = *svh;
|
|---|
| 1754 | if (!SvOK(sv)) {
|
|---|
| 1755 | TRACEME(("cached %s->%s: not found", hvname, method));
|
|---|
| 1756 | return (SV *) 0;
|
|---|
| 1757 | } else {
|
|---|
| 1758 | TRACEME(("cached %s->%s: 0x%"UVxf,
|
|---|
| 1759 | hvname, method, PTR2UV(sv)));
|
|---|
| 1760 | return sv;
|
|---|
| 1761 | }
|
|---|
| 1762 | }
|
|---|
| 1763 |
|
|---|
| 1764 | TRACEME(("not cached yet"));
|
|---|
| 1765 | return pkg_fetchmeth(aTHX_ cache, pkg, method); /* Fetch and cache */
|
|---|
| 1766 | }
|
|---|
| 1767 |
|
|---|
| 1768 | /*
|
|---|
| 1769 | * scalar_call
|
|---|
| 1770 | *
|
|---|
| 1771 | * Call routine as obj->hook(av) in scalar context.
|
|---|
| 1772 | * Propagates the single returned value if not called in void context.
|
|---|
| 1773 | */
|
|---|
| 1774 | static SV *scalar_call(
|
|---|
| 1775 | pTHX_
|
|---|
| 1776 | SV *obj,
|
|---|
| 1777 | SV *hook,
|
|---|
| 1778 | int cloning,
|
|---|
| 1779 | AV *av,
|
|---|
| 1780 | I32 flags)
|
|---|
| 1781 | {
|
|---|
| 1782 | dSP;
|
|---|
| 1783 | int count;
|
|---|
| 1784 | SV *sv = 0;
|
|---|
| 1785 |
|
|---|
| 1786 | TRACEME(("scalar_call (cloning=%d)", cloning));
|
|---|
| 1787 |
|
|---|
| 1788 | ENTER;
|
|---|
| 1789 | SAVETMPS;
|
|---|
| 1790 |
|
|---|
| 1791 | PUSHMARK(sp);
|
|---|
| 1792 | XPUSHs(obj);
|
|---|
| 1793 | XPUSHs(sv_2mortal(newSViv(cloning))); /* Cloning flag */
|
|---|
| 1794 | if (av) {
|
|---|
| 1795 | SV **ary = AvARRAY(av);
|
|---|
| 1796 | int cnt = AvFILLp(av) + 1;
|
|---|
| 1797 | int i;
|
|---|
| 1798 | XPUSHs(ary[0]); /* Frozen string */
|
|---|
| 1799 | for (i = 1; i < cnt; i++) {
|
|---|
| 1800 | TRACEME(("pushing arg #%d (0x%"UVxf")...",
|
|---|
| 1801 | i, PTR2UV(ary[i])));
|
|---|
| 1802 | XPUSHs(sv_2mortal(newRV(ary[i])));
|
|---|
| 1803 | }
|
|---|
| 1804 | }
|
|---|
| 1805 | PUTBACK;
|
|---|
| 1806 |
|
|---|
| 1807 | TRACEME(("calling..."));
|
|---|
| 1808 | count = perl_call_sv(hook, flags); /* Go back to Perl code */
|
|---|
| 1809 | TRACEME(("count = %d", count));
|
|---|
| 1810 |
|
|---|
| 1811 | SPAGAIN;
|
|---|
| 1812 |
|
|---|
| 1813 | if (count) {
|
|---|
| 1814 | sv = POPs;
|
|---|
| 1815 | SvREFCNT_inc(sv); /* We're returning it, must stay alive! */
|
|---|
| 1816 | }
|
|---|
| 1817 |
|
|---|
| 1818 | PUTBACK;
|
|---|
| 1819 | FREETMPS;
|
|---|
| 1820 | LEAVE;
|
|---|
| 1821 |
|
|---|
| 1822 | return sv;
|
|---|
| 1823 | }
|
|---|
| 1824 |
|
|---|
| 1825 | /*
|
|---|
| 1826 | * array_call
|
|---|
| 1827 | *
|
|---|
| 1828 | * Call routine obj->hook(cloning) in list context.
|
|---|
| 1829 | * Returns the list of returned values in an array.
|
|---|
| 1830 | */
|
|---|
| 1831 | static AV *array_call(
|
|---|
| 1832 | pTHX_
|
|---|
| 1833 | SV *obj,
|
|---|
| 1834 | SV *hook,
|
|---|
| 1835 | int cloning)
|
|---|
| 1836 | {
|
|---|
| 1837 | dSP;
|
|---|
| 1838 | int count;
|
|---|
| 1839 | AV *av;
|
|---|
| 1840 | int i;
|
|---|
| 1841 |
|
|---|
| 1842 | TRACEME(("array_call (cloning=%d)", cloning));
|
|---|
| 1843 |
|
|---|
| 1844 | ENTER;
|
|---|
| 1845 | SAVETMPS;
|
|---|
| 1846 |
|
|---|
| 1847 | PUSHMARK(sp);
|
|---|
| 1848 | XPUSHs(obj); /* Target object */
|
|---|
| 1849 | XPUSHs(sv_2mortal(newSViv(cloning))); /* Cloning flag */
|
|---|
| 1850 | PUTBACK;
|
|---|
| 1851 |
|
|---|
| 1852 | count = perl_call_sv(hook, G_ARRAY); /* Go back to Perl code */
|
|---|
| 1853 |
|
|---|
| 1854 | SPAGAIN;
|
|---|
| 1855 |
|
|---|
| 1856 | av = newAV();
|
|---|
| 1857 | for (i = count - 1; i >= 0; i--) {
|
|---|
| 1858 | SV *sv = POPs;
|
|---|
| 1859 | av_store(av, i, SvREFCNT_inc(sv));
|
|---|
| 1860 | }
|
|---|
| 1861 |
|
|---|
| 1862 | PUTBACK;
|
|---|
| 1863 | FREETMPS;
|
|---|
| 1864 | LEAVE;
|
|---|
| 1865 |
|
|---|
| 1866 | return av;
|
|---|
| 1867 | }
|
|---|
| 1868 |
|
|---|
| 1869 | /*
|
|---|
| 1870 | * known_class
|
|---|
| 1871 | *
|
|---|
| 1872 | * Lookup the class name in the `hclass' table and either assign it a new ID
|
|---|
| 1873 | * or return the existing one, by filling in `classnum'.
|
|---|
| 1874 | *
|
|---|
| 1875 | * Return true if the class was known, false if the ID was just generated.
|
|---|
| 1876 | */
|
|---|
| 1877 | static int known_class(
|
|---|
| 1878 | pTHX_
|
|---|
| 1879 | stcxt_t *cxt,
|
|---|
| 1880 | char *name, /* Class name */
|
|---|
| 1881 | int len, /* Name length */
|
|---|
| 1882 | I32 *classnum)
|
|---|
| 1883 | {
|
|---|
| 1884 | SV **svh;
|
|---|
| 1885 | HV *hclass = cxt->hclass;
|
|---|
| 1886 |
|
|---|
| 1887 | TRACEME(("known_class (%s)", name));
|
|---|
| 1888 |
|
|---|
| 1889 | /*
|
|---|
| 1890 | * Recall that we don't store pointers in this hash table, but tags.
|
|---|
| 1891 | * Therefore, we need LOW_32BITS() to extract the relevant parts.
|
|---|
| 1892 | */
|
|---|
| 1893 |
|
|---|
| 1894 | svh = hv_fetch(hclass, name, len, FALSE);
|
|---|
| 1895 | if (svh) {
|
|---|
| 1896 | *classnum = LOW_32BITS(*svh);
|
|---|
| 1897 | return TRUE;
|
|---|
| 1898 | }
|
|---|
| 1899 |
|
|---|
| 1900 | /*
|
|---|
| 1901 | * Unknown classname, we need to record it.
|
|---|
| 1902 | */
|
|---|
| 1903 |
|
|---|
| 1904 | cxt->classnum++;
|
|---|
| 1905 | if (!hv_store(hclass, name, len, INT2PTR(SV*, cxt->classnum), 0))
|
|---|
| 1906 | CROAK(("Unable to record new classname"));
|
|---|
| 1907 |
|
|---|
| 1908 | *classnum = cxt->classnum;
|
|---|
| 1909 | return FALSE;
|
|---|
| 1910 | }
|
|---|
| 1911 |
|
|---|
| 1912 | /***
|
|---|
| 1913 | *** Sepcific store routines.
|
|---|
| 1914 | ***/
|
|---|
| 1915 |
|
|---|
| 1916 | /*
|
|---|
| 1917 | * store_ref
|
|---|
| 1918 | *
|
|---|
| 1919 | * Store a reference.
|
|---|
| 1920 | * Layout is SX_REF <object> or SX_OVERLOAD <object>.
|
|---|
| 1921 | */
|
|---|
| 1922 | static int store_ref(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 1923 | {
|
|---|
| 1924 | int is_weak = 0;
|
|---|
| 1925 | TRACEME(("store_ref (0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 1926 |
|
|---|
| 1927 | /*
|
|---|
| 1928 | * Follow reference, and check if target is overloaded.
|
|---|
| 1929 | */
|
|---|
| 1930 |
|
|---|
| 1931 | #ifdef SvWEAKREF
|
|---|
| 1932 | if (SvWEAKREF(sv))
|
|---|
| 1933 | is_weak = 1;
|
|---|
| 1934 | TRACEME(("ref (0x%"UVxf") is%s weak", PTR2UV(sv), is_weak ? "" : "n't"));
|
|---|
| 1935 | #endif
|
|---|
| 1936 | sv = SvRV(sv);
|
|---|
| 1937 |
|
|---|
| 1938 | if (SvOBJECT(sv)) {
|
|---|
| 1939 | HV *stash = (HV *) SvSTASH(sv);
|
|---|
| 1940 | if (stash && Gv_AMG(stash)) {
|
|---|
| 1941 | TRACEME(("ref (0x%"UVxf") is overloaded", PTR2UV(sv)));
|
|---|
| 1942 | PUTMARK(is_weak ? SX_WEAKOVERLOAD : SX_OVERLOAD);
|
|---|
| 1943 | } else
|
|---|
| 1944 | PUTMARK(is_weak ? SX_WEAKREF : SX_REF);
|
|---|
| 1945 | } else
|
|---|
| 1946 | PUTMARK(is_weak ? SX_WEAKREF : SX_REF);
|
|---|
| 1947 |
|
|---|
| 1948 | return store(aTHX_ cxt, sv);
|
|---|
| 1949 | }
|
|---|
| 1950 |
|
|---|
| 1951 | /*
|
|---|
| 1952 | * store_scalar
|
|---|
| 1953 | *
|
|---|
| 1954 | * Store a scalar.
|
|---|
| 1955 | *
|
|---|
| 1956 | * Layout is SX_LSCALAR <length> <data>, SX_SCALAR <length> <data> or SX_UNDEF.
|
|---|
| 1957 | * The <data> section is omitted if <length> is 0.
|
|---|
| 1958 | *
|
|---|
| 1959 | * If integer or double, the layout is SX_INTEGER <data> or SX_DOUBLE <data>.
|
|---|
| 1960 | * Small integers (within [-127, +127]) are stored as SX_BYTE <byte>.
|
|---|
| 1961 | */
|
|---|
| 1962 | static int store_scalar(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 1963 | {
|
|---|
| 1964 | IV iv;
|
|---|
| 1965 | char *pv;
|
|---|
| 1966 | STRLEN len;
|
|---|
| 1967 | U32 flags = SvFLAGS(sv); /* "cc -O" may put it in register */
|
|---|
| 1968 |
|
|---|
| 1969 | TRACEME(("store_scalar (0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 1970 |
|
|---|
| 1971 | /*
|
|---|
| 1972 | * For efficiency, break the SV encapsulation by peaking at the flags
|
|---|
| 1973 | * directly without using the Perl macros to avoid dereferencing
|
|---|
| 1974 | * sv->sv_flags each time we wish to check the flags.
|
|---|
| 1975 | */
|
|---|
| 1976 |
|
|---|
| 1977 | if (!(flags & SVf_OK)) { /* !SvOK(sv) */
|
|---|
| 1978 | if (sv == &PL_sv_undef) {
|
|---|
| 1979 | TRACEME(("immortal undef"));
|
|---|
| 1980 | PUTMARK(SX_SV_UNDEF);
|
|---|
| 1981 | } else {
|
|---|
| 1982 | TRACEME(("undef at 0x%"UVxf, PTR2UV(sv)));
|
|---|
| 1983 | PUTMARK(SX_UNDEF);
|
|---|
| 1984 | }
|
|---|
| 1985 | return 0;
|
|---|
| 1986 | }
|
|---|
| 1987 |
|
|---|
| 1988 | /*
|
|---|
| 1989 | * Always store the string representation of a scalar if it exists.
|
|---|
| 1990 | * Gisle Aas provided me with this test case, better than a long speach:
|
|---|
| 1991 | *
|
|---|
| 1992 | * perl -MDevel::Peek -le '$a="abc"; $a+0; Dump($a)'
|
|---|
| 1993 | * SV = PVNV(0x80c8520)
|
|---|
| 1994 | * REFCNT = 1
|
|---|
| 1995 | * FLAGS = (NOK,POK,pNOK,pPOK)
|
|---|
| 1996 | * IV = 0
|
|---|
| 1997 | * NV = 0
|
|---|
| 1998 | * PV = 0x80c83d0 "abc"\0
|
|---|
| 1999 | * CUR = 3
|
|---|
| 2000 | * LEN = 4
|
|---|
| 2001 | *
|
|---|
| 2002 | * Write SX_SCALAR, length, followed by the actual data.
|
|---|
| 2003 | *
|
|---|
| 2004 | * Otherwise, write an SX_BYTE, SX_INTEGER or an SX_DOUBLE as
|
|---|
| 2005 | * appropriate, followed by the actual (binary) data. A double
|
|---|
| 2006 | * is written as a string if network order, for portability.
|
|---|
| 2007 | *
|
|---|
| 2008 | * NOTE: instead of using SvNOK(sv), we test for SvNOKp(sv).
|
|---|
| 2009 | * The reason is that when the scalar value is tainted, the SvNOK(sv)
|
|---|
| 2010 | * value is false.
|
|---|
| 2011 | *
|
|---|
| 2012 | * The test for a read-only scalar with both POK and NOK set is meant
|
|---|
| 2013 | * to quickly detect &PL_sv_yes and &PL_sv_no without having to pay the
|
|---|
| 2014 | * address comparison for each scalar we store.
|
|---|
| 2015 | */
|
|---|
| 2016 |
|
|---|
| 2017 | #define SV_MAYBE_IMMORTAL (SVf_READONLY|SVf_POK|SVf_NOK)
|
|---|
| 2018 |
|
|---|
| 2019 | if ((flags & SV_MAYBE_IMMORTAL) == SV_MAYBE_IMMORTAL) {
|
|---|
| 2020 | if (sv == &PL_sv_yes) {
|
|---|
| 2021 | TRACEME(("immortal yes"));
|
|---|
| 2022 | PUTMARK(SX_SV_YES);
|
|---|
| 2023 | } else if (sv == &PL_sv_no) {
|
|---|
| 2024 | TRACEME(("immortal no"));
|
|---|
| 2025 | PUTMARK(SX_SV_NO);
|
|---|
| 2026 | } else {
|
|---|
| 2027 | pv = SvPV(sv, len); /* We know it's SvPOK */
|
|---|
| 2028 | goto string; /* Share code below */
|
|---|
| 2029 | }
|
|---|
| 2030 | } else if (flags & SVf_POK) {
|
|---|
| 2031 | /* public string - go direct to string read. */
|
|---|
| 2032 | goto string_readlen;
|
|---|
| 2033 | } else if (
|
|---|
| 2034 | #if (PATCHLEVEL <= 6)
|
|---|
| 2035 | /* For 5.6 and earlier NV flag trumps IV flag, so only use integer
|
|---|
| 2036 | direct if NV flag is off. */
|
|---|
| 2037 | (flags & (SVf_NOK | SVf_IOK)) == SVf_IOK
|
|---|
| 2038 | #else
|
|---|
| 2039 | /* 5.7 rules are that if IV public flag is set, IV value is as
|
|---|
| 2040 | good, if not better, than NV value. */
|
|---|
| 2041 | flags & SVf_IOK
|
|---|
| 2042 | #endif
|
|---|
| 2043 | ) {
|
|---|
| 2044 | iv = SvIV(sv);
|
|---|
| 2045 | /*
|
|---|
| 2046 | * Will come here from below with iv set if double is an integer.
|
|---|
| 2047 | */
|
|---|
| 2048 | integer:
|
|---|
| 2049 |
|
|---|
| 2050 | /* Sorry. This isn't in 5.005_56 (IIRC) or earlier. */
|
|---|
| 2051 | #ifdef SVf_IVisUV
|
|---|
| 2052 | /* Need to do this out here, else 0xFFFFFFFF becomes iv of -1
|
|---|
| 2053 | * (for example) and that ends up in the optimised small integer
|
|---|
| 2054 | * case.
|
|---|
| 2055 | */
|
|---|
| 2056 | if ((flags & SVf_IVisUV) && SvUV(sv) > IV_MAX) {
|
|---|
| 2057 | TRACEME(("large unsigned integer as string, value = %"UVuf, SvUV(sv)));
|
|---|
| 2058 | goto string_readlen;
|
|---|
| 2059 | }
|
|---|
| 2060 | #endif
|
|---|
| 2061 | /*
|
|---|
| 2062 | * Optimize small integers into a single byte, otherwise store as
|
|---|
| 2063 | * a real integer (converted into network order if they asked).
|
|---|
| 2064 | */
|
|---|
| 2065 |
|
|---|
| 2066 | if (iv >= -128 && iv <= 127) {
|
|---|
| 2067 | unsigned char siv = (unsigned char) (iv + 128); /* [0,255] */
|
|---|
| 2068 | PUTMARK(SX_BYTE);
|
|---|
| 2069 | PUTMARK(siv);
|
|---|
| 2070 | TRACEME(("small integer stored as %d", siv));
|
|---|
| 2071 | } else if (cxt->netorder) {
|
|---|
| 2072 | #ifndef HAS_HTONL
|
|---|
| 2073 | TRACEME(("no htonl, fall back to string for integer"));
|
|---|
| 2074 | goto string_readlen;
|
|---|
| 2075 | #else
|
|---|
| 2076 | I32 niv;
|
|---|
| 2077 |
|
|---|
| 2078 |
|
|---|
| 2079 | #if IVSIZE > 4
|
|---|
| 2080 | if (
|
|---|
| 2081 | #ifdef SVf_IVisUV
|
|---|
| 2082 | /* Sorry. This isn't in 5.005_56 (IIRC) or earlier. */
|
|---|
| 2083 | ((flags & SVf_IVisUV) && SvUV(sv) > 0x7FFFFFFF) ||
|
|---|
| 2084 | #endif
|
|---|
| 2085 | (iv > 0x7FFFFFFF) || (iv < -0x80000000)) {
|
|---|
| 2086 | /* Bigger than 32 bits. */
|
|---|
| 2087 | TRACEME(("large network order integer as string, value = %"IVdf, iv));
|
|---|
| 2088 | goto string_readlen;
|
|---|
| 2089 | }
|
|---|
| 2090 | #endif
|
|---|
| 2091 |
|
|---|
| 2092 | niv = (I32) htonl((I32) iv);
|
|---|
| 2093 | TRACEME(("using network order"));
|
|---|
| 2094 | PUTMARK(SX_NETINT);
|
|---|
| 2095 | WRITE_I32(niv);
|
|---|
| 2096 | #endif
|
|---|
| 2097 | } else {
|
|---|
| 2098 | PUTMARK(SX_INTEGER);
|
|---|
| 2099 | WRITE(&iv, sizeof(iv));
|
|---|
| 2100 | }
|
|---|
| 2101 |
|
|---|
| 2102 | TRACEME(("ok (integer 0x%"UVxf", value = %"IVdf")", PTR2UV(sv), iv));
|
|---|
| 2103 | } else if (flags & SVf_NOK) {
|
|---|
| 2104 | NV nv;
|
|---|
| 2105 | #if (PATCHLEVEL <= 6)
|
|---|
| 2106 | nv = SvNV(sv);
|
|---|
| 2107 | /*
|
|---|
| 2108 | * Watch for number being an integer in disguise.
|
|---|
| 2109 | */
|
|---|
| 2110 | if (nv == (NV) (iv = I_V(nv))) {
|
|---|
| 2111 | TRACEME(("double %"NVff" is actually integer %"IVdf, nv, iv));
|
|---|
| 2112 | goto integer; /* Share code above */
|
|---|
| 2113 | }
|
|---|
| 2114 | #else
|
|---|
| 2115 |
|
|---|
| 2116 | SvIV_please(sv);
|
|---|
| 2117 | if (SvIOK_notUV(sv)) {
|
|---|
| 2118 | iv = SvIV(sv);
|
|---|
| 2119 | goto integer; /* Share code above */
|
|---|
| 2120 | }
|
|---|
| 2121 | nv = SvNV(sv);
|
|---|
| 2122 | #endif
|
|---|
| 2123 |
|
|---|
| 2124 | if (cxt->netorder) {
|
|---|
| 2125 | TRACEME(("double %"NVff" stored as string", nv));
|
|---|
| 2126 | goto string_readlen; /* Share code below */
|
|---|
| 2127 | }
|
|---|
| 2128 |
|
|---|
| 2129 | PUTMARK(SX_DOUBLE);
|
|---|
| 2130 | WRITE(&nv, sizeof(nv));
|
|---|
| 2131 |
|
|---|
| 2132 | TRACEME(("ok (double 0x%"UVxf", value = %"NVff")", PTR2UV(sv), nv));
|
|---|
| 2133 |
|
|---|
| 2134 | } else if (flags & (SVp_POK | SVp_NOK | SVp_IOK)) {
|
|---|
| 2135 | I32 wlen; /* For 64-bit machines */
|
|---|
| 2136 |
|
|---|
| 2137 | string_readlen:
|
|---|
| 2138 | pv = SvPV(sv, len);
|
|---|
| 2139 |
|
|---|
| 2140 | /*
|
|---|
| 2141 | * Will come here from above if it was readonly, POK and NOK but
|
|---|
| 2142 | * neither &PL_sv_yes nor &PL_sv_no.
|
|---|
| 2143 | */
|
|---|
| 2144 | string:
|
|---|
| 2145 |
|
|---|
| 2146 | wlen = (I32) len; /* WLEN via STORE_SCALAR expects I32 */
|
|---|
| 2147 | if (SvUTF8 (sv))
|
|---|
| 2148 | STORE_UTF8STR(pv, wlen);
|
|---|
| 2149 | else
|
|---|
| 2150 | STORE_SCALAR(pv, wlen);
|
|---|
| 2151 | TRACEME(("ok (scalar 0x%"UVxf" '%s', length = %"IVdf")",
|
|---|
| 2152 | PTR2UV(sv), SvPVX(sv), (IV)len));
|
|---|
| 2153 | } else
|
|---|
| 2154 | CROAK(("Can't determine type of %s(0x%"UVxf")",
|
|---|
| 2155 | sv_reftype(sv, FALSE),
|
|---|
| 2156 | PTR2UV(sv)));
|
|---|
| 2157 | return 0; /* Ok, no recursion on scalars */
|
|---|
| 2158 | }
|
|---|
| 2159 |
|
|---|
| 2160 | /*
|
|---|
| 2161 | * store_array
|
|---|
| 2162 | *
|
|---|
| 2163 | * Store an array.
|
|---|
| 2164 | *
|
|---|
| 2165 | * Layout is SX_ARRAY <size> followed by each item, in increading index order.
|
|---|
| 2166 | * Each item is stored as <object>.
|
|---|
| 2167 | */
|
|---|
| 2168 | static int store_array(pTHX_ stcxt_t *cxt, AV *av)
|
|---|
| 2169 | {
|
|---|
| 2170 | SV **sav;
|
|---|
| 2171 | I32 len = av_len(av) + 1;
|
|---|
| 2172 | I32 i;
|
|---|
| 2173 | int ret;
|
|---|
| 2174 |
|
|---|
| 2175 | TRACEME(("store_array (0x%"UVxf")", PTR2UV(av)));
|
|---|
| 2176 |
|
|---|
| 2177 | /*
|
|---|
| 2178 | * Signal array by emitting SX_ARRAY, followed by the array length.
|
|---|
| 2179 | */
|
|---|
| 2180 |
|
|---|
| 2181 | PUTMARK(SX_ARRAY);
|
|---|
| 2182 | WLEN(len);
|
|---|
| 2183 | TRACEME(("size = %d", len));
|
|---|
| 2184 |
|
|---|
| 2185 | /*
|
|---|
| 2186 | * Now store each item recursively.
|
|---|
| 2187 | */
|
|---|
| 2188 |
|
|---|
| 2189 | for (i = 0; i < len; i++) {
|
|---|
| 2190 | sav = av_fetch(av, i, 0);
|
|---|
| 2191 | if (!sav) {
|
|---|
| 2192 | TRACEME(("(#%d) undef item", i));
|
|---|
| 2193 | STORE_SV_UNDEF();
|
|---|
| 2194 | continue;
|
|---|
| 2195 | }
|
|---|
| 2196 | TRACEME(("(#%d) item", i));
|
|---|
| 2197 | if ((ret = store(aTHX_ cxt, *sav))) /* Extra () for -Wall, grr... */
|
|---|
| 2198 | return ret;
|
|---|
| 2199 | }
|
|---|
| 2200 |
|
|---|
| 2201 | TRACEME(("ok (array)"));
|
|---|
| 2202 |
|
|---|
| 2203 | return 0;
|
|---|
| 2204 | }
|
|---|
| 2205 |
|
|---|
| 2206 |
|
|---|
| 2207 | #if (PATCHLEVEL <= 6)
|
|---|
| 2208 |
|
|---|
| 2209 | /*
|
|---|
| 2210 | * sortcmp
|
|---|
| 2211 | *
|
|---|
| 2212 | * Sort two SVs
|
|---|
| 2213 | * Borrowed from perl source file pp_ctl.c, where it is used by pp_sort.
|
|---|
| 2214 | */
|
|---|
| 2215 | static int
|
|---|
| 2216 | sortcmp(const void *a, const void *b)
|
|---|
| 2217 | {
|
|---|
| 2218 | #if defined(USE_ITHREADS)
|
|---|
| 2219 | dTHX;
|
|---|
| 2220 | #endif /* USE_ITHREADS */
|
|---|
| 2221 | return sv_cmp(*(SV * const *) a, *(SV * const *) b);
|
|---|
| 2222 | }
|
|---|
| 2223 |
|
|---|
| 2224 | #endif /* PATCHLEVEL <= 6 */
|
|---|
| 2225 |
|
|---|
| 2226 | /*
|
|---|
| 2227 | * store_hash
|
|---|
| 2228 | *
|
|---|
| 2229 | * Store a hash table.
|
|---|
| 2230 | *
|
|---|
| 2231 | * For a "normal" hash (not restricted, no utf8 keys):
|
|---|
| 2232 | *
|
|---|
| 2233 | * Layout is SX_HASH <size> followed by each key/value pair, in random order.
|
|---|
| 2234 | * Values are stored as <object>.
|
|---|
| 2235 | * Keys are stored as <length> <data>, the <data> section being omitted
|
|---|
| 2236 | * if length is 0.
|
|---|
| 2237 | *
|
|---|
| 2238 | * For a "fancy" hash (restricted or utf8 keys):
|
|---|
| 2239 | *
|
|---|
| 2240 | * Layout is SX_FLAG_HASH <size> <hash flags> followed by each key/value pair,
|
|---|
| 2241 | * in random order.
|
|---|
| 2242 | * Values are stored as <object>.
|
|---|
| 2243 | * Keys are stored as <flags> <length> <data>, the <data> section being omitted
|
|---|
| 2244 | * if length is 0.
|
|---|
| 2245 | * Currently the only hash flag is "restriced"
|
|---|
| 2246 | * Key flags are as for hv.h
|
|---|
| 2247 | */
|
|---|
| 2248 | static int store_hash(pTHX_ stcxt_t *cxt, HV *hv)
|
|---|
| 2249 | {
|
|---|
| 2250 | dVAR;
|
|---|
| 2251 | I32 len =
|
|---|
| 2252 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 2253 | HvTOTALKEYS(hv);
|
|---|
| 2254 | #else
|
|---|
| 2255 | HvKEYS(hv);
|
|---|
| 2256 | #endif
|
|---|
| 2257 | I32 i;
|
|---|
| 2258 | int ret = 0;
|
|---|
| 2259 | I32 riter;
|
|---|
| 2260 | HE *eiter;
|
|---|
| 2261 | int flagged_hash = ((SvREADONLY(hv)
|
|---|
| 2262 | #ifdef HAS_HASH_KEY_FLAGS
|
|---|
| 2263 | || HvHASKFLAGS(hv)
|
|---|
| 2264 | #endif
|
|---|
| 2265 | ) ? 1 : 0);
|
|---|
| 2266 | unsigned char hash_flags = (SvREADONLY(hv) ? SHV_RESTRICTED : 0);
|
|---|
| 2267 |
|
|---|
| 2268 | if (flagged_hash) {
|
|---|
| 2269 | /* needs int cast for C++ compilers, doesn't it? */
|
|---|
| 2270 | TRACEME(("store_hash (0x%"UVxf") (flags %x)", PTR2UV(hv),
|
|---|
| 2271 | (int) hash_flags));
|
|---|
| 2272 | } else {
|
|---|
| 2273 | TRACEME(("store_hash (0x%"UVxf")", PTR2UV(hv)));
|
|---|
| 2274 | }
|
|---|
| 2275 |
|
|---|
| 2276 | /*
|
|---|
| 2277 | * Signal hash by emitting SX_HASH, followed by the table length.
|
|---|
| 2278 | */
|
|---|
| 2279 |
|
|---|
| 2280 | if (flagged_hash) {
|
|---|
| 2281 | PUTMARK(SX_FLAG_HASH);
|
|---|
| 2282 | PUTMARK(hash_flags);
|
|---|
| 2283 | } else {
|
|---|
| 2284 | PUTMARK(SX_HASH);
|
|---|
| 2285 | }
|
|---|
| 2286 | WLEN(len);
|
|---|
| 2287 | TRACEME(("size = %d", len));
|
|---|
| 2288 |
|
|---|
| 2289 | /*
|
|---|
| 2290 | * Save possible iteration state via each() on that table.
|
|---|
| 2291 | */
|
|---|
| 2292 |
|
|---|
| 2293 | riter = HvRITER_get(hv);
|
|---|
| 2294 | eiter = HvEITER_get(hv);
|
|---|
| 2295 | hv_iterinit(hv);
|
|---|
| 2296 |
|
|---|
| 2297 | /*
|
|---|
| 2298 | * Now store each item recursively.
|
|---|
| 2299 | *
|
|---|
| 2300 | * If canonical is defined to some true value then store each
|
|---|
| 2301 | * key/value pair in sorted order otherwise the order is random.
|
|---|
| 2302 | * Canonical order is irrelevant when a deep clone operation is performed.
|
|---|
| 2303 | *
|
|---|
| 2304 | * Fetch the value from perl only once per store() operation, and only
|
|---|
| 2305 | * when needed.
|
|---|
| 2306 | */
|
|---|
| 2307 |
|
|---|
| 2308 | if (
|
|---|
| 2309 | !(cxt->optype & ST_CLONE) && (cxt->canonical == 1 ||
|
|---|
| 2310 | (cxt->canonical < 0 && (cxt->canonical =
|
|---|
| 2311 | (SvTRUE(perl_get_sv("Storable::canonical", TRUE)) ? 1 : 0))))
|
|---|
| 2312 | ) {
|
|---|
| 2313 | /*
|
|---|
| 2314 | * Storing in order, sorted by key.
|
|---|
| 2315 | * Run through the hash, building up an array of keys in a
|
|---|
| 2316 | * mortal array, sort the array and then run through the
|
|---|
| 2317 | * array.
|
|---|
| 2318 | */
|
|---|
| 2319 |
|
|---|
| 2320 | AV *av = newAV();
|
|---|
| 2321 |
|
|---|
| 2322 | /*av_extend (av, len);*/
|
|---|
| 2323 |
|
|---|
| 2324 | TRACEME(("using canonical order"));
|
|---|
| 2325 |
|
|---|
| 2326 | for (i = 0; i < len; i++) {
|
|---|
| 2327 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 2328 | HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
|
|---|
| 2329 | #else
|
|---|
| 2330 | HE *he = hv_iternext(hv);
|
|---|
| 2331 | #endif
|
|---|
| 2332 | SV *key = hv_iterkeysv(he);
|
|---|
| 2333 | av_store(av, AvFILLp(av)+1, key); /* av_push(), really */
|
|---|
| 2334 | }
|
|---|
| 2335 |
|
|---|
| 2336 | STORE_HASH_SORT;
|
|---|
| 2337 |
|
|---|
| 2338 | for (i = 0; i < len; i++) {
|
|---|
| 2339 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 2340 | int placeholders = (int)HvPLACEHOLDERS_get(hv);
|
|---|
| 2341 | #endif
|
|---|
| 2342 | unsigned char flags = 0;
|
|---|
| 2343 | char *keyval;
|
|---|
| 2344 | STRLEN keylen_tmp;
|
|---|
| 2345 | I32 keylen;
|
|---|
| 2346 | SV *key = av_shift(av);
|
|---|
| 2347 | /* This will fail if key is a placeholder.
|
|---|
| 2348 | Track how many placeholders we have, and error if we
|
|---|
| 2349 | "see" too many. */
|
|---|
| 2350 | HE *he = hv_fetch_ent(hv, key, 0, 0);
|
|---|
| 2351 | SV *val;
|
|---|
| 2352 |
|
|---|
| 2353 | if (he) {
|
|---|
| 2354 | if (!(val = HeVAL(he))) {
|
|---|
| 2355 | /* Internal error, not I/O error */
|
|---|
| 2356 | return 1;
|
|---|
| 2357 | }
|
|---|
| 2358 | } else {
|
|---|
| 2359 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 2360 | /* Should be a placeholder. */
|
|---|
| 2361 | if (placeholders-- < 0) {
|
|---|
| 2362 | /* This should not happen - number of
|
|---|
| 2363 | retrieves should be identical to
|
|---|
| 2364 | number of placeholders. */
|
|---|
| 2365 | return 1;
|
|---|
| 2366 | }
|
|---|
| 2367 | /* Value is never needed, and PL_sv_undef is
|
|---|
| 2368 | more space efficient to store. */
|
|---|
| 2369 | val = &PL_sv_undef;
|
|---|
| 2370 | ASSERT (flags == 0,
|
|---|
| 2371 | ("Flags not 0 but %d", flags));
|
|---|
| 2372 | flags = SHV_K_PLACEHOLDER;
|
|---|
| 2373 | #else
|
|---|
| 2374 | return 1;
|
|---|
| 2375 | #endif
|
|---|
| 2376 | }
|
|---|
| 2377 |
|
|---|
| 2378 | /*
|
|---|
| 2379 | * Store value first.
|
|---|
| 2380 | */
|
|---|
| 2381 |
|
|---|
| 2382 | TRACEME(("(#%d) value 0x%"UVxf, i, PTR2UV(val)));
|
|---|
| 2383 |
|
|---|
| 2384 | if ((ret = store(aTHX_ cxt, val))) /* Extra () for -Wall, grr... */
|
|---|
| 2385 | goto out;
|
|---|
| 2386 |
|
|---|
| 2387 | /*
|
|---|
| 2388 | * Write key string.
|
|---|
| 2389 | * Keys are written after values to make sure retrieval
|
|---|
| 2390 | * can be optimal in terms of memory usage, where keys are
|
|---|
| 2391 | * read into a fixed unique buffer called kbuf.
|
|---|
| 2392 | * See retrieve_hash() for details.
|
|---|
| 2393 | */
|
|---|
| 2394 |
|
|---|
| 2395 | /* Implementation of restricted hashes isn't nicely
|
|---|
| 2396 | abstracted: */
|
|---|
| 2397 | if ((hash_flags & SHV_RESTRICTED) && SvREADONLY(val)) {
|
|---|
| 2398 | flags |= SHV_K_LOCKED;
|
|---|
| 2399 | }
|
|---|
| 2400 |
|
|---|
| 2401 | keyval = SvPV(key, keylen_tmp);
|
|---|
| 2402 | keylen = keylen_tmp;
|
|---|
| 2403 | #ifdef HAS_UTF8_HASHES
|
|---|
| 2404 | /* If you build without optimisation on pre 5.6
|
|---|
| 2405 | then nothing spots that SvUTF8(key) is always 0,
|
|---|
| 2406 | so the block isn't optimised away, at which point
|
|---|
| 2407 | the linker dislikes the reference to
|
|---|
| 2408 | bytes_from_utf8. */
|
|---|
| 2409 | if (SvUTF8(key)) {
|
|---|
| 2410 | const char *keysave = keyval;
|
|---|
| 2411 | bool is_utf8 = TRUE;
|
|---|
| 2412 |
|
|---|
| 2413 | /* Just casting the &klen to (STRLEN) won't work
|
|---|
| 2414 | well if STRLEN and I32 are of different widths.
|
|---|
| 2415 | --jhi */
|
|---|
| 2416 | keyval = (char*)bytes_from_utf8((U8*)keyval,
|
|---|
| 2417 | &keylen_tmp,
|
|---|
| 2418 | &is_utf8);
|
|---|
| 2419 |
|
|---|
| 2420 | /* If we were able to downgrade here, then than
|
|---|
| 2421 | means that we have a key which only had chars
|
|---|
| 2422 | 0-255, but was utf8 encoded. */
|
|---|
| 2423 |
|
|---|
| 2424 | if (keyval != keysave) {
|
|---|
| 2425 | keylen = keylen_tmp;
|
|---|
| 2426 | flags |= SHV_K_WASUTF8;
|
|---|
| 2427 | } else {
|
|---|
| 2428 | /* keylen_tmp can't have changed, so no need
|
|---|
| 2429 | to assign back to keylen. */
|
|---|
| 2430 | flags |= SHV_K_UTF8;
|
|---|
| 2431 | }
|
|---|
| 2432 | }
|
|---|
| 2433 | #endif
|
|---|
| 2434 |
|
|---|
| 2435 | if (flagged_hash) {
|
|---|
| 2436 | PUTMARK(flags);
|
|---|
| 2437 | TRACEME(("(#%d) key '%s' flags %x %u", i, keyval, flags, *keyval));
|
|---|
| 2438 | } else {
|
|---|
| 2439 | /* This is a workaround for a bug in 5.8.0
|
|---|
| 2440 | that causes the HEK_WASUTF8 flag to be
|
|---|
| 2441 | set on an HEK without the hash being
|
|---|
| 2442 | marked as having key flags. We just
|
|---|
| 2443 | cross our fingers and drop the flag.
|
|---|
| 2444 | AMS 20030901 */
|
|---|
| 2445 | assert (flags == 0 || flags == SHV_K_WASUTF8);
|
|---|
| 2446 | TRACEME(("(#%d) key '%s'", i, keyval));
|
|---|
| 2447 | }
|
|---|
| 2448 | WLEN(keylen);
|
|---|
| 2449 | if (keylen)
|
|---|
| 2450 | WRITE(keyval, keylen);
|
|---|
| 2451 | if (flags & SHV_K_WASUTF8)
|
|---|
| 2452 | Safefree (keyval);
|
|---|
| 2453 | }
|
|---|
| 2454 |
|
|---|
| 2455 | /*
|
|---|
| 2456 | * Free up the temporary array
|
|---|
| 2457 | */
|
|---|
| 2458 |
|
|---|
| 2459 | av_undef(av);
|
|---|
| 2460 | sv_free((SV *) av);
|
|---|
| 2461 |
|
|---|
| 2462 | } else {
|
|---|
| 2463 |
|
|---|
| 2464 | /*
|
|---|
| 2465 | * Storing in "random" order (in the order the keys are stored
|
|---|
| 2466 | * within the hash). This is the default and will be faster!
|
|---|
| 2467 | */
|
|---|
| 2468 |
|
|---|
| 2469 | for (i = 0; i < len; i++) {
|
|---|
| 2470 | char *key = 0;
|
|---|
| 2471 | I32 len;
|
|---|
| 2472 | unsigned char flags;
|
|---|
| 2473 | #ifdef HV_ITERNEXT_WANTPLACEHOLDERS
|
|---|
| 2474 | HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS);
|
|---|
| 2475 | #else
|
|---|
| 2476 | HE *he = hv_iternext(hv);
|
|---|
| 2477 | #endif
|
|---|
| 2478 | SV *val = (he ? hv_iterval(hv, he) : 0);
|
|---|
| 2479 | SV *key_sv = NULL;
|
|---|
| 2480 | HEK *hek;
|
|---|
| 2481 |
|
|---|
| 2482 | if (val == 0)
|
|---|
| 2483 | return 1; /* Internal error, not I/O error */
|
|---|
| 2484 |
|
|---|
| 2485 | /* Implementation of restricted hashes isn't nicely
|
|---|
| 2486 | abstracted: */
|
|---|
| 2487 | flags
|
|---|
| 2488 | = (((hash_flags & SHV_RESTRICTED)
|
|---|
| 2489 | && SvREADONLY(val))
|
|---|
| 2490 | ? SHV_K_LOCKED : 0);
|
|---|
| 2491 |
|
|---|
| 2492 | if (val == &PL_sv_placeholder) {
|
|---|
| 2493 | flags |= SHV_K_PLACEHOLDER;
|
|---|
| 2494 | val = &PL_sv_undef;
|
|---|
| 2495 | }
|
|---|
| 2496 |
|
|---|
| 2497 | /*
|
|---|
| 2498 | * Store value first.
|
|---|
| 2499 | */
|
|---|
| 2500 |
|
|---|
| 2501 | TRACEME(("(#%d) value 0x%"UVxf, i, PTR2UV(val)));
|
|---|
| 2502 |
|
|---|
| 2503 | if ((ret = store(aTHX_ cxt, val))) /* Extra () for -Wall, grr... */
|
|---|
| 2504 | goto out;
|
|---|
| 2505 |
|
|---|
| 2506 |
|
|---|
| 2507 | hek = HeKEY_hek(he);
|
|---|
| 2508 | len = HEK_LEN(hek);
|
|---|
| 2509 | if (len == HEf_SVKEY) {
|
|---|
| 2510 | /* This is somewhat sick, but the internal APIs are
|
|---|
| 2511 | * such that XS code could put one of these in in
|
|---|
| 2512 | * a regular hash.
|
|---|
| 2513 | * Maybe we should be capable of storing one if
|
|---|
| 2514 | * found.
|
|---|
| 2515 | */
|
|---|
| 2516 | key_sv = HeKEY_sv(he);
|
|---|
| 2517 | flags |= SHV_K_ISSV;
|
|---|
| 2518 | } else {
|
|---|
| 2519 | /* Regular string key. */
|
|---|
| 2520 | #ifdef HAS_HASH_KEY_FLAGS
|
|---|
| 2521 | if (HEK_UTF8(hek))
|
|---|
| 2522 | flags |= SHV_K_UTF8;
|
|---|
| 2523 | if (HEK_WASUTF8(hek))
|
|---|
| 2524 | flags |= SHV_K_WASUTF8;
|
|---|
| 2525 | #endif
|
|---|
| 2526 | key = HEK_KEY(hek);
|
|---|
| 2527 | }
|
|---|
| 2528 | /*
|
|---|
| 2529 | * Write key string.
|
|---|
| 2530 | * Keys are written after values to make sure retrieval
|
|---|
| 2531 | * can be optimal in terms of memory usage, where keys are
|
|---|
| 2532 | * read into a fixed unique buffer called kbuf.
|
|---|
| 2533 | * See retrieve_hash() for details.
|
|---|
| 2534 | */
|
|---|
| 2535 |
|
|---|
| 2536 | if (flagged_hash) {
|
|---|
| 2537 | PUTMARK(flags);
|
|---|
| 2538 | TRACEME(("(#%d) key '%s' flags %x", i, key, flags));
|
|---|
| 2539 | } else {
|
|---|
| 2540 | /* This is a workaround for a bug in 5.8.0
|
|---|
| 2541 | that causes the HEK_WASUTF8 flag to be
|
|---|
| 2542 | set on an HEK without the hash being
|
|---|
| 2543 | marked as having key flags. We just
|
|---|
| 2544 | cross our fingers and drop the flag.
|
|---|
| 2545 | AMS 20030901 */
|
|---|
| 2546 | assert (flags == 0 || flags == SHV_K_WASUTF8);
|
|---|
| 2547 | TRACEME(("(#%d) key '%s'", i, key));
|
|---|
| 2548 | }
|
|---|
| 2549 | if (flags & SHV_K_ISSV) {
|
|---|
| 2550 | store(aTHX_ cxt, key_sv);
|
|---|
| 2551 | } else {
|
|---|
| 2552 | WLEN(len);
|
|---|
| 2553 | if (len)
|
|---|
| 2554 | WRITE(key, len);
|
|---|
| 2555 | }
|
|---|
| 2556 | }
|
|---|
| 2557 | }
|
|---|
| 2558 |
|
|---|
| 2559 | TRACEME(("ok (hash 0x%"UVxf")", PTR2UV(hv)));
|
|---|
| 2560 |
|
|---|
| 2561 | out:
|
|---|
| 2562 | HvRITER_set(hv, riter); /* Restore hash iterator state */
|
|---|
| 2563 | HvEITER_set(hv, eiter);
|
|---|
| 2564 |
|
|---|
| 2565 | return ret;
|
|---|
| 2566 | }
|
|---|
| 2567 |
|
|---|
| 2568 | /*
|
|---|
| 2569 | * store_code
|
|---|
| 2570 | *
|
|---|
| 2571 | * Store a code reference.
|
|---|
| 2572 | *
|
|---|
| 2573 | * Layout is SX_CODE <length> followed by a scalar containing the perl
|
|---|
| 2574 | * source code of the code reference.
|
|---|
| 2575 | */
|
|---|
| 2576 | static int store_code(pTHX_ stcxt_t *cxt, CV *cv)
|
|---|
| 2577 | {
|
|---|
| 2578 | #if PERL_VERSION < 6
|
|---|
| 2579 | /*
|
|---|
| 2580 | * retrieve_code does not work with perl 5.005 or less
|
|---|
| 2581 | */
|
|---|
| 2582 | return store_other(aTHX_ cxt, (SV*)cv);
|
|---|
| 2583 | #else
|
|---|
| 2584 | dSP;
|
|---|
| 2585 | I32 len;
|
|---|
| 2586 | int count, reallen;
|
|---|
| 2587 | SV *text, *bdeparse;
|
|---|
| 2588 |
|
|---|
| 2589 | TRACEME(("store_code (0x%"UVxf")", PTR2UV(cv)));
|
|---|
| 2590 |
|
|---|
| 2591 | if (
|
|---|
| 2592 | cxt->deparse == 0 ||
|
|---|
| 2593 | (cxt->deparse < 0 && !(cxt->deparse =
|
|---|
| 2594 | SvTRUE(perl_get_sv("Storable::Deparse", TRUE)) ? 1 : 0))
|
|---|
| 2595 | ) {
|
|---|
| 2596 | return store_other(aTHX_ cxt, (SV*)cv);
|
|---|
| 2597 | }
|
|---|
| 2598 |
|
|---|
| 2599 | /*
|
|---|
| 2600 | * Require B::Deparse. At least B::Deparse 0.61 is needed for
|
|---|
| 2601 | * blessed code references.
|
|---|
| 2602 | */
|
|---|
| 2603 | /* Ownership of both SVs is passed to load_module, which frees them. */
|
|---|
| 2604 | load_module(PERL_LOADMOD_NOIMPORT, newSVpvn("B::Deparse",10), newSVnv(0.61));
|
|---|
| 2605 |
|
|---|
| 2606 | ENTER;
|
|---|
| 2607 | SAVETMPS;
|
|---|
| 2608 |
|
|---|
| 2609 | /*
|
|---|
| 2610 | * create the B::Deparse object
|
|---|
| 2611 | */
|
|---|
| 2612 |
|
|---|
| 2613 | PUSHMARK(sp);
|
|---|
| 2614 | XPUSHs(sv_2mortal(newSVpvn("B::Deparse",10)));
|
|---|
| 2615 | PUTBACK;
|
|---|
| 2616 | count = call_method("new", G_SCALAR);
|
|---|
| 2617 | SPAGAIN;
|
|---|
| 2618 | if (count != 1)
|
|---|
| 2619 | CROAK(("Unexpected return value from B::Deparse::new\n"));
|
|---|
| 2620 | bdeparse = POPs;
|
|---|
| 2621 |
|
|---|
| 2622 | /*
|
|---|
| 2623 | * call the coderef2text method
|
|---|
| 2624 | */
|
|---|
| 2625 |
|
|---|
| 2626 | PUSHMARK(sp);
|
|---|
| 2627 | XPUSHs(bdeparse); /* XXX is this already mortal? */
|
|---|
| 2628 | XPUSHs(sv_2mortal(newRV_inc((SV*)cv)));
|
|---|
| 2629 | PUTBACK;
|
|---|
| 2630 | count = call_method("coderef2text", G_SCALAR);
|
|---|
| 2631 | SPAGAIN;
|
|---|
| 2632 | if (count != 1)
|
|---|
| 2633 | CROAK(("Unexpected return value from B::Deparse::coderef2text\n"));
|
|---|
| 2634 |
|
|---|
| 2635 | text = POPs;
|
|---|
| 2636 | len = SvLEN(text);
|
|---|
| 2637 | reallen = strlen(SvPV_nolen(text));
|
|---|
| 2638 |
|
|---|
| 2639 | /*
|
|---|
| 2640 | * Empty code references or XS functions are deparsed as
|
|---|
| 2641 | * "(prototype) ;" or ";".
|
|---|
| 2642 | */
|
|---|
| 2643 |
|
|---|
| 2644 | if (len == 0 || *(SvPV_nolen(text)+reallen-1) == ';') {
|
|---|
| 2645 | CROAK(("The result of B::Deparse::coderef2text was empty - maybe you're trying to serialize an XS function?\n"));
|
|---|
| 2646 | }
|
|---|
| 2647 |
|
|---|
| 2648 | /*
|
|---|
| 2649 | * Signal code by emitting SX_CODE.
|
|---|
| 2650 | */
|
|---|
| 2651 |
|
|---|
| 2652 | PUTMARK(SX_CODE);
|
|---|
| 2653 | cxt->tagnum++; /* necessary, as SX_CODE is a SEEN() candidate */
|
|---|
| 2654 | TRACEME(("size = %d", len));
|
|---|
| 2655 | TRACEME(("code = %s", SvPV_nolen(text)));
|
|---|
| 2656 |
|
|---|
| 2657 | /*
|
|---|
| 2658 | * Now store the source code.
|
|---|
| 2659 | */
|
|---|
| 2660 |
|
|---|
| 2661 | STORE_SCALAR(SvPV_nolen(text), len);
|
|---|
| 2662 |
|
|---|
| 2663 | FREETMPS;
|
|---|
| 2664 | LEAVE;
|
|---|
| 2665 |
|
|---|
| 2666 | TRACEME(("ok (code)"));
|
|---|
| 2667 |
|
|---|
| 2668 | return 0;
|
|---|
| 2669 | #endif
|
|---|
| 2670 | }
|
|---|
| 2671 |
|
|---|
| 2672 | /*
|
|---|
| 2673 | * store_tied
|
|---|
| 2674 | *
|
|---|
| 2675 | * When storing a tied object (be it a tied scalar, array or hash), we lay out
|
|---|
| 2676 | * a special mark, followed by the underlying tied object. For instance, when
|
|---|
| 2677 | * dealing with a tied hash, we store SX_TIED_HASH <hash object>, where
|
|---|
| 2678 | * <hash object> stands for the serialization of the tied hash.
|
|---|
| 2679 | */
|
|---|
| 2680 | static int store_tied(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 2681 | {
|
|---|
| 2682 | MAGIC *mg;
|
|---|
| 2683 | SV *obj = NULL;
|
|---|
| 2684 | int ret = 0;
|
|---|
| 2685 | int svt = SvTYPE(sv);
|
|---|
| 2686 | char mtype = 'P';
|
|---|
| 2687 |
|
|---|
| 2688 | TRACEME(("store_tied (0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 2689 |
|
|---|
| 2690 | /*
|
|---|
| 2691 | * We have a small run-time penalty here because we chose to factorise
|
|---|
| 2692 | * all tieds objects into the same routine, and not have a store_tied_hash,
|
|---|
| 2693 | * a store_tied_array, etc...
|
|---|
| 2694 | *
|
|---|
| 2695 | * Don't use a switch() statement, as most compilers don't optimize that
|
|---|
| 2696 | * well for 2/3 values. An if() else if() cascade is just fine. We put
|
|---|
| 2697 | * tied hashes first, as they are the most likely beasts.
|
|---|
| 2698 | */
|
|---|
| 2699 |
|
|---|
| 2700 | if (svt == SVt_PVHV) {
|
|---|
| 2701 | TRACEME(("tied hash"));
|
|---|
| 2702 | PUTMARK(SX_TIED_HASH); /* Introduces tied hash */
|
|---|
| 2703 | } else if (svt == SVt_PVAV) {
|
|---|
| 2704 | TRACEME(("tied array"));
|
|---|
| 2705 | PUTMARK(SX_TIED_ARRAY); /* Introduces tied array */
|
|---|
| 2706 | } else {
|
|---|
| 2707 | TRACEME(("tied scalar"));
|
|---|
| 2708 | PUTMARK(SX_TIED_SCALAR); /* Introduces tied scalar */
|
|---|
| 2709 | mtype = 'q';
|
|---|
| 2710 | }
|
|---|
| 2711 |
|
|---|
| 2712 | if (!(mg = mg_find(sv, mtype)))
|
|---|
| 2713 | CROAK(("No magic '%c' found while storing tied %s", mtype,
|
|---|
| 2714 | (svt == SVt_PVHV) ? "hash" :
|
|---|
| 2715 | (svt == SVt_PVAV) ? "array" : "scalar"));
|
|---|
| 2716 |
|
|---|
| 2717 | /*
|
|---|
| 2718 | * The mg->mg_obj found by mg_find() above actually points to the
|
|---|
| 2719 | * underlying tied Perl object implementation. For instance, if the
|
|---|
| 2720 | * original SV was that of a tied array, then mg->mg_obj is an AV.
|
|---|
| 2721 | *
|
|---|
| 2722 | * Note that we store the Perl object as-is. We don't call its FETCH
|
|---|
| 2723 | * method along the way. At retrieval time, we won't call its STORE
|
|---|
| 2724 | * method either, but the tieing magic will be re-installed. In itself,
|
|---|
| 2725 | * that ensures that the tieing semantics are preserved since futher
|
|---|
| 2726 | * accesses on the retrieved object will indeed call the magic methods...
|
|---|
| 2727 | */
|
|---|
| 2728 |
|
|---|
| 2729 | /* [#17040] mg_obj is NULL for scalar self-ties. AMS 20030416 */
|
|---|
| 2730 | obj = mg->mg_obj ? mg->mg_obj : newSV(0);
|
|---|
| 2731 | if ((ret = store(aTHX_ cxt, obj)))
|
|---|
| 2732 | return ret;
|
|---|
| 2733 |
|
|---|
| 2734 | TRACEME(("ok (tied)"));
|
|---|
| 2735 |
|
|---|
| 2736 | return 0;
|
|---|
| 2737 | }
|
|---|
| 2738 |
|
|---|
| 2739 | /*
|
|---|
| 2740 | * store_tied_item
|
|---|
| 2741 | *
|
|---|
| 2742 | * Stores a reference to an item within a tied structure:
|
|---|
| 2743 | *
|
|---|
| 2744 | * . \$h{key}, stores both the (tied %h) object and 'key'.
|
|---|
| 2745 | * . \$a[idx], stores both the (tied @a) object and 'idx'.
|
|---|
| 2746 | *
|
|---|
| 2747 | * Layout is therefore either:
|
|---|
| 2748 | * SX_TIED_KEY <object> <key>
|
|---|
| 2749 | * SX_TIED_IDX <object> <index>
|
|---|
| 2750 | */
|
|---|
| 2751 | static int store_tied_item(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 2752 | {
|
|---|
| 2753 | MAGIC *mg;
|
|---|
| 2754 | int ret;
|
|---|
| 2755 |
|
|---|
| 2756 | TRACEME(("store_tied_item (0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 2757 |
|
|---|
| 2758 | if (!(mg = mg_find(sv, 'p')))
|
|---|
| 2759 | CROAK(("No magic 'p' found while storing reference to tied item"));
|
|---|
| 2760 |
|
|---|
| 2761 | /*
|
|---|
| 2762 | * We discriminate between \$h{key} and \$a[idx] via mg_ptr.
|
|---|
| 2763 | */
|
|---|
| 2764 |
|
|---|
| 2765 | if (mg->mg_ptr) {
|
|---|
| 2766 | TRACEME(("store_tied_item: storing a ref to a tied hash item"));
|
|---|
| 2767 | PUTMARK(SX_TIED_KEY);
|
|---|
| 2768 | TRACEME(("store_tied_item: storing OBJ 0x%"UVxf, PTR2UV(mg->mg_obj)));
|
|---|
| 2769 |
|
|---|
| 2770 | if ((ret = store(aTHX_ cxt, mg->mg_obj))) /* Extra () for -Wall, grr... */
|
|---|
| 2771 | return ret;
|
|---|
| 2772 |
|
|---|
| 2773 | TRACEME(("store_tied_item: storing PTR 0x%"UVxf, PTR2UV(mg->mg_ptr)));
|
|---|
| 2774 |
|
|---|
| 2775 | if ((ret = store(aTHX_ cxt, (SV *) mg->mg_ptr))) /* Idem, for -Wall */
|
|---|
| 2776 | return ret;
|
|---|
| 2777 | } else {
|
|---|
| 2778 | I32 idx = mg->mg_len;
|
|---|
| 2779 |
|
|---|
| 2780 | TRACEME(("store_tied_item: storing a ref to a tied array item "));
|
|---|
| 2781 | PUTMARK(SX_TIED_IDX);
|
|---|
| 2782 | TRACEME(("store_tied_item: storing OBJ 0x%"UVxf, PTR2UV(mg->mg_obj)));
|
|---|
| 2783 |
|
|---|
| 2784 | if ((ret = store(aTHX_ cxt, mg->mg_obj))) /* Idem, for -Wall */
|
|---|
| 2785 | return ret;
|
|---|
| 2786 |
|
|---|
| 2787 | TRACEME(("store_tied_item: storing IDX %d", idx));
|
|---|
| 2788 |
|
|---|
| 2789 | WLEN(idx);
|
|---|
| 2790 | }
|
|---|
| 2791 |
|
|---|
| 2792 | TRACEME(("ok (tied item)"));
|
|---|
| 2793 |
|
|---|
| 2794 | return 0;
|
|---|
| 2795 | }
|
|---|
| 2796 |
|
|---|
| 2797 | /*
|
|---|
| 2798 | * store_hook -- dispatched manually, not via sv_store[]
|
|---|
| 2799 | *
|
|---|
| 2800 | * The blessed SV is serialized by a hook.
|
|---|
| 2801 | *
|
|---|
| 2802 | * Simple Layout is:
|
|---|
| 2803 | *
|
|---|
| 2804 | * SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
|
|---|
| 2805 | *
|
|---|
| 2806 | * where <flags> indicates how long <len>, <len2> and <len3> are, whether
|
|---|
| 2807 | * the trailing part [] is present, the type of object (scalar, array or hash).
|
|---|
| 2808 | * There is also a bit which says how the classname is stored between:
|
|---|
| 2809 | *
|
|---|
| 2810 | * <len> <classname>
|
|---|
| 2811 | * <index>
|
|---|
| 2812 | *
|
|---|
| 2813 | * and when the <index> form is used (classname already seen), the "large
|
|---|
| 2814 | * classname" bit in <flags> indicates how large the <index> is.
|
|---|
| 2815 | *
|
|---|
| 2816 | * The serialized string returned by the hook is of length <len2> and comes
|
|---|
| 2817 | * next. It is an opaque string for us.
|
|---|
| 2818 | *
|
|---|
| 2819 | * Those <len3> object IDs which are listed last represent the extra references
|
|---|
| 2820 | * not directly serialized by the hook, but which are linked to the object.
|
|---|
| 2821 | *
|
|---|
| 2822 | * When recursion is mandated to resolve object-IDs not yet seen, we have
|
|---|
| 2823 | * instead, with <header> being flags with bits set to indicate the object type
|
|---|
| 2824 | * and that recursion was indeed needed:
|
|---|
| 2825 | *
|
|---|
| 2826 | * SX_HOOK <header> <object> <header> <object> <flags>
|
|---|
| 2827 | *
|
|---|
| 2828 | * that same header being repeated between serialized objects obtained through
|
|---|
| 2829 | * recursion, until we reach flags indicating no recursion, at which point
|
|---|
| 2830 | * we know we've resynchronized with a single layout, after <flags>.
|
|---|
| 2831 | *
|
|---|
| 2832 | * When storing a blessed ref to a tied variable, the following format is
|
|---|
| 2833 | * used:
|
|---|
| 2834 | *
|
|---|
| 2835 | * SX_HOOK <flags> <extra> ... [<len3> <object-IDs>] <magic object>
|
|---|
| 2836 | *
|
|---|
| 2837 | * The first <flags> indication carries an object of type SHT_EXTRA, and the
|
|---|
| 2838 | * real object type is held in the <extra> flag. At the very end of the
|
|---|
| 2839 | * serialization stream, the underlying magic object is serialized, just like
|
|---|
| 2840 | * any other tied variable.
|
|---|
| 2841 | */
|
|---|
| 2842 | static int store_hook(
|
|---|
| 2843 | pTHX_
|
|---|
| 2844 | stcxt_t *cxt,
|
|---|
| 2845 | SV *sv,
|
|---|
| 2846 | int type,
|
|---|
| 2847 | HV *pkg,
|
|---|
| 2848 | SV *hook)
|
|---|
| 2849 | {
|
|---|
| 2850 | I32 len;
|
|---|
| 2851 | char *classname;
|
|---|
| 2852 | STRLEN len2;
|
|---|
| 2853 | SV *ref;
|
|---|
| 2854 | AV *av;
|
|---|
| 2855 | SV **ary;
|
|---|
| 2856 | int count; /* really len3 + 1 */
|
|---|
| 2857 | unsigned char flags;
|
|---|
| 2858 | char *pv;
|
|---|
| 2859 | int i;
|
|---|
| 2860 | int recursed = 0; /* counts recursion */
|
|---|
| 2861 | int obj_type; /* object type, on 2 bits */
|
|---|
| 2862 | I32 classnum;
|
|---|
| 2863 | int ret;
|
|---|
| 2864 | int clone = cxt->optype & ST_CLONE;
|
|---|
| 2865 | char mtype = '\0'; /* for blessed ref to tied structures */
|
|---|
| 2866 | unsigned char eflags = '\0'; /* used when object type is SHT_EXTRA */
|
|---|
| 2867 |
|
|---|
| 2868 | TRACEME(("store_hook, classname \"%s\", tagged #%d", HvNAME_get(pkg), cxt->tagnum));
|
|---|
| 2869 |
|
|---|
| 2870 | /*
|
|---|
| 2871 | * Determine object type on 2 bits.
|
|---|
| 2872 | */
|
|---|
| 2873 |
|
|---|
| 2874 | switch (type) {
|
|---|
| 2875 | case svis_SCALAR:
|
|---|
| 2876 | obj_type = SHT_SCALAR;
|
|---|
| 2877 | break;
|
|---|
| 2878 | case svis_ARRAY:
|
|---|
| 2879 | obj_type = SHT_ARRAY;
|
|---|
| 2880 | break;
|
|---|
| 2881 | case svis_HASH:
|
|---|
| 2882 | obj_type = SHT_HASH;
|
|---|
| 2883 | break;
|
|---|
| 2884 | case svis_TIED:
|
|---|
| 2885 | /*
|
|---|
| 2886 | * Produced by a blessed ref to a tied data structure, $o in the
|
|---|
| 2887 | * following Perl code.
|
|---|
| 2888 | *
|
|---|
| 2889 | * my %h;
|
|---|
| 2890 | * tie %h, 'FOO';
|
|---|
| 2891 | * my $o = bless \%h, 'BAR';
|
|---|
| 2892 | *
|
|---|
| 2893 | * Signal the tie-ing magic by setting the object type as SHT_EXTRA
|
|---|
| 2894 | * (since we have only 2 bits in <flags> to store the type), and an
|
|---|
| 2895 | * <extra> byte flag will be emitted after the FIRST <flags> in the
|
|---|
| 2896 | * stream, carrying what we put in `eflags'.
|
|---|
| 2897 | */
|
|---|
| 2898 | obj_type = SHT_EXTRA;
|
|---|
| 2899 | switch (SvTYPE(sv)) {
|
|---|
| 2900 | case SVt_PVHV:
|
|---|
| 2901 | eflags = (unsigned char) SHT_THASH;
|
|---|
| 2902 | mtype = 'P';
|
|---|
| 2903 | break;
|
|---|
| 2904 | case SVt_PVAV:
|
|---|
| 2905 | eflags = (unsigned char) SHT_TARRAY;
|
|---|
| 2906 | mtype = 'P';
|
|---|
| 2907 | break;
|
|---|
| 2908 | default:
|
|---|
| 2909 | eflags = (unsigned char) SHT_TSCALAR;
|
|---|
| 2910 | mtype = 'q';
|
|---|
| 2911 | break;
|
|---|
| 2912 | }
|
|---|
| 2913 | break;
|
|---|
| 2914 | default:
|
|---|
| 2915 | CROAK(("Unexpected object type (%d) in store_hook()", type));
|
|---|
| 2916 | }
|
|---|
| 2917 | flags = SHF_NEED_RECURSE | obj_type;
|
|---|
| 2918 |
|
|---|
| 2919 | classname = HvNAME_get(pkg);
|
|---|
| 2920 | len = strlen(classname);
|
|---|
| 2921 |
|
|---|
| 2922 | /*
|
|---|
| 2923 | * To call the hook, we need to fake a call like:
|
|---|
| 2924 | *
|
|---|
| 2925 | * $object->STORABLE_freeze($cloning);
|
|---|
| 2926 | *
|
|---|
| 2927 | * but we don't have the $object here. For instance, if $object is
|
|---|
| 2928 | * a blessed array, what we have in `sv' is the array, and we can't
|
|---|
| 2929 | * call a method on those.
|
|---|
| 2930 | *
|
|---|
| 2931 | * Therefore, we need to create a temporary reference to the object and
|
|---|
| 2932 | * make the call on that reference.
|
|---|
| 2933 | */
|
|---|
| 2934 |
|
|---|
| 2935 | TRACEME(("about to call STORABLE_freeze on class %s", classname));
|
|---|
| 2936 |
|
|---|
| 2937 | ref = newRV_noinc(sv); /* Temporary reference */
|
|---|
| 2938 | av = array_call(aTHX_ ref, hook, clone); /* @a = $object->STORABLE_freeze($c) */
|
|---|
| 2939 | SvRV_set(ref, NULL);
|
|---|
| 2940 | SvREFCNT_dec(ref); /* Reclaim temporary reference */
|
|---|
| 2941 |
|
|---|
| 2942 | count = AvFILLp(av) + 1;
|
|---|
| 2943 | TRACEME(("store_hook, array holds %d items", count));
|
|---|
| 2944 |
|
|---|
| 2945 | /*
|
|---|
| 2946 | * If they return an empty list, it means they wish to ignore the
|
|---|
| 2947 | * hook for this class (and not just this instance -- that's for them
|
|---|
| 2948 | * to handle if they so wish).
|
|---|
| 2949 | *
|
|---|
| 2950 | * Simply disable the cached entry for the hook (it won't be recomputed
|
|---|
| 2951 | * since it's present in the cache) and recurse to store_blessed().
|
|---|
| 2952 | */
|
|---|
| 2953 |
|
|---|
| 2954 | if (!count) {
|
|---|
| 2955 | /*
|
|---|
| 2956 | * They must not change their mind in the middle of a serialization.
|
|---|
| 2957 | */
|
|---|
| 2958 |
|
|---|
| 2959 | if (hv_fetch(cxt->hclass, classname, len, FALSE))
|
|---|
| 2960 | CROAK(("Too late to ignore hooks for %s class \"%s\"",
|
|---|
| 2961 | (cxt->optype & ST_CLONE) ? "cloning" : "storing", classname));
|
|---|
| 2962 |
|
|---|
| 2963 | pkg_hide(aTHX_ cxt->hook, pkg, "STORABLE_freeze");
|
|---|
| 2964 |
|
|---|
| 2965 | ASSERT(!pkg_can(aTHX_ cxt->hook, pkg, "STORABLE_freeze"), ("hook invisible"));
|
|---|
| 2966 | TRACEME(("ignoring STORABLE_freeze in class \"%s\"", classname));
|
|---|
| 2967 |
|
|---|
| 2968 | return store_blessed(aTHX_ cxt, sv, type, pkg);
|
|---|
| 2969 | }
|
|---|
| 2970 |
|
|---|
| 2971 | /*
|
|---|
| 2972 | * Get frozen string.
|
|---|
| 2973 | */
|
|---|
| 2974 |
|
|---|
| 2975 | ary = AvARRAY(av);
|
|---|
| 2976 | pv = SvPV(ary[0], len2);
|
|---|
| 2977 | /* We can't use pkg_can here because it only caches one method per
|
|---|
| 2978 | * package */
|
|---|
| 2979 | {
|
|---|
| 2980 | GV* gv = gv_fetchmethod_autoload(pkg, "STORABLE_attach", FALSE);
|
|---|
| 2981 | if (gv && isGV(gv)) {
|
|---|
| 2982 | if (count > 1)
|
|---|
| 2983 | CROAK(("Freeze cannot return references if %s class is using STORABLE_attach", classname));
|
|---|
| 2984 | goto check_done;
|
|---|
| 2985 | }
|
|---|
| 2986 | }
|
|---|
| 2987 |
|
|---|
| 2988 | /*
|
|---|
| 2989 | * If they returned more than one item, we need to serialize some
|
|---|
| 2990 | * extra references if not already done.
|
|---|
| 2991 | *
|
|---|
| 2992 | * Loop over the array, starting at position #1, and for each item,
|
|---|
| 2993 | * ensure it is a reference, serialize it if not already done, and
|
|---|
| 2994 | * replace the entry with the tag ID of the corresponding serialized
|
|---|
| 2995 | * object.
|
|---|
| 2996 | *
|
|---|
| 2997 | * We CHEAT by not calling av_fetch() and read directly within the
|
|---|
| 2998 | * array, for speed.
|
|---|
| 2999 | */
|
|---|
| 3000 |
|
|---|
| 3001 | for (i = 1; i < count; i++) {
|
|---|
| 3002 | #ifdef USE_PTR_TABLE
|
|---|
| 3003 | char *fake_tag;
|
|---|
| 3004 | #else
|
|---|
| 3005 | SV **svh;
|
|---|
| 3006 | #endif
|
|---|
| 3007 | SV *rsv = ary[i];
|
|---|
| 3008 | SV *xsv;
|
|---|
| 3009 | SV *tag;
|
|---|
| 3010 | AV *av_hook = cxt->hook_seen;
|
|---|
| 3011 |
|
|---|
| 3012 | if (!SvROK(rsv))
|
|---|
| 3013 | CROAK(("Item #%d returned by STORABLE_freeze "
|
|---|
| 3014 | "for %s is not a reference", i, classname));
|
|---|
| 3015 | xsv = SvRV(rsv); /* Follow ref to know what to look for */
|
|---|
| 3016 |
|
|---|
| 3017 | /*
|
|---|
| 3018 | * Look in hseen and see if we have a tag already.
|
|---|
| 3019 | * Serialize entry if not done already, and get its tag.
|
|---|
| 3020 | */
|
|---|
| 3021 |
|
|---|
| 3022 | #ifdef USE_PTR_TABLE
|
|---|
| 3023 | /* Fakery needed because ptr_table_fetch returns zero for a
|
|---|
| 3024 | failure, whereas the existing code assumes that it can
|
|---|
| 3025 | safely store a tag zero. So for ptr_tables we store tag+1
|
|---|
| 3026 | */
|
|---|
| 3027 | if ((fake_tag = ptr_table_fetch(cxt->pseen, xsv)))
|
|---|
| 3028 | goto sv_seen; /* Avoid moving code too far to the right */
|
|---|
| 3029 | #else
|
|---|
| 3030 | if ((svh = hv_fetch(cxt->hseen, (char *) &xsv, sizeof(xsv), FALSE)))
|
|---|
| 3031 | goto sv_seen; /* Avoid moving code too far to the right */
|
|---|
| 3032 | #endif
|
|---|
| 3033 |
|
|---|
| 3034 | TRACEME(("listed object %d at 0x%"UVxf" is unknown", i-1, PTR2UV(xsv)));
|
|---|
| 3035 |
|
|---|
| 3036 | /*
|
|---|
| 3037 | * We need to recurse to store that object and get it to be known
|
|---|
| 3038 | * so that we can resolve the list of object-IDs at retrieve time.
|
|---|
| 3039 | *
|
|---|
| 3040 | * The first time we do this, we need to emit the proper header
|
|---|
| 3041 | * indicating that we recursed, and what the type of object is (the
|
|---|
| 3042 | * object we're storing via a user-hook). Indeed, during retrieval,
|
|---|
| 3043 | * we'll have to create the object before recursing to retrieve the
|
|---|
| 3044 | * others, in case those would point back at that object.
|
|---|
| 3045 | */
|
|---|
| 3046 |
|
|---|
| 3047 | /* [SX_HOOK] <flags> [<extra>] <object>*/
|
|---|
| 3048 | if (!recursed++) {
|
|---|
| 3049 | PUTMARK(SX_HOOK);
|
|---|
| 3050 | PUTMARK(flags);
|
|---|
| 3051 | if (obj_type == SHT_EXTRA)
|
|---|
| 3052 | PUTMARK(eflags);
|
|---|
| 3053 | } else
|
|---|
| 3054 | PUTMARK(flags);
|
|---|
| 3055 |
|
|---|
| 3056 | if ((ret = store(aTHX_ cxt, xsv))) /* Given by hook for us to store */
|
|---|
| 3057 | return ret;
|
|---|
| 3058 |
|
|---|
| 3059 | #ifdef USE_PTR_TABLE
|
|---|
| 3060 | fake_tag = ptr_table_fetch(cxt->pseen, xsv);
|
|---|
| 3061 | if (!sv)
|
|---|
| 3062 | CROAK(("Could not serialize item #%d from hook in %s", i, classname));
|
|---|
| 3063 | #else
|
|---|
| 3064 | svh = hv_fetch(cxt->hseen, (char *) &xsv, sizeof(xsv), FALSE);
|
|---|
| 3065 | if (!svh)
|
|---|
| 3066 | CROAK(("Could not serialize item #%d from hook in %s", i, classname));
|
|---|
| 3067 | #endif
|
|---|
| 3068 | /*
|
|---|
| 3069 | * It was the first time we serialized `xsv'.
|
|---|
| 3070 | *
|
|---|
| 3071 | * Keep this SV alive until the end of the serialization: if we
|
|---|
| 3072 | * disposed of it right now by decrementing its refcount, and it was
|
|---|
| 3073 | * a temporary value, some next temporary value allocated during
|
|---|
| 3074 | * another STORABLE_freeze might take its place, and we'd wrongly
|
|---|
| 3075 | * assume that new SV was already serialized, based on its presence
|
|---|
| 3076 | * in cxt->hseen.
|
|---|
| 3077 | *
|
|---|
| 3078 | * Therefore, push it away in cxt->hook_seen.
|
|---|
| 3079 | */
|
|---|
| 3080 |
|
|---|
| 3081 | av_store(av_hook, AvFILLp(av_hook)+1, SvREFCNT_inc(xsv));
|
|---|
| 3082 |
|
|---|
| 3083 | sv_seen:
|
|---|
| 3084 | /*
|
|---|
| 3085 | * Dispose of the REF they returned. If we saved the `xsv' away
|
|---|
| 3086 | * in the array of returned SVs, that will not cause the underlying
|
|---|
| 3087 | * referenced SV to be reclaimed.
|
|---|
| 3088 | */
|
|---|
| 3089 |
|
|---|
| 3090 | ASSERT(SvREFCNT(xsv) > 1, ("SV will survive disposal of its REF"));
|
|---|
| 3091 | SvREFCNT_dec(rsv); /* Dispose of reference */
|
|---|
| 3092 |
|
|---|
| 3093 | /*
|
|---|
| 3094 | * Replace entry with its tag (not a real SV, so no refcnt increment)
|
|---|
| 3095 | */
|
|---|
| 3096 |
|
|---|
| 3097 | #ifdef USE_PTR_TABLE
|
|---|
| 3098 | tag = (SV *)--fake_tag;
|
|---|
| 3099 | #else
|
|---|
| 3100 | tag = *svh;
|
|---|
| 3101 | #endif
|
|---|
| 3102 | ary[i] = tag
|
|---|
| 3103 | TRACEME(("listed object %d at 0x%"UVxf" is tag #%"UVuf,
|
|---|
| 3104 | i-1, PTR2UV(xsv), PTR2UV(tag)));
|
|---|
| 3105 | }
|
|---|
| 3106 |
|
|---|
| 3107 | /*
|
|---|
| 3108 | * Allocate a class ID if not already done.
|
|---|
| 3109 | *
|
|---|
| 3110 | * This needs to be done after the recursion above, since at retrieval
|
|---|
| 3111 | * time, we'll see the inner objects first. Many thanks to
|
|---|
| 3112 | * Salvador Ortiz Garcia <[email protected]> who spot that bug and
|
|---|
| 3113 | * proposed the right fix. -- RAM, 15/09/2000
|
|---|
| 3114 | */
|
|---|
| 3115 |
|
|---|
| 3116 | check_done:
|
|---|
| 3117 | if (!known_class(aTHX_ cxt, classname, len, &classnum)) {
|
|---|
| 3118 | TRACEME(("first time we see class %s, ID = %d", classname, classnum));
|
|---|
| 3119 | classnum = -1; /* Mark: we must store classname */
|
|---|
| 3120 | } else {
|
|---|
| 3121 | TRACEME(("already seen class %s, ID = %d", classname, classnum));
|
|---|
| 3122 | }
|
|---|
| 3123 |
|
|---|
| 3124 | /*
|
|---|
| 3125 | * Compute leading flags.
|
|---|
| 3126 | */
|
|---|
| 3127 |
|
|---|
| 3128 | flags = obj_type;
|
|---|
| 3129 | if (((classnum == -1) ? len : classnum) > LG_SCALAR)
|
|---|
| 3130 | flags |= SHF_LARGE_CLASSLEN;
|
|---|
| 3131 | if (classnum != -1)
|
|---|
| 3132 | flags |= SHF_IDX_CLASSNAME;
|
|---|
| 3133 | if (len2 > LG_SCALAR)
|
|---|
| 3134 | flags |= SHF_LARGE_STRLEN;
|
|---|
| 3135 | if (count > 1)
|
|---|
| 3136 | flags |= SHF_HAS_LIST;
|
|---|
| 3137 | if (count > (LG_SCALAR + 1))
|
|---|
| 3138 | flags |= SHF_LARGE_LISTLEN;
|
|---|
| 3139 |
|
|---|
| 3140 | /*
|
|---|
| 3141 | * We're ready to emit either serialized form:
|
|---|
| 3142 | *
|
|---|
| 3143 | * SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
|
|---|
| 3144 | * SX_HOOK <flags> <index> <len2> <str> [<len3> <object-IDs>]
|
|---|
| 3145 | *
|
|---|
| 3146 | * If we recursed, the SX_HOOK has already been emitted.
|
|---|
| 3147 | */
|
|---|
| 3148 |
|
|---|
| 3149 | TRACEME(("SX_HOOK (recursed=%d) flags=0x%x "
|
|---|
| 3150 | "class=%"IVdf" len=%"IVdf" len2=%"IVdf" len3=%d",
|
|---|
| 3151 | recursed, flags, (IV)classnum, (IV)len, (IV)len2, count-1));
|
|---|
| 3152 |
|
|---|
| 3153 | /* SX_HOOK <flags> [<extra>] */
|
|---|
| 3154 | if (!recursed) {
|
|---|
| 3155 | PUTMARK(SX_HOOK);
|
|---|
| 3156 | PUTMARK(flags);
|
|---|
| 3157 | if (obj_type == SHT_EXTRA)
|
|---|
| 3158 | PUTMARK(eflags);
|
|---|
| 3159 | } else
|
|---|
| 3160 | PUTMARK(flags);
|
|---|
| 3161 |
|
|---|
| 3162 | /* <len> <classname> or <index> */
|
|---|
| 3163 | if (flags & SHF_IDX_CLASSNAME) {
|
|---|
| 3164 | if (flags & SHF_LARGE_CLASSLEN)
|
|---|
| 3165 | WLEN(classnum);
|
|---|
| 3166 | else {
|
|---|
| 3167 | unsigned char cnum = (unsigned char) classnum;
|
|---|
| 3168 | PUTMARK(cnum);
|
|---|
| 3169 | }
|
|---|
| 3170 | } else {
|
|---|
| 3171 | if (flags & SHF_LARGE_CLASSLEN)
|
|---|
| 3172 | WLEN(len);
|
|---|
| 3173 | else {
|
|---|
| 3174 | unsigned char clen = (unsigned char) len;
|
|---|
| 3175 | PUTMARK(clen);
|
|---|
| 3176 | }
|
|---|
| 3177 | WRITE(classname, len); /* Final \0 is omitted */
|
|---|
| 3178 | }
|
|---|
| 3179 |
|
|---|
| 3180 | /* <len2> <frozen-str> */
|
|---|
| 3181 | if (flags & SHF_LARGE_STRLEN) {
|
|---|
| 3182 | I32 wlen2 = len2; /* STRLEN might be 8 bytes */
|
|---|
| 3183 | WLEN(wlen2); /* Must write an I32 for 64-bit machines */
|
|---|
| 3184 | } else {
|
|---|
| 3185 | unsigned char clen = (unsigned char) len2;
|
|---|
| 3186 | PUTMARK(clen);
|
|---|
| 3187 | }
|
|---|
| 3188 | if (len2)
|
|---|
| 3189 | WRITE(pv, (SSize_t)len2); /* Final \0 is omitted */
|
|---|
| 3190 |
|
|---|
| 3191 | /* [<len3> <object-IDs>] */
|
|---|
| 3192 | if (flags & SHF_HAS_LIST) {
|
|---|
| 3193 | int len3 = count - 1;
|
|---|
| 3194 | if (flags & SHF_LARGE_LISTLEN)
|
|---|
| 3195 | WLEN(len3);
|
|---|
| 3196 | else {
|
|---|
| 3197 | unsigned char clen = (unsigned char) len3;
|
|---|
| 3198 | PUTMARK(clen);
|
|---|
| 3199 | }
|
|---|
| 3200 |
|
|---|
| 3201 | /*
|
|---|
| 3202 | * NOTA BENE, for 64-bit machines: the ary[i] below does not yield a
|
|---|
| 3203 | * real pointer, rather a tag number, well under the 32-bit limit.
|
|---|
| 3204 | */
|
|---|
| 3205 |
|
|---|
| 3206 | for (i = 1; i < count; i++) {
|
|---|
| 3207 | I32 tagval = htonl(LOW_32BITS(ary[i]));
|
|---|
| 3208 | WRITE_I32(tagval);
|
|---|
| 3209 | TRACEME(("object %d, tag #%d", i-1, ntohl(tagval)));
|
|---|
| 3210 | }
|
|---|
| 3211 | }
|
|---|
| 3212 |
|
|---|
| 3213 | /*
|
|---|
| 3214 | * Free the array. We need extra care for indices after 0, since they
|
|---|
| 3215 | * don't hold real SVs but integers cast.
|
|---|
| 3216 | */
|
|---|
| 3217 |
|
|---|
| 3218 | if (count > 1)
|
|---|
| 3219 | AvFILLp(av) = 0; /* Cheat, nothing after 0 interests us */
|
|---|
| 3220 | av_undef(av);
|
|---|
| 3221 | sv_free((SV *) av);
|
|---|
| 3222 |
|
|---|
| 3223 | /*
|
|---|
| 3224 | * If object was tied, need to insert serialization of the magic object.
|
|---|
| 3225 | */
|
|---|
| 3226 |
|
|---|
| 3227 | if (obj_type == SHT_EXTRA) {
|
|---|
| 3228 | MAGIC *mg;
|
|---|
| 3229 |
|
|---|
| 3230 | if (!(mg = mg_find(sv, mtype))) {
|
|---|
| 3231 | int svt = SvTYPE(sv);
|
|---|
| 3232 | CROAK(("No magic '%c' found while storing ref to tied %s with hook",
|
|---|
| 3233 | mtype, (svt == SVt_PVHV) ? "hash" :
|
|---|
| 3234 | (svt == SVt_PVAV) ? "array" : "scalar"));
|
|---|
| 3235 | }
|
|---|
| 3236 |
|
|---|
| 3237 | TRACEME(("handling the magic object 0x%"UVxf" part of 0x%"UVxf,
|
|---|
| 3238 | PTR2UV(mg->mg_obj), PTR2UV(sv)));
|
|---|
| 3239 |
|
|---|
| 3240 | /*
|
|---|
| 3241 | * [<magic object>]
|
|---|
| 3242 | */
|
|---|
| 3243 |
|
|---|
| 3244 | if ((ret = store(aTHX_ cxt, mg->mg_obj))) /* Extra () for -Wall, grr... */
|
|---|
| 3245 | return ret;
|
|---|
| 3246 | }
|
|---|
| 3247 |
|
|---|
| 3248 | return 0;
|
|---|
| 3249 | }
|
|---|
| 3250 |
|
|---|
| 3251 | /*
|
|---|
| 3252 | * store_blessed -- dispatched manually, not via sv_store[]
|
|---|
| 3253 | *
|
|---|
| 3254 | * Check whether there is a STORABLE_xxx hook defined in the class or in one
|
|---|
| 3255 | * of its ancestors. If there is, then redispatch to store_hook();
|
|---|
| 3256 | *
|
|---|
| 3257 | * Otherwise, the blessed SV is stored using the following layout:
|
|---|
| 3258 | *
|
|---|
| 3259 | * SX_BLESS <flag> <len> <classname> <object>
|
|---|
| 3260 | *
|
|---|
| 3261 | * where <flag> indicates whether <len> is stored on 0 or 4 bytes, depending
|
|---|
| 3262 | * on the high-order bit in flag: if 1, then length follows on 4 bytes.
|
|---|
| 3263 | * Otherwise, the low order bits give the length, thereby giving a compact
|
|---|
| 3264 | * representation for class names less than 127 chars long.
|
|---|
| 3265 | *
|
|---|
| 3266 | * Each <classname> seen is remembered and indexed, so that the next time
|
|---|
| 3267 | * an object in the blessed in the same <classname> is stored, the following
|
|---|
| 3268 | * will be emitted:
|
|---|
| 3269 | *
|
|---|
| 3270 | * SX_IX_BLESS <flag> <index> <object>
|
|---|
| 3271 | *
|
|---|
| 3272 | * where <index> is the classname index, stored on 0 or 4 bytes depending
|
|---|
| 3273 | * on the high-order bit in flag (same encoding as above for <len>).
|
|---|
| 3274 | */
|
|---|
| 3275 | static int store_blessed(
|
|---|
| 3276 | pTHX_
|
|---|
| 3277 | stcxt_t *cxt,
|
|---|
| 3278 | SV *sv,
|
|---|
| 3279 | int type,
|
|---|
| 3280 | HV *pkg)
|
|---|
| 3281 | {
|
|---|
| 3282 | SV *hook;
|
|---|
| 3283 | I32 len;
|
|---|
| 3284 | char *classname;
|
|---|
| 3285 | I32 classnum;
|
|---|
| 3286 |
|
|---|
| 3287 | TRACEME(("store_blessed, type %d, class \"%s\"", type, HvNAME_get(pkg)));
|
|---|
| 3288 |
|
|---|
| 3289 | /*
|
|---|
| 3290 | * Look for a hook for this blessed SV and redirect to store_hook()
|
|---|
| 3291 | * if needed.
|
|---|
| 3292 | */
|
|---|
| 3293 |
|
|---|
| 3294 | hook = pkg_can(aTHX_ cxt->hook, pkg, "STORABLE_freeze");
|
|---|
| 3295 | if (hook)
|
|---|
| 3296 | return store_hook(aTHX_ cxt, sv, type, pkg, hook);
|
|---|
| 3297 |
|
|---|
| 3298 | /*
|
|---|
| 3299 | * This is a blessed SV without any serialization hook.
|
|---|
| 3300 | */
|
|---|
| 3301 |
|
|---|
| 3302 | classname = HvNAME_get(pkg);
|
|---|
| 3303 | len = strlen(classname);
|
|---|
| 3304 |
|
|---|
| 3305 | TRACEME(("blessed 0x%"UVxf" in %s, no hook: tagged #%d",
|
|---|
| 3306 | PTR2UV(sv), classname, cxt->tagnum));
|
|---|
| 3307 |
|
|---|
| 3308 | /*
|
|---|
| 3309 | * Determine whether it is the first time we see that class name (in which
|
|---|
| 3310 | * case it will be stored in the SX_BLESS form), or whether we already
|
|---|
| 3311 | * saw that class name before (in which case the SX_IX_BLESS form will be
|
|---|
| 3312 | * used).
|
|---|
| 3313 | */
|
|---|
| 3314 |
|
|---|
| 3315 | if (known_class(aTHX_ cxt, classname, len, &classnum)) {
|
|---|
| 3316 | TRACEME(("already seen class %s, ID = %d", classname, classnum));
|
|---|
| 3317 | PUTMARK(SX_IX_BLESS);
|
|---|
| 3318 | if (classnum <= LG_BLESS) {
|
|---|
| 3319 | unsigned char cnum = (unsigned char) classnum;
|
|---|
| 3320 | PUTMARK(cnum);
|
|---|
| 3321 | } else {
|
|---|
| 3322 | unsigned char flag = (unsigned char) 0x80;
|
|---|
| 3323 | PUTMARK(flag);
|
|---|
| 3324 | WLEN(classnum);
|
|---|
| 3325 | }
|
|---|
| 3326 | } else {
|
|---|
| 3327 | TRACEME(("first time we see class %s, ID = %d", classname, classnum));
|
|---|
| 3328 | PUTMARK(SX_BLESS);
|
|---|
| 3329 | if (len <= LG_BLESS) {
|
|---|
| 3330 | unsigned char clen = (unsigned char) len;
|
|---|
| 3331 | PUTMARK(clen);
|
|---|
| 3332 | } else {
|
|---|
| 3333 | unsigned char flag = (unsigned char) 0x80;
|
|---|
| 3334 | PUTMARK(flag);
|
|---|
| 3335 | WLEN(len); /* Don't BER-encode, this should be rare */
|
|---|
| 3336 | }
|
|---|
| 3337 | WRITE(classname, len); /* Final \0 is omitted */
|
|---|
| 3338 | }
|
|---|
| 3339 |
|
|---|
| 3340 | /*
|
|---|
| 3341 | * Now emit the <object> part.
|
|---|
| 3342 | */
|
|---|
| 3343 |
|
|---|
| 3344 | return SV_STORE(type)(aTHX_ cxt, sv);
|
|---|
| 3345 | }
|
|---|
| 3346 |
|
|---|
| 3347 | /*
|
|---|
| 3348 | * store_other
|
|---|
| 3349 | *
|
|---|
| 3350 | * We don't know how to store the item we reached, so return an error condition.
|
|---|
| 3351 | * (it's probably a GLOB, some CODE reference, etc...)
|
|---|
| 3352 | *
|
|---|
| 3353 | * If they defined the `forgive_me' variable at the Perl level to some
|
|---|
| 3354 | * true value, then don't croak, just warn, and store a placeholder string
|
|---|
| 3355 | * instead.
|
|---|
| 3356 | */
|
|---|
| 3357 | static int store_other(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 3358 | {
|
|---|
| 3359 | I32 len;
|
|---|
| 3360 | char buf[80];
|
|---|
| 3361 |
|
|---|
| 3362 | TRACEME(("store_other"));
|
|---|
| 3363 |
|
|---|
| 3364 | /*
|
|---|
| 3365 | * Fetch the value from perl only once per store() operation.
|
|---|
| 3366 | */
|
|---|
| 3367 |
|
|---|
| 3368 | if (
|
|---|
| 3369 | cxt->forgive_me == 0 ||
|
|---|
| 3370 | (cxt->forgive_me < 0 && !(cxt->forgive_me =
|
|---|
| 3371 | SvTRUE(perl_get_sv("Storable::forgive_me", TRUE)) ? 1 : 0))
|
|---|
| 3372 | )
|
|---|
| 3373 | CROAK(("Can't store %s items", sv_reftype(sv, FALSE)));
|
|---|
| 3374 |
|
|---|
| 3375 | warn("Can't store item %s(0x%"UVxf")",
|
|---|
| 3376 | sv_reftype(sv, FALSE), PTR2UV(sv));
|
|---|
| 3377 |
|
|---|
| 3378 | /*
|
|---|
| 3379 | * Store placeholder string as a scalar instead...
|
|---|
| 3380 | */
|
|---|
| 3381 |
|
|---|
| 3382 | (void) sprintf(buf, "You lost %s(0x%"UVxf")%c", sv_reftype(sv, FALSE),
|
|---|
| 3383 | PTR2UV(sv), (char) 0);
|
|---|
| 3384 |
|
|---|
| 3385 | len = strlen(buf);
|
|---|
| 3386 | STORE_SCALAR(buf, len);
|
|---|
| 3387 | TRACEME(("ok (dummy \"%s\", length = %"IVdf")", buf, (IV) len));
|
|---|
| 3388 |
|
|---|
| 3389 | return 0;
|
|---|
| 3390 | }
|
|---|
| 3391 |
|
|---|
| 3392 | /***
|
|---|
| 3393 | *** Store driving routines
|
|---|
| 3394 | ***/
|
|---|
| 3395 |
|
|---|
| 3396 | /*
|
|---|
| 3397 | * sv_type
|
|---|
| 3398 | *
|
|---|
| 3399 | * WARNING: partially duplicates Perl's sv_reftype for speed.
|
|---|
| 3400 | *
|
|---|
| 3401 | * Returns the type of the SV, identified by an integer. That integer
|
|---|
| 3402 | * may then be used to index the dynamic routine dispatch table.
|
|---|
| 3403 | */
|
|---|
| 3404 | static int sv_type(pTHX_ SV *sv)
|
|---|
| 3405 | {
|
|---|
| 3406 | switch (SvTYPE(sv)) {
|
|---|
| 3407 | case SVt_NULL:
|
|---|
| 3408 | case SVt_IV:
|
|---|
| 3409 | case SVt_NV:
|
|---|
| 3410 | /*
|
|---|
| 3411 | * No need to check for ROK, that can't be set here since there
|
|---|
| 3412 | * is no field capable of hodling the xrv_rv reference.
|
|---|
| 3413 | */
|
|---|
| 3414 | return svis_SCALAR;
|
|---|
| 3415 | case SVt_PV:
|
|---|
| 3416 | case SVt_RV:
|
|---|
| 3417 | case SVt_PVIV:
|
|---|
| 3418 | case SVt_PVNV:
|
|---|
| 3419 | /*
|
|---|
| 3420 | * Starting from SVt_PV, it is possible to have the ROK flag
|
|---|
| 3421 | * set, the pointer to the other SV being either stored in
|
|---|
| 3422 | * the xrv_rv (in the case of a pure SVt_RV), or as the
|
|---|
| 3423 | * xpv_pv field of an SVt_PV and its heirs.
|
|---|
| 3424 | *
|
|---|
| 3425 | * However, those SV cannot be magical or they would be an
|
|---|
| 3426 | * SVt_PVMG at least.
|
|---|
| 3427 | */
|
|---|
| 3428 | return SvROK(sv) ? svis_REF : svis_SCALAR;
|
|---|
| 3429 | case SVt_PVMG:
|
|---|
| 3430 | case SVt_PVLV: /* Workaround for perl5.004_04 "LVALUE" bug */
|
|---|
| 3431 | if (SvRMAGICAL(sv) && (mg_find(sv, 'p')))
|
|---|
| 3432 | return svis_TIED_ITEM;
|
|---|
| 3433 | /* FALL THROUGH */
|
|---|
| 3434 | case SVt_PVBM:
|
|---|
| 3435 | if (SvRMAGICAL(sv) && (mg_find(sv, 'q')))
|
|---|
| 3436 | return svis_TIED;
|
|---|
| 3437 | return SvROK(sv) ? svis_REF : svis_SCALAR;
|
|---|
| 3438 | case SVt_PVAV:
|
|---|
| 3439 | if (SvRMAGICAL(sv) && (mg_find(sv, 'P')))
|
|---|
| 3440 | return svis_TIED;
|
|---|
| 3441 | return svis_ARRAY;
|
|---|
| 3442 | case SVt_PVHV:
|
|---|
| 3443 | if (SvRMAGICAL(sv) && (mg_find(sv, 'P')))
|
|---|
| 3444 | return svis_TIED;
|
|---|
| 3445 | return svis_HASH;
|
|---|
| 3446 | case SVt_PVCV:
|
|---|
| 3447 | return svis_CODE;
|
|---|
| 3448 | default:
|
|---|
| 3449 | break;
|
|---|
| 3450 | }
|
|---|
| 3451 |
|
|---|
| 3452 | return svis_OTHER;
|
|---|
| 3453 | }
|
|---|
| 3454 |
|
|---|
| 3455 | /*
|
|---|
| 3456 | * store
|
|---|
| 3457 | *
|
|---|
| 3458 | * Recursively store objects pointed to by the sv to the specified file.
|
|---|
| 3459 | *
|
|---|
| 3460 | * Layout is <content> or SX_OBJECT <tagnum> if we reach an already stored
|
|---|
| 3461 | * object (one for which storage has started -- it may not be over if we have
|
|---|
| 3462 | * a self-referenced structure). This data set forms a stored <object>.
|
|---|
| 3463 | */
|
|---|
| 3464 | static int store(pTHX_ stcxt_t *cxt, SV *sv)
|
|---|
| 3465 | {
|
|---|
| 3466 | SV **svh;
|
|---|
| 3467 | int ret;
|
|---|
| 3468 | int type;
|
|---|
| 3469 | #ifdef USE_PTR_TABLE
|
|---|
| 3470 | struct ptr_tbl *pseen = cxt->pseen;
|
|---|
| 3471 | #else
|
|---|
| 3472 | HV *hseen = cxt->hseen;
|
|---|
| 3473 | #endif
|
|---|
| 3474 |
|
|---|
| 3475 | TRACEME(("store (0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 3476 |
|
|---|
| 3477 | /*
|
|---|
| 3478 | * If object has already been stored, do not duplicate data.
|
|---|
| 3479 | * Simply emit the SX_OBJECT marker followed by its tag data.
|
|---|
| 3480 | * The tag is always written in network order.
|
|---|
| 3481 | *
|
|---|
| 3482 | * NOTA BENE, for 64-bit machines: the "*svh" below does not yield a
|
|---|
| 3483 | * real pointer, rather a tag number (watch the insertion code below).
|
|---|
| 3484 | * That means it probably safe to assume it is well under the 32-bit limit,
|
|---|
| 3485 | * and makes the truncation safe.
|
|---|
| 3486 | * -- RAM, 14/09/1999
|
|---|
| 3487 | */
|
|---|
| 3488 |
|
|---|
| 3489 | #ifdef USE_PTR_TABLE
|
|---|
| 3490 | svh = ptr_table_fetch(pseen, sv);
|
|---|
| 3491 | #else
|
|---|
| 3492 | svh = hv_fetch(hseen, (char *) &sv, sizeof(sv), FALSE);
|
|---|
| 3493 | #endif
|
|---|
| 3494 | if (svh) {
|
|---|
| 3495 | I32 tagval;
|
|---|
| 3496 |
|
|---|
| 3497 | if (sv == &PL_sv_undef) {
|
|---|
| 3498 | /* We have seen PL_sv_undef before, but fake it as
|
|---|
| 3499 | if we have not.
|
|---|
| 3500 |
|
|---|
| 3501 | Not the simplest solution to making restricted
|
|---|
| 3502 | hashes work on 5.8.0, but it does mean that
|
|---|
| 3503 | repeated references to the one true undef will
|
|---|
| 3504 | take up less space in the output file.
|
|---|
| 3505 | */
|
|---|
| 3506 | /* Need to jump past the next hv_store, because on the
|
|---|
| 3507 | second store of undef the old hash value will be
|
|---|
| 3508 | SvREFCNT_dec()ed, and as Storable cheats horribly
|
|---|
| 3509 | by storing non-SVs in the hash a SEGV will ensure.
|
|---|
| 3510 | Need to increase the tag number so that the
|
|---|
| 3511 | receiver has no idea what games we're up to. This
|
|---|
| 3512 | special casing doesn't affect hooks that store
|
|---|
| 3513 | undef, as the hook routine does its own lookup into
|
|---|
| 3514 | hseen. Also this means that any references back
|
|---|
| 3515 | to PL_sv_undef (from the pathological case of hooks
|
|---|
| 3516 | storing references to it) will find the seen hash
|
|---|
| 3517 | entry for the first time, as if we didn't have this
|
|---|
| 3518 | hackery here. (That hseen lookup works even on 5.8.0
|
|---|
| 3519 | because it's a key of &PL_sv_undef and a value
|
|---|
| 3520 | which is a tag number, not a value which is
|
|---|
| 3521 | PL_sv_undef.) */
|
|---|
| 3522 | cxt->tagnum++;
|
|---|
| 3523 | type = svis_SCALAR;
|
|---|
| 3524 | goto undef_special_case;
|
|---|
| 3525 | }
|
|---|
| 3526 |
|
|---|
| 3527 | #ifdef USE_PTR_TABLE
|
|---|
| 3528 | tagval = htonl(LOW_32BITS(((char *)svh)-1));
|
|---|
| 3529 | #else
|
|---|
| 3530 | tagval = htonl(LOW_32BITS(*svh));
|
|---|
| 3531 | #endif
|
|---|
| 3532 |
|
|---|
| 3533 | TRACEME(("object 0x%"UVxf" seen as #%d", PTR2UV(sv), ntohl(tagval)));
|
|---|
| 3534 |
|
|---|
| 3535 | PUTMARK(SX_OBJECT);
|
|---|
| 3536 | WRITE_I32(tagval);
|
|---|
| 3537 | return 0;
|
|---|
| 3538 | }
|
|---|
| 3539 |
|
|---|
| 3540 | /*
|
|---|
| 3541 | * Allocate a new tag and associate it with the address of the sv being
|
|---|
| 3542 | * stored, before recursing...
|
|---|
| 3543 | *
|
|---|
| 3544 | * In order to avoid creating new SvIVs to hold the tagnum we just
|
|---|
| 3545 | * cast the tagnum to an SV pointer and store that in the hash. This
|
|---|
| 3546 | * means that we must clean up the hash manually afterwards, but gives
|
|---|
| 3547 | * us a 15% throughput increase.
|
|---|
| 3548 | *
|
|---|
| 3549 | */
|
|---|
| 3550 |
|
|---|
| 3551 | cxt->tagnum++;
|
|---|
| 3552 | #ifdef USE_PTR_TABLE
|
|---|
| 3553 | ptr_table_store(pseen, sv, INT2PTR(SV*, 1 + cxt->tagnum));
|
|---|
| 3554 | #else
|
|---|
| 3555 | if (!hv_store(hseen,
|
|---|
| 3556 | (char *) &sv, sizeof(sv), INT2PTR(SV*, cxt->tagnum), 0))
|
|---|
| 3557 | return -1;
|
|---|
| 3558 | #endif
|
|---|
| 3559 |
|
|---|
| 3560 | /*
|
|---|
| 3561 | * Store `sv' and everything beneath it, using appropriate routine.
|
|---|
| 3562 | * Abort immediately if we get a non-zero status back.
|
|---|
| 3563 | */
|
|---|
| 3564 |
|
|---|
| 3565 | type = sv_type(aTHX_ sv);
|
|---|
| 3566 |
|
|---|
| 3567 | undef_special_case:
|
|---|
| 3568 | TRACEME(("storing 0x%"UVxf" tag #%d, type %d...",
|
|---|
| 3569 | PTR2UV(sv), cxt->tagnum, type));
|
|---|
| 3570 |
|
|---|
| 3571 | if (SvOBJECT(sv)) {
|
|---|
| 3572 | HV *pkg = SvSTASH(sv);
|
|---|
| 3573 | ret = store_blessed(aTHX_ cxt, sv, type, pkg);
|
|---|
| 3574 | } else
|
|---|
| 3575 | ret = SV_STORE(type)(aTHX_ cxt, sv);
|
|---|
| 3576 |
|
|---|
| 3577 | TRACEME(("%s (stored 0x%"UVxf", refcnt=%d, %s)",
|
|---|
| 3578 | ret ? "FAILED" : "ok", PTR2UV(sv),
|
|---|
| 3579 | SvREFCNT(sv), sv_reftype(sv, FALSE)));
|
|---|
| 3580 |
|
|---|
| 3581 | return ret;
|
|---|
| 3582 | }
|
|---|
| 3583 |
|
|---|
| 3584 | /*
|
|---|
| 3585 | * magic_write
|
|---|
| 3586 | *
|
|---|
| 3587 | * Write magic number and system information into the file.
|
|---|
| 3588 | * Layout is <magic> <network> [<len> <byteorder> <sizeof int> <sizeof long>
|
|---|
| 3589 | * <sizeof ptr>] where <len> is the length of the byteorder hexa string.
|
|---|
| 3590 | * All size and lenghts are written as single characters here.
|
|---|
| 3591 | *
|
|---|
| 3592 | * Note that no byte ordering info is emitted when <network> is true, since
|
|---|
| 3593 | * integers will be emitted in network order in that case.
|
|---|
| 3594 | */
|
|---|
| 3595 | static int magic_write(pTHX_ stcxt_t *cxt)
|
|---|
| 3596 | {
|
|---|
| 3597 | /*
|
|---|
| 3598 | * Starting with 0.6, the "use_network_order" byte flag is also used to
|
|---|
| 3599 | * indicate the version number of the binary image, encoded in the upper
|
|---|
| 3600 | * bits. The bit 0 is always used to indicate network order.
|
|---|
| 3601 | */
|
|---|
| 3602 | /*
|
|---|
| 3603 | * Starting with 0.7, a full byte is dedicated to the minor version of
|
|---|
| 3604 | * the binary format, which is incremented only when new markers are
|
|---|
| 3605 | * introduced, for instance, but when backward compatibility is preserved.
|
|---|
| 3606 | */
|
|---|
| 3607 |
|
|---|
| 3608 | /* Make these at compile time. The WRITE() macro is sufficiently complex
|
|---|
| 3609 | that it saves about 200 bytes doing it this way and only using it
|
|---|
| 3610 | once. */
|
|---|
| 3611 | static const unsigned char network_file_header[] = {
|
|---|
| 3612 | MAGICSTR_BYTES,
|
|---|
| 3613 | (STORABLE_BIN_MAJOR << 1) | 1,
|
|---|
| 3614 | STORABLE_BIN_WRITE_MINOR
|
|---|
| 3615 | };
|
|---|
| 3616 | static const unsigned char file_header[] = {
|
|---|
| 3617 | MAGICSTR_BYTES,
|
|---|
| 3618 | (STORABLE_BIN_MAJOR << 1) | 0,
|
|---|
| 3619 | STORABLE_BIN_WRITE_MINOR,
|
|---|
| 3620 | /* sizeof the array includes the 0 byte at the end: */
|
|---|
| 3621 | (char) sizeof (byteorderstr) - 1,
|
|---|
| 3622 | BYTEORDER_BYTES,
|
|---|
| 3623 | (unsigned char) sizeof(int),
|
|---|
| 3624 | (unsigned char) sizeof(long),
|
|---|
| 3625 | (unsigned char) sizeof(char *),
|
|---|
| 3626 | (unsigned char) sizeof(NV)
|
|---|
| 3627 | };
|
|---|
| 3628 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 3629 | static const unsigned char file_header_56[] = {
|
|---|
| 3630 | MAGICSTR_BYTES,
|
|---|
| 3631 | (STORABLE_BIN_MAJOR << 1) | 0,
|
|---|
| 3632 | STORABLE_BIN_WRITE_MINOR,
|
|---|
| 3633 | /* sizeof the array includes the 0 byte at the end: */
|
|---|
| 3634 | (char) sizeof (byteorderstr_56) - 1,
|
|---|
| 3635 | BYTEORDER_BYTES_56,
|
|---|
| 3636 | (unsigned char) sizeof(int),
|
|---|
| 3637 | (unsigned char) sizeof(long),
|
|---|
| 3638 | (unsigned char) sizeof(char *),
|
|---|
| 3639 | (unsigned char) sizeof(NV)
|
|---|
| 3640 | };
|
|---|
| 3641 | #endif
|
|---|
| 3642 | const unsigned char *header;
|
|---|
| 3643 | SSize_t length;
|
|---|
| 3644 |
|
|---|
| 3645 | TRACEME(("magic_write on fd=%d", cxt->fio ? PerlIO_fileno(cxt->fio) : -1));
|
|---|
| 3646 |
|
|---|
| 3647 | if (cxt->netorder) {
|
|---|
| 3648 | header = network_file_header;
|
|---|
| 3649 | length = sizeof (network_file_header);
|
|---|
| 3650 | } else {
|
|---|
| 3651 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 3652 | if (SvTRUE(perl_get_sv("Storable::interwork_56_64bit", TRUE))) {
|
|---|
| 3653 | header = file_header_56;
|
|---|
| 3654 | length = sizeof (file_header_56);
|
|---|
| 3655 | } else
|
|---|
| 3656 | #endif
|
|---|
| 3657 | {
|
|---|
| 3658 | header = file_header;
|
|---|
| 3659 | length = sizeof (file_header);
|
|---|
| 3660 | }
|
|---|
| 3661 | }
|
|---|
| 3662 |
|
|---|
| 3663 | if (!cxt->fio) {
|
|---|
| 3664 | /* sizeof the array includes the 0 byte at the end. */
|
|---|
| 3665 | header += sizeof (magicstr) - 1;
|
|---|
| 3666 | length -= sizeof (magicstr) - 1;
|
|---|
| 3667 | }
|
|---|
| 3668 |
|
|---|
| 3669 | WRITE( (unsigned char*) header, length);
|
|---|
| 3670 |
|
|---|
| 3671 | if (!cxt->netorder) {
|
|---|
| 3672 | TRACEME(("ok (magic_write byteorder = 0x%lx [%d], I%d L%d P%d D%d)",
|
|---|
| 3673 | (unsigned long) BYTEORDER, (int) sizeof (byteorderstr) - 1,
|
|---|
| 3674 | (int) sizeof(int), (int) sizeof(long),
|
|---|
| 3675 | (int) sizeof(char *), (int) sizeof(NV)));
|
|---|
| 3676 | }
|
|---|
| 3677 | return 0;
|
|---|
| 3678 | }
|
|---|
| 3679 |
|
|---|
| 3680 | /*
|
|---|
| 3681 | * do_store
|
|---|
| 3682 | *
|
|---|
| 3683 | * Common code for store operations.
|
|---|
| 3684 | *
|
|---|
| 3685 | * When memory store is requested (f = NULL) and a non null SV* is given in
|
|---|
| 3686 | * `res', it is filled with a new SV created out of the memory buffer.
|
|---|
| 3687 | *
|
|---|
| 3688 | * It is required to provide a non-null `res' when the operation type is not
|
|---|
| 3689 | * dclone() and store() is performed to memory.
|
|---|
| 3690 | */
|
|---|
| 3691 | static int do_store(
|
|---|
| 3692 | pTHX_
|
|---|
| 3693 | PerlIO *f,
|
|---|
| 3694 | SV *sv,
|
|---|
| 3695 | int optype,
|
|---|
| 3696 | int network_order,
|
|---|
| 3697 | SV **res)
|
|---|
| 3698 | {
|
|---|
| 3699 | dSTCXT;
|
|---|
| 3700 | int status;
|
|---|
| 3701 |
|
|---|
| 3702 | ASSERT(!(f == 0 && !(optype & ST_CLONE)) || res,
|
|---|
| 3703 | ("must supply result SV pointer for real recursion to memory"));
|
|---|
| 3704 |
|
|---|
| 3705 | TRACEME(("do_store (optype=%d, netorder=%d)",
|
|---|
| 3706 | optype, network_order));
|
|---|
| 3707 |
|
|---|
| 3708 | optype |= ST_STORE;
|
|---|
| 3709 |
|
|---|
| 3710 | /*
|
|---|
| 3711 | * Workaround for CROAK leak: if they enter with a "dirty" context,
|
|---|
| 3712 | * free up memory for them now.
|
|---|
| 3713 | */
|
|---|
| 3714 |
|
|---|
| 3715 | if (cxt->s_dirty)
|
|---|
| 3716 | clean_context(aTHX_ cxt);
|
|---|
| 3717 |
|
|---|
| 3718 | /*
|
|---|
| 3719 | * Now that STORABLE_xxx hooks exist, it is possible that they try to
|
|---|
| 3720 | * re-enter store() via the hooks. We need to stack contexts.
|
|---|
| 3721 | */
|
|---|
| 3722 |
|
|---|
| 3723 | if (cxt->entry)
|
|---|
| 3724 | cxt = allocate_context(aTHX_ cxt);
|
|---|
| 3725 |
|
|---|
| 3726 | cxt->entry++;
|
|---|
| 3727 |
|
|---|
| 3728 | ASSERT(cxt->entry == 1, ("starting new recursion"));
|
|---|
| 3729 | ASSERT(!cxt->s_dirty, ("clean context"));
|
|---|
| 3730 |
|
|---|
| 3731 | /*
|
|---|
| 3732 | * Ensure sv is actually a reference. From perl, we called something
|
|---|
| 3733 | * like:
|
|---|
| 3734 | * pstore(aTHX_ FILE, \@array);
|
|---|
| 3735 | * so we must get the scalar value behing that reference.
|
|---|
| 3736 | */
|
|---|
| 3737 |
|
|---|
| 3738 | if (!SvROK(sv))
|
|---|
| 3739 | CROAK(("Not a reference"));
|
|---|
| 3740 | sv = SvRV(sv); /* So follow it to know what to store */
|
|---|
| 3741 |
|
|---|
| 3742 | /*
|
|---|
| 3743 | * If we're going to store to memory, reset the buffer.
|
|---|
| 3744 | */
|
|---|
| 3745 |
|
|---|
| 3746 | if (!f)
|
|---|
| 3747 | MBUF_INIT(0);
|
|---|
| 3748 |
|
|---|
| 3749 | /*
|
|---|
| 3750 | * Prepare context and emit headers.
|
|---|
| 3751 | */
|
|---|
| 3752 |
|
|---|
| 3753 | init_store_context(aTHX_ cxt, f, optype, network_order);
|
|---|
| 3754 |
|
|---|
| 3755 | if (-1 == magic_write(aTHX_ cxt)) /* Emit magic and ILP info */
|
|---|
| 3756 | return 0; /* Error */
|
|---|
| 3757 |
|
|---|
| 3758 | /*
|
|---|
| 3759 | * Recursively store object...
|
|---|
| 3760 | */
|
|---|
| 3761 |
|
|---|
| 3762 | ASSERT(is_storing(aTHX), ("within store operation"));
|
|---|
| 3763 |
|
|---|
| 3764 | status = store(aTHX_ cxt, sv); /* Just do it! */
|
|---|
| 3765 |
|
|---|
| 3766 | /*
|
|---|
| 3767 | * If they asked for a memory store and they provided an SV pointer,
|
|---|
| 3768 | * make an SV string out of the buffer and fill their pointer.
|
|---|
| 3769 | *
|
|---|
| 3770 | * When asking for ST_REAL, it's MANDATORY for the caller to provide
|
|---|
| 3771 | * an SV, since context cleanup might free the buffer if we did recurse.
|
|---|
| 3772 | * (unless caller is dclone(), which is aware of that).
|
|---|
| 3773 | */
|
|---|
| 3774 |
|
|---|
| 3775 | if (!cxt->fio && res)
|
|---|
| 3776 | *res = mbuf2sv(aTHX);
|
|---|
| 3777 |
|
|---|
| 3778 | /*
|
|---|
| 3779 | * Final cleanup.
|
|---|
| 3780 | *
|
|---|
| 3781 | * The "root" context is never freed, since it is meant to be always
|
|---|
| 3782 | * handy for the common case where no recursion occurs at all (i.e.
|
|---|
| 3783 | * we enter store() outside of any Storable code and leave it, period).
|
|---|
| 3784 | * We know it's the "root" context because there's nothing stacked
|
|---|
| 3785 | * underneath it.
|
|---|
| 3786 | *
|
|---|
| 3787 | * OPTIMIZATION:
|
|---|
| 3788 | *
|
|---|
| 3789 | * When deep cloning, we don't free the context: doing so would force
|
|---|
| 3790 | * us to copy the data in the memory buffer. Sicne we know we're
|
|---|
| 3791 | * about to enter do_retrieve...
|
|---|
| 3792 | */
|
|---|
| 3793 |
|
|---|
| 3794 | clean_store_context(aTHX_ cxt);
|
|---|
| 3795 | if (cxt->prev && !(cxt->optype & ST_CLONE))
|
|---|
| 3796 | free_context(aTHX_ cxt);
|
|---|
| 3797 |
|
|---|
| 3798 | TRACEME(("do_store returns %d", status));
|
|---|
| 3799 |
|
|---|
| 3800 | return status == 0;
|
|---|
| 3801 | }
|
|---|
| 3802 |
|
|---|
| 3803 | /*
|
|---|
| 3804 | * pstore
|
|---|
| 3805 | *
|
|---|
| 3806 | * Store the transitive data closure of given object to disk.
|
|---|
| 3807 | * Returns 0 on error, a true value otherwise.
|
|---|
| 3808 | */
|
|---|
| 3809 | int pstore(pTHX_ PerlIO *f, SV *sv)
|
|---|
| 3810 | {
|
|---|
| 3811 | TRACEME(("pstore"));
|
|---|
| 3812 | return do_store(aTHX_ f, sv, 0, FALSE, (SV**) 0);
|
|---|
| 3813 |
|
|---|
| 3814 | }
|
|---|
| 3815 |
|
|---|
| 3816 | /*
|
|---|
| 3817 | * net_pstore
|
|---|
| 3818 | *
|
|---|
| 3819 | * Same as pstore(), but network order is used for integers and doubles are
|
|---|
| 3820 | * emitted as strings.
|
|---|
| 3821 | */
|
|---|
| 3822 | int net_pstore(pTHX_ PerlIO *f, SV *sv)
|
|---|
| 3823 | {
|
|---|
| 3824 | TRACEME(("net_pstore"));
|
|---|
| 3825 | return do_store(aTHX_ f, sv, 0, TRUE, (SV**) 0);
|
|---|
| 3826 | }
|
|---|
| 3827 |
|
|---|
| 3828 | /***
|
|---|
| 3829 | *** Memory stores.
|
|---|
| 3830 | ***/
|
|---|
| 3831 |
|
|---|
| 3832 | /*
|
|---|
| 3833 | * mbuf2sv
|
|---|
| 3834 | *
|
|---|
| 3835 | * Build a new SV out of the content of the internal memory buffer.
|
|---|
| 3836 | */
|
|---|
| 3837 | static SV *mbuf2sv(pTHX)
|
|---|
| 3838 | {
|
|---|
| 3839 | dSTCXT;
|
|---|
| 3840 |
|
|---|
| 3841 | return newSVpv(mbase, MBUF_SIZE());
|
|---|
| 3842 | }
|
|---|
| 3843 |
|
|---|
| 3844 | /*
|
|---|
| 3845 | * mstore
|
|---|
| 3846 | *
|
|---|
| 3847 | * Store the transitive data closure of given object to memory.
|
|---|
| 3848 | * Returns undef on error, a scalar value containing the data otherwise.
|
|---|
| 3849 | */
|
|---|
| 3850 | SV *mstore(pTHX_ SV *sv)
|
|---|
| 3851 | {
|
|---|
| 3852 | SV *out;
|
|---|
| 3853 |
|
|---|
| 3854 | TRACEME(("mstore"));
|
|---|
| 3855 |
|
|---|
| 3856 | if (!do_store(aTHX_ (PerlIO*) 0, sv, 0, FALSE, &out))
|
|---|
| 3857 | return &PL_sv_undef;
|
|---|
| 3858 |
|
|---|
| 3859 | return out;
|
|---|
| 3860 | }
|
|---|
| 3861 |
|
|---|
| 3862 | /*
|
|---|
| 3863 | * net_mstore
|
|---|
| 3864 | *
|
|---|
| 3865 | * Same as mstore(), but network order is used for integers and doubles are
|
|---|
| 3866 | * emitted as strings.
|
|---|
| 3867 | */
|
|---|
| 3868 | SV *net_mstore(pTHX_ SV *sv)
|
|---|
| 3869 | {
|
|---|
| 3870 | SV *out;
|
|---|
| 3871 |
|
|---|
| 3872 | TRACEME(("net_mstore"));
|
|---|
| 3873 |
|
|---|
| 3874 | if (!do_store(aTHX_ (PerlIO*) 0, sv, 0, TRUE, &out))
|
|---|
| 3875 | return &PL_sv_undef;
|
|---|
| 3876 |
|
|---|
| 3877 | return out;
|
|---|
| 3878 | }
|
|---|
| 3879 |
|
|---|
| 3880 | /***
|
|---|
| 3881 | *** Specific retrieve callbacks.
|
|---|
| 3882 | ***/
|
|---|
| 3883 |
|
|---|
| 3884 | /*
|
|---|
| 3885 | * retrieve_other
|
|---|
| 3886 | *
|
|---|
| 3887 | * Return an error via croak, since it is not possible that we get here
|
|---|
| 3888 | * under normal conditions, when facing a file produced via pstore().
|
|---|
| 3889 | */
|
|---|
| 3890 | static SV *retrieve_other(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 3891 | {
|
|---|
| 3892 | if (
|
|---|
| 3893 | cxt->ver_major != STORABLE_BIN_MAJOR &&
|
|---|
| 3894 | cxt->ver_minor != STORABLE_BIN_MINOR
|
|---|
| 3895 | ) {
|
|---|
| 3896 | CROAK(("Corrupted storable %s (binary v%d.%d), current is v%d.%d",
|
|---|
| 3897 | cxt->fio ? "file" : "string",
|
|---|
| 3898 | cxt->ver_major, cxt->ver_minor,
|
|---|
| 3899 | STORABLE_BIN_MAJOR, STORABLE_BIN_MINOR));
|
|---|
| 3900 | } else {
|
|---|
| 3901 | CROAK(("Corrupted storable %s (binary v%d.%d)",
|
|---|
| 3902 | cxt->fio ? "file" : "string",
|
|---|
| 3903 | cxt->ver_major, cxt->ver_minor));
|
|---|
| 3904 | }
|
|---|
| 3905 |
|
|---|
| 3906 | return (SV *) 0; /* Just in case */
|
|---|
| 3907 | }
|
|---|
| 3908 |
|
|---|
| 3909 | /*
|
|---|
| 3910 | * retrieve_idx_blessed
|
|---|
| 3911 | *
|
|---|
| 3912 | * Layout is SX_IX_BLESS <index> <object> with SX_IX_BLESS already read.
|
|---|
| 3913 | * <index> can be coded on either 1 or 5 bytes.
|
|---|
| 3914 | */
|
|---|
| 3915 | static SV *retrieve_idx_blessed(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 3916 | {
|
|---|
| 3917 | I32 idx;
|
|---|
| 3918 | char *classname;
|
|---|
| 3919 | SV **sva;
|
|---|
| 3920 | SV *sv;
|
|---|
| 3921 |
|
|---|
| 3922 | TRACEME(("retrieve_idx_blessed (#%d)", cxt->tagnum));
|
|---|
| 3923 | ASSERT(!cname, ("no bless-into class given here, got %s", cname));
|
|---|
| 3924 |
|
|---|
| 3925 | GETMARK(idx); /* Index coded on a single char? */
|
|---|
| 3926 | if (idx & 0x80)
|
|---|
| 3927 | RLEN(idx);
|
|---|
| 3928 |
|
|---|
| 3929 | /*
|
|---|
| 3930 | * Fetch classname in `aclass'
|
|---|
| 3931 | */
|
|---|
| 3932 |
|
|---|
| 3933 | sva = av_fetch(cxt->aclass, idx, FALSE);
|
|---|
| 3934 | if (!sva)
|
|---|
| 3935 | CROAK(("Class name #%"IVdf" should have been seen already", (IV) idx));
|
|---|
| 3936 |
|
|---|
| 3937 | classname = SvPVX(*sva); /* We know it's a PV, by construction */
|
|---|
| 3938 |
|
|---|
| 3939 | TRACEME(("class ID %d => %s", idx, classname));
|
|---|
| 3940 |
|
|---|
| 3941 | /*
|
|---|
| 3942 | * Retrieve object and bless it.
|
|---|
| 3943 | */
|
|---|
| 3944 |
|
|---|
| 3945 | sv = retrieve(aTHX_ cxt, classname); /* First SV which is SEEN will be blessed */
|
|---|
| 3946 |
|
|---|
| 3947 | return sv;
|
|---|
| 3948 | }
|
|---|
| 3949 |
|
|---|
| 3950 | /*
|
|---|
| 3951 | * retrieve_blessed
|
|---|
| 3952 | *
|
|---|
| 3953 | * Layout is SX_BLESS <len> <classname> <object> with SX_BLESS already read.
|
|---|
| 3954 | * <len> can be coded on either 1 or 5 bytes.
|
|---|
| 3955 | */
|
|---|
| 3956 | static SV *retrieve_blessed(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 3957 | {
|
|---|
| 3958 | I32 len;
|
|---|
| 3959 | SV *sv;
|
|---|
| 3960 | char buf[LG_BLESS + 1]; /* Avoid malloc() if possible */
|
|---|
| 3961 | char *classname = buf;
|
|---|
| 3962 |
|
|---|
| 3963 | TRACEME(("retrieve_blessed (#%d)", cxt->tagnum));
|
|---|
| 3964 | ASSERT(!cname, ("no bless-into class given here, got %s", cname));
|
|---|
| 3965 |
|
|---|
| 3966 | /*
|
|---|
| 3967 | * Decode class name length and read that name.
|
|---|
| 3968 | *
|
|---|
| 3969 | * Short classnames have two advantages: their length is stored on one
|
|---|
| 3970 | * single byte, and the string can be read on the stack.
|
|---|
| 3971 | */
|
|---|
| 3972 |
|
|---|
| 3973 | GETMARK(len); /* Length coded on a single char? */
|
|---|
| 3974 | if (len & 0x80) {
|
|---|
| 3975 | RLEN(len);
|
|---|
| 3976 | TRACEME(("** allocating %d bytes for class name", len+1));
|
|---|
| 3977 | New(10003, classname, len+1, char);
|
|---|
| 3978 | }
|
|---|
| 3979 | READ(classname, len);
|
|---|
| 3980 | classname[len] = '\0'; /* Mark string end */
|
|---|
| 3981 |
|
|---|
| 3982 | /*
|
|---|
| 3983 | * It's a new classname, otherwise it would have been an SX_IX_BLESS.
|
|---|
| 3984 | */
|
|---|
| 3985 |
|
|---|
| 3986 | TRACEME(("new class name \"%s\" will bear ID = %d", classname, cxt->classnum));
|
|---|
| 3987 |
|
|---|
| 3988 | if (!av_store(cxt->aclass, cxt->classnum++, newSVpvn(classname, len)))
|
|---|
| 3989 | return (SV *) 0;
|
|---|
| 3990 |
|
|---|
| 3991 | /*
|
|---|
| 3992 | * Retrieve object and bless it.
|
|---|
| 3993 | */
|
|---|
| 3994 |
|
|---|
| 3995 | sv = retrieve(aTHX_ cxt, classname); /* First SV which is SEEN will be blessed */
|
|---|
| 3996 | if (classname != buf)
|
|---|
| 3997 | Safefree(classname);
|
|---|
| 3998 |
|
|---|
| 3999 | return sv;
|
|---|
| 4000 | }
|
|---|
| 4001 |
|
|---|
| 4002 | /*
|
|---|
| 4003 | * retrieve_hook
|
|---|
| 4004 | *
|
|---|
| 4005 | * Layout: SX_HOOK <flags> <len> <classname> <len2> <str> [<len3> <object-IDs>]
|
|---|
| 4006 | * with leading mark already read, as usual.
|
|---|
| 4007 | *
|
|---|
| 4008 | * When recursion was involved during serialization of the object, there
|
|---|
| 4009 | * is an unknown amount of serialized objects after the SX_HOOK mark. Until
|
|---|
| 4010 | * we reach a <flags> marker with the recursion bit cleared.
|
|---|
| 4011 | *
|
|---|
| 4012 | * If the first <flags> byte contains a type of SHT_EXTRA, then the real type
|
|---|
| 4013 | * is held in the <extra> byte, and if the object is tied, the serialized
|
|---|
| 4014 | * magic object comes at the very end:
|
|---|
| 4015 | *
|
|---|
| 4016 | * SX_HOOK <flags> <extra> ... [<len3> <object-IDs>] <magic object>
|
|---|
| 4017 | *
|
|---|
| 4018 | * This means the STORABLE_thaw hook will NOT get a tied variable during its
|
|---|
| 4019 | * processing (since we won't have seen the magic object by the time the hook
|
|---|
| 4020 | * is called). See comments below for why it was done that way.
|
|---|
| 4021 | */
|
|---|
| 4022 | static SV *retrieve_hook(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4023 | {
|
|---|
| 4024 | I32 len;
|
|---|
| 4025 | char buf[LG_BLESS + 1]; /* Avoid malloc() if possible */
|
|---|
| 4026 | char *classname = buf;
|
|---|
| 4027 | unsigned int flags;
|
|---|
| 4028 | I32 len2;
|
|---|
| 4029 | SV *frozen;
|
|---|
| 4030 | I32 len3 = 0;
|
|---|
| 4031 | AV *av = 0;
|
|---|
| 4032 | SV *hook;
|
|---|
| 4033 | SV *sv;
|
|---|
| 4034 | SV *rv;
|
|---|
| 4035 | GV *attach;
|
|---|
| 4036 | int obj_type;
|
|---|
| 4037 | int clone = cxt->optype & ST_CLONE;
|
|---|
| 4038 | char mtype = '\0';
|
|---|
| 4039 | unsigned int extra_type = 0;
|
|---|
| 4040 |
|
|---|
| 4041 | TRACEME(("retrieve_hook (#%d)", cxt->tagnum));
|
|---|
| 4042 | ASSERT(!cname, ("no bless-into class given here, got %s", cname));
|
|---|
| 4043 |
|
|---|
| 4044 | /*
|
|---|
| 4045 | * Read flags, which tell us about the type, and whether we need to recurse.
|
|---|
| 4046 | */
|
|---|
| 4047 |
|
|---|
| 4048 | GETMARK(flags);
|
|---|
| 4049 |
|
|---|
| 4050 | /*
|
|---|
| 4051 | * Create the (empty) object, and mark it as seen.
|
|---|
| 4052 | *
|
|---|
| 4053 | * This must be done now, because tags are incremented, and during
|
|---|
| 4054 | * serialization, the object tag was affected before recursion could
|
|---|
| 4055 | * take place.
|
|---|
| 4056 | */
|
|---|
| 4057 |
|
|---|
| 4058 | obj_type = flags & SHF_TYPE_MASK;
|
|---|
| 4059 | switch (obj_type) {
|
|---|
| 4060 | case SHT_SCALAR:
|
|---|
| 4061 | sv = newSV(0);
|
|---|
| 4062 | break;
|
|---|
| 4063 | case SHT_ARRAY:
|
|---|
| 4064 | sv = (SV *) newAV();
|
|---|
| 4065 | break;
|
|---|
| 4066 | case SHT_HASH:
|
|---|
| 4067 | sv = (SV *) newHV();
|
|---|
| 4068 | break;
|
|---|
| 4069 | case SHT_EXTRA:
|
|---|
| 4070 | /*
|
|---|
| 4071 | * Read <extra> flag to know the type of the object.
|
|---|
| 4072 | * Record associated magic type for later.
|
|---|
| 4073 | */
|
|---|
| 4074 | GETMARK(extra_type);
|
|---|
| 4075 | switch (extra_type) {
|
|---|
| 4076 | case SHT_TSCALAR:
|
|---|
| 4077 | sv = newSV(0);
|
|---|
| 4078 | mtype = 'q';
|
|---|
| 4079 | break;
|
|---|
| 4080 | case SHT_TARRAY:
|
|---|
| 4081 | sv = (SV *) newAV();
|
|---|
| 4082 | mtype = 'P';
|
|---|
| 4083 | break;
|
|---|
| 4084 | case SHT_THASH:
|
|---|
| 4085 | sv = (SV *) newHV();
|
|---|
| 4086 | mtype = 'P';
|
|---|
| 4087 | break;
|
|---|
| 4088 | default:
|
|---|
| 4089 | return retrieve_other(aTHX_ cxt, 0); /* Let it croak */
|
|---|
| 4090 | }
|
|---|
| 4091 | break;
|
|---|
| 4092 | default:
|
|---|
| 4093 | return retrieve_other(aTHX_ cxt, 0); /* Let it croak */
|
|---|
| 4094 | }
|
|---|
| 4095 | SEEN(sv, 0, 0); /* Don't bless yet */
|
|---|
| 4096 |
|
|---|
| 4097 | /*
|
|---|
| 4098 | * Whilst flags tell us to recurse, do so.
|
|---|
| 4099 | *
|
|---|
| 4100 | * We don't need to remember the addresses returned by retrieval, because
|
|---|
| 4101 | * all the references will be obtained through indirection via the object
|
|---|
| 4102 | * tags in the object-ID list.
|
|---|
| 4103 | *
|
|---|
| 4104 | * We need to decrement the reference count for these objects
|
|---|
| 4105 | * because, if the user doesn't save a reference to them in the hook,
|
|---|
| 4106 | * they must be freed when this context is cleaned.
|
|---|
| 4107 | */
|
|---|
| 4108 |
|
|---|
| 4109 | while (flags & SHF_NEED_RECURSE) {
|
|---|
| 4110 | TRACEME(("retrieve_hook recursing..."));
|
|---|
| 4111 | rv = retrieve(aTHX_ cxt, 0);
|
|---|
| 4112 | if (!rv)
|
|---|
| 4113 | return (SV *) 0;
|
|---|
| 4114 | SvREFCNT_dec(rv);
|
|---|
| 4115 | TRACEME(("retrieve_hook back with rv=0x%"UVxf,
|
|---|
| 4116 | PTR2UV(rv)));
|
|---|
| 4117 | GETMARK(flags);
|
|---|
| 4118 | }
|
|---|
| 4119 |
|
|---|
| 4120 | if (flags & SHF_IDX_CLASSNAME) {
|
|---|
| 4121 | SV **sva;
|
|---|
| 4122 | I32 idx;
|
|---|
| 4123 |
|
|---|
| 4124 | /*
|
|---|
| 4125 | * Fetch index from `aclass'
|
|---|
| 4126 | */
|
|---|
| 4127 |
|
|---|
| 4128 | if (flags & SHF_LARGE_CLASSLEN)
|
|---|
| 4129 | RLEN(idx);
|
|---|
| 4130 | else
|
|---|
| 4131 | GETMARK(idx);
|
|---|
| 4132 |
|
|---|
| 4133 | sva = av_fetch(cxt->aclass, idx, FALSE);
|
|---|
| 4134 | if (!sva)
|
|---|
| 4135 | CROAK(("Class name #%"IVdf" should have been seen already",
|
|---|
| 4136 | (IV) idx));
|
|---|
| 4137 |
|
|---|
| 4138 | classname = SvPVX(*sva); /* We know it's a PV, by construction */
|
|---|
| 4139 | TRACEME(("class ID %d => %s", idx, classname));
|
|---|
| 4140 |
|
|---|
| 4141 | } else {
|
|---|
| 4142 | /*
|
|---|
| 4143 | * Decode class name length and read that name.
|
|---|
| 4144 | *
|
|---|
| 4145 | * NOTA BENE: even if the length is stored on one byte, we don't read
|
|---|
| 4146 | * on the stack. Just like retrieve_blessed(), we limit the name to
|
|---|
| 4147 | * LG_BLESS bytes. This is an arbitrary decision.
|
|---|
| 4148 | */
|
|---|
| 4149 |
|
|---|
| 4150 | if (flags & SHF_LARGE_CLASSLEN)
|
|---|
| 4151 | RLEN(len);
|
|---|
| 4152 | else
|
|---|
| 4153 | GETMARK(len);
|
|---|
| 4154 |
|
|---|
| 4155 | if (len > LG_BLESS) {
|
|---|
| 4156 | TRACEME(("** allocating %d bytes for class name", len+1));
|
|---|
| 4157 | New(10003, classname, len+1, char);
|
|---|
| 4158 | }
|
|---|
| 4159 |
|
|---|
| 4160 | READ(classname, len);
|
|---|
| 4161 | classname[len] = '\0'; /* Mark string end */
|
|---|
| 4162 |
|
|---|
| 4163 | /*
|
|---|
| 4164 | * Record new classname.
|
|---|
| 4165 | */
|
|---|
| 4166 |
|
|---|
| 4167 | if (!av_store(cxt->aclass, cxt->classnum++, newSVpvn(classname, len)))
|
|---|
| 4168 | return (SV *) 0;
|
|---|
| 4169 | }
|
|---|
| 4170 |
|
|---|
| 4171 | TRACEME(("class name: %s", classname));
|
|---|
| 4172 |
|
|---|
| 4173 | /*
|
|---|
| 4174 | * Decode user-frozen string length and read it in an SV.
|
|---|
| 4175 | *
|
|---|
| 4176 | * For efficiency reasons, we read data directly into the SV buffer.
|
|---|
| 4177 | * To understand that code, read retrieve_scalar()
|
|---|
| 4178 | */
|
|---|
| 4179 |
|
|---|
| 4180 | if (flags & SHF_LARGE_STRLEN)
|
|---|
| 4181 | RLEN(len2);
|
|---|
| 4182 | else
|
|---|
| 4183 | GETMARK(len2);
|
|---|
| 4184 |
|
|---|
| 4185 | frozen = NEWSV(10002, len2);
|
|---|
| 4186 | if (len2) {
|
|---|
| 4187 | SAFEREAD(SvPVX(frozen), len2, frozen);
|
|---|
| 4188 | SvCUR_set(frozen, len2);
|
|---|
| 4189 | *SvEND(frozen) = '\0';
|
|---|
| 4190 | }
|
|---|
| 4191 | (void) SvPOK_only(frozen); /* Validates string pointer */
|
|---|
| 4192 | if (cxt->s_tainted) /* Is input source tainted? */
|
|---|
| 4193 | SvTAINT(frozen);
|
|---|
| 4194 |
|
|---|
| 4195 | TRACEME(("frozen string: %d bytes", len2));
|
|---|
| 4196 |
|
|---|
| 4197 | /*
|
|---|
| 4198 | * Decode object-ID list length, if present.
|
|---|
| 4199 | */
|
|---|
| 4200 |
|
|---|
| 4201 | if (flags & SHF_HAS_LIST) {
|
|---|
| 4202 | if (flags & SHF_LARGE_LISTLEN)
|
|---|
| 4203 | RLEN(len3);
|
|---|
| 4204 | else
|
|---|
| 4205 | GETMARK(len3);
|
|---|
| 4206 | if (len3) {
|
|---|
| 4207 | av = newAV();
|
|---|
| 4208 | av_extend(av, len3 + 1); /* Leave room for [0] */
|
|---|
| 4209 | AvFILLp(av) = len3; /* About to be filled anyway */
|
|---|
| 4210 | }
|
|---|
| 4211 | }
|
|---|
| 4212 |
|
|---|
| 4213 | TRACEME(("has %d object IDs to link", len3));
|
|---|
| 4214 |
|
|---|
| 4215 | /*
|
|---|
| 4216 | * Read object-ID list into array.
|
|---|
| 4217 | * Because we pre-extended it, we can cheat and fill it manually.
|
|---|
| 4218 | *
|
|---|
| 4219 | * We read object tags and we can convert them into SV* on the fly
|
|---|
| 4220 | * because we know all the references listed in there (as tags)
|
|---|
| 4221 | * have been already serialized, hence we have a valid correspondance
|
|---|
| 4222 | * between each of those tags and the recreated SV.
|
|---|
| 4223 | */
|
|---|
| 4224 |
|
|---|
| 4225 | if (av) {
|
|---|
| 4226 | SV **ary = AvARRAY(av);
|
|---|
| 4227 | int i;
|
|---|
| 4228 | for (i = 1; i <= len3; i++) { /* We leave [0] alone */
|
|---|
| 4229 | I32 tag;
|
|---|
| 4230 | SV **svh;
|
|---|
| 4231 | SV *xsv;
|
|---|
| 4232 |
|
|---|
| 4233 | READ_I32(tag);
|
|---|
| 4234 | tag = ntohl(tag);
|
|---|
| 4235 | svh = av_fetch(cxt->aseen, tag, FALSE);
|
|---|
| 4236 | if (!svh) {
|
|---|
| 4237 | if (tag == cxt->where_is_undef) {
|
|---|
| 4238 | /* av_fetch uses PL_sv_undef internally, hence this
|
|---|
| 4239 | somewhat gruesome hack. */
|
|---|
| 4240 | xsv = &PL_sv_undef;
|
|---|
| 4241 | svh = &xsv;
|
|---|
| 4242 | } else {
|
|---|
| 4243 | CROAK(("Object #%"IVdf" should have been retrieved already",
|
|---|
| 4244 | (IV) tag));
|
|---|
| 4245 | }
|
|---|
| 4246 | }
|
|---|
| 4247 | xsv = *svh;
|
|---|
| 4248 | ary[i] = SvREFCNT_inc(xsv);
|
|---|
| 4249 | }
|
|---|
| 4250 | }
|
|---|
| 4251 |
|
|---|
| 4252 | /*
|
|---|
| 4253 | * Bless the object and look up the STORABLE_thaw hook.
|
|---|
| 4254 | */
|
|---|
| 4255 |
|
|---|
| 4256 | BLESS(sv, classname);
|
|---|
| 4257 |
|
|---|
| 4258 | /* Handle attach case; again can't use pkg_can because it only
|
|---|
| 4259 | * caches one method */
|
|---|
| 4260 | attach = gv_fetchmethod_autoload(SvSTASH(sv), "STORABLE_attach", FALSE);
|
|---|
| 4261 | if (attach && isGV(attach)) {
|
|---|
| 4262 | SV* attached;
|
|---|
| 4263 | SV* attach_hook = newRV((SV*) GvCV(attach));
|
|---|
| 4264 |
|
|---|
| 4265 | if (av)
|
|---|
| 4266 | CROAK(("STORABLE_attach called with unexpected references"));
|
|---|
| 4267 | av = newAV();
|
|---|
| 4268 | av_extend(av, 1);
|
|---|
| 4269 | AvFILLp(av) = 0;
|
|---|
| 4270 | AvARRAY(av)[0] = SvREFCNT_inc(frozen);
|
|---|
| 4271 | rv = newSVpv(classname, 0);
|
|---|
| 4272 | attached = scalar_call(aTHX_ rv, attach_hook, clone, av, G_SCALAR);
|
|---|
| 4273 | if (attached &&
|
|---|
| 4274 | SvROK(attached) &&
|
|---|
| 4275 | sv_derived_from(attached, classname))
|
|---|
| 4276 | return SvRV(attached);
|
|---|
| 4277 | CROAK(("STORABLE_attach did not return a %s object", classname));
|
|---|
| 4278 | }
|
|---|
| 4279 |
|
|---|
| 4280 | hook = pkg_can(aTHX_ cxt->hook, SvSTASH(sv), "STORABLE_thaw");
|
|---|
| 4281 | if (!hook) {
|
|---|
| 4282 | /*
|
|---|
| 4283 | * Hook not found. Maybe they did not require the module where this
|
|---|
| 4284 | * hook is defined yet?
|
|---|
| 4285 | *
|
|---|
| 4286 | * If the require below succeeds, we'll be able to find the hook.
|
|---|
| 4287 | * Still, it only works reliably when each class is defined in a
|
|---|
| 4288 | * file of its own.
|
|---|
| 4289 | */
|
|---|
| 4290 |
|
|---|
| 4291 | SV *psv = newSVpvn("require ", 8);
|
|---|
| 4292 | sv_catpv(psv, classname);
|
|---|
| 4293 |
|
|---|
| 4294 | TRACEME(("No STORABLE_thaw defined for objects of class %s", classname));
|
|---|
| 4295 | TRACEME(("Going to require module '%s' with '%s'", classname, SvPVX(psv)));
|
|---|
| 4296 |
|
|---|
| 4297 | perl_eval_sv(psv, G_DISCARD);
|
|---|
| 4298 | sv_free(psv);
|
|---|
| 4299 |
|
|---|
| 4300 | /*
|
|---|
| 4301 | * We cache results of pkg_can, so we need to uncache before attempting
|
|---|
| 4302 | * the lookup again.
|
|---|
| 4303 | */
|
|---|
| 4304 |
|
|---|
| 4305 | pkg_uncache(aTHX_ cxt->hook, SvSTASH(sv), "STORABLE_thaw");
|
|---|
| 4306 | hook = pkg_can(aTHX_ cxt->hook, SvSTASH(sv), "STORABLE_thaw");
|
|---|
| 4307 |
|
|---|
| 4308 | if (!hook)
|
|---|
| 4309 | CROAK(("No STORABLE_thaw defined for objects of class %s "
|
|---|
| 4310 | "(even after a \"require %s;\")", classname, classname));
|
|---|
| 4311 | }
|
|---|
| 4312 |
|
|---|
| 4313 | /*
|
|---|
| 4314 | * If we don't have an `av' yet, prepare one.
|
|---|
| 4315 | * Then insert the frozen string as item [0].
|
|---|
| 4316 | */
|
|---|
| 4317 |
|
|---|
| 4318 | if (!av) {
|
|---|
| 4319 | av = newAV();
|
|---|
| 4320 | av_extend(av, 1);
|
|---|
| 4321 | AvFILLp(av) = 0;
|
|---|
| 4322 | }
|
|---|
| 4323 | AvARRAY(av)[0] = SvREFCNT_inc(frozen);
|
|---|
| 4324 |
|
|---|
| 4325 | /*
|
|---|
| 4326 | * Call the hook as:
|
|---|
| 4327 | *
|
|---|
| 4328 | * $object->STORABLE_thaw($cloning, $frozen, @refs);
|
|---|
| 4329 | *
|
|---|
| 4330 | * where $object is our blessed (empty) object, $cloning is a boolean
|
|---|
| 4331 | * telling whether we're running a deep clone, $frozen is the frozen
|
|---|
| 4332 | * string the user gave us in his serializing hook, and @refs, which may
|
|---|
| 4333 | * be empty, is the list of extra references he returned along for us
|
|---|
| 4334 | * to serialize.
|
|---|
| 4335 | *
|
|---|
| 4336 | * In effect, the hook is an alternate creation routine for the class,
|
|---|
| 4337 | * the object itself being already created by the runtime.
|
|---|
| 4338 | */
|
|---|
| 4339 |
|
|---|
| 4340 | TRACEME(("calling STORABLE_thaw on %s at 0x%"UVxf" (%"IVdf" args)",
|
|---|
| 4341 | classname, PTR2UV(sv), (IV) AvFILLp(av) + 1));
|
|---|
| 4342 |
|
|---|
| 4343 | rv = newRV(sv);
|
|---|
| 4344 | (void) scalar_call(aTHX_ rv, hook, clone, av, G_SCALAR|G_DISCARD);
|
|---|
| 4345 | SvREFCNT_dec(rv);
|
|---|
| 4346 |
|
|---|
| 4347 | /*
|
|---|
| 4348 | * Final cleanup.
|
|---|
| 4349 | */
|
|---|
| 4350 |
|
|---|
| 4351 | SvREFCNT_dec(frozen);
|
|---|
| 4352 | av_undef(av);
|
|---|
| 4353 | sv_free((SV *) av);
|
|---|
| 4354 | if (!(flags & SHF_IDX_CLASSNAME) && classname != buf)
|
|---|
| 4355 | Safefree(classname);
|
|---|
| 4356 |
|
|---|
| 4357 | /*
|
|---|
| 4358 | * If we had an <extra> type, then the object was not as simple, and
|
|---|
| 4359 | * we need to restore extra magic now.
|
|---|
| 4360 | */
|
|---|
| 4361 |
|
|---|
| 4362 | if (!extra_type)
|
|---|
| 4363 | return sv;
|
|---|
| 4364 |
|
|---|
| 4365 | TRACEME(("retrieving magic object for 0x%"UVxf"...", PTR2UV(sv)));
|
|---|
| 4366 |
|
|---|
| 4367 | rv = retrieve(aTHX_ cxt, 0); /* Retrieve <magic object> */
|
|---|
| 4368 |
|
|---|
| 4369 | TRACEME(("restoring the magic object 0x%"UVxf" part of 0x%"UVxf,
|
|---|
| 4370 | PTR2UV(rv), PTR2UV(sv)));
|
|---|
| 4371 |
|
|---|
| 4372 | switch (extra_type) {
|
|---|
| 4373 | case SHT_TSCALAR:
|
|---|
| 4374 | sv_upgrade(sv, SVt_PVMG);
|
|---|
| 4375 | break;
|
|---|
| 4376 | case SHT_TARRAY:
|
|---|
| 4377 | sv_upgrade(sv, SVt_PVAV);
|
|---|
| 4378 | AvREAL_off((AV *)sv);
|
|---|
| 4379 | break;
|
|---|
| 4380 | case SHT_THASH:
|
|---|
| 4381 | sv_upgrade(sv, SVt_PVHV);
|
|---|
| 4382 | break;
|
|---|
| 4383 | default:
|
|---|
| 4384 | CROAK(("Forgot to deal with extra type %d", extra_type));
|
|---|
| 4385 | break;
|
|---|
| 4386 | }
|
|---|
| 4387 |
|
|---|
| 4388 | /*
|
|---|
| 4389 | * Adding the magic only now, well after the STORABLE_thaw hook was called
|
|---|
| 4390 | * means the hook cannot know it deals with an object whose variable is
|
|---|
| 4391 | * tied. But this is happening when retrieving $o in the following case:
|
|---|
| 4392 | *
|
|---|
| 4393 | * my %h;
|
|---|
| 4394 | * tie %h, 'FOO';
|
|---|
| 4395 | * my $o = bless \%h, 'BAR';
|
|---|
| 4396 | *
|
|---|
| 4397 | * The 'BAR' class is NOT the one where %h is tied into. Therefore, as
|
|---|
| 4398 | * far as the 'BAR' class is concerned, the fact that %h is not a REAL
|
|---|
| 4399 | * hash but a tied one should not matter at all, and remain transparent.
|
|---|
| 4400 | * This means the magic must be restored by Storable AFTER the hook is
|
|---|
| 4401 | * called.
|
|---|
| 4402 | *
|
|---|
| 4403 | * That looks very reasonable to me, but then I've come up with this
|
|---|
| 4404 | * after a bug report from David Nesting, who was trying to store such
|
|---|
| 4405 | * an object and caused Storable to fail. And unfortunately, it was
|
|---|
| 4406 | * also the easiest way to retrofit support for blessed ref to tied objects
|
|---|
| 4407 | * into the existing design. -- RAM, 17/02/2001
|
|---|
| 4408 | */
|
|---|
| 4409 |
|
|---|
| 4410 | sv_magic(sv, rv, mtype, Nullch, 0);
|
|---|
| 4411 | SvREFCNT_dec(rv); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4412 |
|
|---|
| 4413 | return sv;
|
|---|
| 4414 | }
|
|---|
| 4415 |
|
|---|
| 4416 | /*
|
|---|
| 4417 | * retrieve_ref
|
|---|
| 4418 | *
|
|---|
| 4419 | * Retrieve reference to some other scalar.
|
|---|
| 4420 | * Layout is SX_REF <object>, with SX_REF already read.
|
|---|
| 4421 | */
|
|---|
| 4422 | static SV *retrieve_ref(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4423 | {
|
|---|
| 4424 | SV *rv;
|
|---|
| 4425 | SV *sv;
|
|---|
| 4426 |
|
|---|
| 4427 | TRACEME(("retrieve_ref (#%d)", cxt->tagnum));
|
|---|
| 4428 |
|
|---|
| 4429 | /*
|
|---|
| 4430 | * We need to create the SV that holds the reference to the yet-to-retrieve
|
|---|
| 4431 | * object now, so that we may record the address in the seen table.
|
|---|
| 4432 | * Otherwise, if the object to retrieve references us, we won't be able
|
|---|
| 4433 | * to resolve the SX_OBJECT we'll see at that point! Hence we cannot
|
|---|
| 4434 | * do the retrieve first and use rv = newRV(sv) since it will be too late
|
|---|
| 4435 | * for SEEN() recording.
|
|---|
| 4436 | */
|
|---|
| 4437 |
|
|---|
| 4438 | rv = NEWSV(10002, 0);
|
|---|
| 4439 | SEEN(rv, cname, 0); /* Will return if rv is null */
|
|---|
| 4440 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4441 | if (!sv)
|
|---|
| 4442 | return (SV *) 0; /* Failed */
|
|---|
| 4443 |
|
|---|
| 4444 | /*
|
|---|
| 4445 | * WARNING: breaks RV encapsulation.
|
|---|
| 4446 | *
|
|---|
| 4447 | * Now for the tricky part. We have to upgrade our existing SV, so that
|
|---|
| 4448 | * it is now an RV on sv... Again, we cheat by duplicating the code
|
|---|
| 4449 | * held in newSVrv(), since we already got our SV from retrieve().
|
|---|
| 4450 | *
|
|---|
| 4451 | * We don't say:
|
|---|
| 4452 | *
|
|---|
| 4453 | * SvRV(rv) = SvREFCNT_inc(sv);
|
|---|
| 4454 | *
|
|---|
| 4455 | * here because the reference count we got from retrieve() above is
|
|---|
| 4456 | * already correct: if the object was retrieved from the file, then
|
|---|
| 4457 | * its reference count is one. Otherwise, if it was retrieved via
|
|---|
| 4458 | * an SX_OBJECT indication, a ref count increment was done.
|
|---|
| 4459 | */
|
|---|
| 4460 |
|
|---|
| 4461 | if (cname) {
|
|---|
| 4462 | /* No need to do anything, as rv will already be PVMG. */
|
|---|
| 4463 | assert (SvTYPE(rv) >= SVt_RV);
|
|---|
| 4464 | } else {
|
|---|
| 4465 | sv_upgrade(rv, SVt_RV);
|
|---|
| 4466 | }
|
|---|
| 4467 |
|
|---|
| 4468 | SvRV_set(rv, sv); /* $rv = \$sv */
|
|---|
| 4469 | SvROK_on(rv);
|
|---|
| 4470 |
|
|---|
| 4471 | TRACEME(("ok (retrieve_ref at 0x%"UVxf")", PTR2UV(rv)));
|
|---|
| 4472 |
|
|---|
| 4473 | return rv;
|
|---|
| 4474 | }
|
|---|
| 4475 |
|
|---|
| 4476 | /*
|
|---|
| 4477 | * retrieve_weakref
|
|---|
| 4478 | *
|
|---|
| 4479 | * Retrieve weak reference to some other scalar.
|
|---|
| 4480 | * Layout is SX_WEAKREF <object>, with SX_WEAKREF already read.
|
|---|
| 4481 | */
|
|---|
| 4482 | static SV *retrieve_weakref(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4483 | {
|
|---|
| 4484 | SV *sv;
|
|---|
| 4485 |
|
|---|
| 4486 | TRACEME(("retrieve_weakref (#%d)", cxt->tagnum));
|
|---|
| 4487 |
|
|---|
| 4488 | sv = retrieve_ref(aTHX_ cxt, cname);
|
|---|
| 4489 | if (sv) {
|
|---|
| 4490 | #ifdef SvWEAKREF
|
|---|
| 4491 | sv_rvweaken(sv);
|
|---|
| 4492 | #else
|
|---|
| 4493 | WEAKREF_CROAK();
|
|---|
| 4494 | #endif
|
|---|
| 4495 | }
|
|---|
| 4496 | return sv;
|
|---|
| 4497 | }
|
|---|
| 4498 |
|
|---|
| 4499 | /*
|
|---|
| 4500 | * retrieve_overloaded
|
|---|
| 4501 | *
|
|---|
| 4502 | * Retrieve reference to some other scalar with overloading.
|
|---|
| 4503 | * Layout is SX_OVERLOAD <object>, with SX_OVERLOAD already read.
|
|---|
| 4504 | */
|
|---|
| 4505 | static SV *retrieve_overloaded(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4506 | {
|
|---|
| 4507 | SV *rv;
|
|---|
| 4508 | SV *sv;
|
|---|
| 4509 | HV *stash;
|
|---|
| 4510 |
|
|---|
| 4511 | TRACEME(("retrieve_overloaded (#%d)", cxt->tagnum));
|
|---|
| 4512 |
|
|---|
| 4513 | /*
|
|---|
| 4514 | * Same code as retrieve_ref(), duplicated to avoid extra call.
|
|---|
| 4515 | */
|
|---|
| 4516 |
|
|---|
| 4517 | rv = NEWSV(10002, 0);
|
|---|
| 4518 | SEEN(rv, cname, 0); /* Will return if rv is null */
|
|---|
| 4519 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4520 | if (!sv)
|
|---|
| 4521 | return (SV *) 0; /* Failed */
|
|---|
| 4522 |
|
|---|
| 4523 | /*
|
|---|
| 4524 | * WARNING: breaks RV encapsulation.
|
|---|
| 4525 | */
|
|---|
| 4526 |
|
|---|
| 4527 | sv_upgrade(rv, SVt_RV);
|
|---|
| 4528 | SvRV_set(rv, sv); /* $rv = \$sv */
|
|---|
| 4529 | SvROK_on(rv);
|
|---|
| 4530 |
|
|---|
| 4531 | /*
|
|---|
| 4532 | * Restore overloading magic.
|
|---|
| 4533 | */
|
|---|
| 4534 |
|
|---|
| 4535 | stash = SvTYPE(sv) ? (HV *) SvSTASH (sv) : 0;
|
|---|
| 4536 | if (!stash) {
|
|---|
| 4537 | CROAK(("Cannot restore overloading on %s(0x%"UVxf
|
|---|
| 4538 | ") (package <unknown>)",
|
|---|
| 4539 | sv_reftype(sv, FALSE),
|
|---|
| 4540 | PTR2UV(sv)));
|
|---|
| 4541 | }
|
|---|
| 4542 | if (!Gv_AMG(stash)) {
|
|---|
| 4543 | SV *psv = newSVpvn("require ", 8);
|
|---|
| 4544 | const char *package = HvNAME_get(stash);
|
|---|
| 4545 | sv_catpv(psv, package);
|
|---|
| 4546 |
|
|---|
| 4547 | TRACEME(("No overloading defined for package %s", package));
|
|---|
| 4548 | TRACEME(("Going to require module '%s' with '%s'", package, SvPVX(psv)));
|
|---|
| 4549 |
|
|---|
| 4550 | perl_eval_sv(psv, G_DISCARD);
|
|---|
| 4551 | sv_free(psv);
|
|---|
| 4552 | if (!Gv_AMG(stash)) {
|
|---|
| 4553 | CROAK(("Cannot restore overloading on %s(0x%"UVxf
|
|---|
| 4554 | ") (package %s) (even after a \"require %s;\")",
|
|---|
| 4555 | sv_reftype(sv, FALSE),
|
|---|
| 4556 | PTR2UV(sv),
|
|---|
| 4557 | package, package));
|
|---|
| 4558 | }
|
|---|
| 4559 | }
|
|---|
| 4560 |
|
|---|
| 4561 | SvAMAGIC_on(rv);
|
|---|
| 4562 |
|
|---|
| 4563 | TRACEME(("ok (retrieve_overloaded at 0x%"UVxf")", PTR2UV(rv)));
|
|---|
| 4564 |
|
|---|
| 4565 | return rv;
|
|---|
| 4566 | }
|
|---|
| 4567 |
|
|---|
| 4568 | /*
|
|---|
| 4569 | * retrieve_weakoverloaded
|
|---|
| 4570 | *
|
|---|
| 4571 | * Retrieve weak overloaded reference to some other scalar.
|
|---|
| 4572 | * Layout is SX_WEAKOVERLOADED <object>, with SX_WEAKOVERLOADED already read.
|
|---|
| 4573 | */
|
|---|
| 4574 | static SV *retrieve_weakoverloaded(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4575 | {
|
|---|
| 4576 | SV *sv;
|
|---|
| 4577 |
|
|---|
| 4578 | TRACEME(("retrieve_weakoverloaded (#%d)", cxt->tagnum));
|
|---|
| 4579 |
|
|---|
| 4580 | sv = retrieve_overloaded(aTHX_ cxt, cname);
|
|---|
| 4581 | if (sv) {
|
|---|
| 4582 | #ifdef SvWEAKREF
|
|---|
| 4583 | sv_rvweaken(sv);
|
|---|
| 4584 | #else
|
|---|
| 4585 | WEAKREF_CROAK();
|
|---|
| 4586 | #endif
|
|---|
| 4587 | }
|
|---|
| 4588 | return sv;
|
|---|
| 4589 | }
|
|---|
| 4590 |
|
|---|
| 4591 | /*
|
|---|
| 4592 | * retrieve_tied_array
|
|---|
| 4593 | *
|
|---|
| 4594 | * Retrieve tied array
|
|---|
| 4595 | * Layout is SX_TIED_ARRAY <object>, with SX_TIED_ARRAY already read.
|
|---|
| 4596 | */
|
|---|
| 4597 | static SV *retrieve_tied_array(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4598 | {
|
|---|
| 4599 | SV *tv;
|
|---|
| 4600 | SV *sv;
|
|---|
| 4601 |
|
|---|
| 4602 | TRACEME(("retrieve_tied_array (#%d)", cxt->tagnum));
|
|---|
| 4603 |
|
|---|
| 4604 | tv = NEWSV(10002, 0);
|
|---|
| 4605 | SEEN(tv, cname, 0); /* Will return if tv is null */
|
|---|
| 4606 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4607 | if (!sv)
|
|---|
| 4608 | return (SV *) 0; /* Failed */
|
|---|
| 4609 |
|
|---|
| 4610 | sv_upgrade(tv, SVt_PVAV);
|
|---|
| 4611 | AvREAL_off((AV *)tv);
|
|---|
| 4612 | sv_magic(tv, sv, 'P', Nullch, 0);
|
|---|
| 4613 | SvREFCNT_dec(sv); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4614 |
|
|---|
| 4615 | TRACEME(("ok (retrieve_tied_array at 0x%"UVxf")", PTR2UV(tv)));
|
|---|
| 4616 |
|
|---|
| 4617 | return tv;
|
|---|
| 4618 | }
|
|---|
| 4619 |
|
|---|
| 4620 | /*
|
|---|
| 4621 | * retrieve_tied_hash
|
|---|
| 4622 | *
|
|---|
| 4623 | * Retrieve tied hash
|
|---|
| 4624 | * Layout is SX_TIED_HASH <object>, with SX_TIED_HASH already read.
|
|---|
| 4625 | */
|
|---|
| 4626 | static SV *retrieve_tied_hash(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4627 | {
|
|---|
| 4628 | SV *tv;
|
|---|
| 4629 | SV *sv;
|
|---|
| 4630 |
|
|---|
| 4631 | TRACEME(("retrieve_tied_hash (#%d)", cxt->tagnum));
|
|---|
| 4632 |
|
|---|
| 4633 | tv = NEWSV(10002, 0);
|
|---|
| 4634 | SEEN(tv, cname, 0); /* Will return if tv is null */
|
|---|
| 4635 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4636 | if (!sv)
|
|---|
| 4637 | return (SV *) 0; /* Failed */
|
|---|
| 4638 |
|
|---|
| 4639 | sv_upgrade(tv, SVt_PVHV);
|
|---|
| 4640 | sv_magic(tv, sv, 'P', Nullch, 0);
|
|---|
| 4641 | SvREFCNT_dec(sv); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4642 |
|
|---|
| 4643 | TRACEME(("ok (retrieve_tied_hash at 0x%"UVxf")", PTR2UV(tv)));
|
|---|
| 4644 |
|
|---|
| 4645 | return tv;
|
|---|
| 4646 | }
|
|---|
| 4647 |
|
|---|
| 4648 | /*
|
|---|
| 4649 | * retrieve_tied_scalar
|
|---|
| 4650 | *
|
|---|
| 4651 | * Retrieve tied scalar
|
|---|
| 4652 | * Layout is SX_TIED_SCALAR <object>, with SX_TIED_SCALAR already read.
|
|---|
| 4653 | */
|
|---|
| 4654 | static SV *retrieve_tied_scalar(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4655 | {
|
|---|
| 4656 | SV *tv;
|
|---|
| 4657 | SV *sv, *obj = NULL;
|
|---|
| 4658 |
|
|---|
| 4659 | TRACEME(("retrieve_tied_scalar (#%d)", cxt->tagnum));
|
|---|
| 4660 |
|
|---|
| 4661 | tv = NEWSV(10002, 0);
|
|---|
| 4662 | SEEN(tv, cname, 0); /* Will return if rv is null */
|
|---|
| 4663 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4664 | if (!sv) {
|
|---|
| 4665 | return (SV *) 0; /* Failed */
|
|---|
| 4666 | }
|
|---|
| 4667 | else if (SvTYPE(sv) != SVt_NULL) {
|
|---|
| 4668 | obj = sv;
|
|---|
| 4669 | }
|
|---|
| 4670 |
|
|---|
| 4671 | sv_upgrade(tv, SVt_PVMG);
|
|---|
| 4672 | sv_magic(tv, obj, 'q', Nullch, 0);
|
|---|
| 4673 |
|
|---|
| 4674 | if (obj) {
|
|---|
| 4675 | /* Undo refcnt inc from sv_magic() */
|
|---|
| 4676 | SvREFCNT_dec(obj);
|
|---|
| 4677 | }
|
|---|
| 4678 |
|
|---|
| 4679 | TRACEME(("ok (retrieve_tied_scalar at 0x%"UVxf")", PTR2UV(tv)));
|
|---|
| 4680 |
|
|---|
| 4681 | return tv;
|
|---|
| 4682 | }
|
|---|
| 4683 |
|
|---|
| 4684 | /*
|
|---|
| 4685 | * retrieve_tied_key
|
|---|
| 4686 | *
|
|---|
| 4687 | * Retrieve reference to value in a tied hash.
|
|---|
| 4688 | * Layout is SX_TIED_KEY <object> <key>, with SX_TIED_KEY already read.
|
|---|
| 4689 | */
|
|---|
| 4690 | static SV *retrieve_tied_key(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4691 | {
|
|---|
| 4692 | SV *tv;
|
|---|
| 4693 | SV *sv;
|
|---|
| 4694 | SV *key;
|
|---|
| 4695 |
|
|---|
| 4696 | TRACEME(("retrieve_tied_key (#%d)", cxt->tagnum));
|
|---|
| 4697 |
|
|---|
| 4698 | tv = NEWSV(10002, 0);
|
|---|
| 4699 | SEEN(tv, cname, 0); /* Will return if tv is null */
|
|---|
| 4700 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4701 | if (!sv)
|
|---|
| 4702 | return (SV *) 0; /* Failed */
|
|---|
| 4703 |
|
|---|
| 4704 | key = retrieve(aTHX_ cxt, 0); /* Retrieve <key> */
|
|---|
| 4705 | if (!key)
|
|---|
| 4706 | return (SV *) 0; /* Failed */
|
|---|
| 4707 |
|
|---|
| 4708 | sv_upgrade(tv, SVt_PVMG);
|
|---|
| 4709 | sv_magic(tv, sv, 'p', (char *)key, HEf_SVKEY);
|
|---|
| 4710 | SvREFCNT_dec(key); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4711 | SvREFCNT_dec(sv); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4712 |
|
|---|
| 4713 | return tv;
|
|---|
| 4714 | }
|
|---|
| 4715 |
|
|---|
| 4716 | /*
|
|---|
| 4717 | * retrieve_tied_idx
|
|---|
| 4718 | *
|
|---|
| 4719 | * Retrieve reference to value in a tied array.
|
|---|
| 4720 | * Layout is SX_TIED_IDX <object> <idx>, with SX_TIED_IDX already read.
|
|---|
| 4721 | */
|
|---|
| 4722 | static SV *retrieve_tied_idx(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4723 | {
|
|---|
| 4724 | SV *tv;
|
|---|
| 4725 | SV *sv;
|
|---|
| 4726 | I32 idx;
|
|---|
| 4727 |
|
|---|
| 4728 | TRACEME(("retrieve_tied_idx (#%d)", cxt->tagnum));
|
|---|
| 4729 |
|
|---|
| 4730 | tv = NEWSV(10002, 0);
|
|---|
| 4731 | SEEN(tv, cname, 0); /* Will return if tv is null */
|
|---|
| 4732 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve <object> */
|
|---|
| 4733 | if (!sv)
|
|---|
| 4734 | return (SV *) 0; /* Failed */
|
|---|
| 4735 |
|
|---|
| 4736 | RLEN(idx); /* Retrieve <idx> */
|
|---|
| 4737 |
|
|---|
| 4738 | sv_upgrade(tv, SVt_PVMG);
|
|---|
| 4739 | sv_magic(tv, sv, 'p', Nullch, idx);
|
|---|
| 4740 | SvREFCNT_dec(sv); /* Undo refcnt inc from sv_magic() */
|
|---|
| 4741 |
|
|---|
| 4742 | return tv;
|
|---|
| 4743 | }
|
|---|
| 4744 |
|
|---|
| 4745 |
|
|---|
| 4746 | /*
|
|---|
| 4747 | * retrieve_lscalar
|
|---|
| 4748 | *
|
|---|
| 4749 | * Retrieve defined long (string) scalar.
|
|---|
| 4750 | *
|
|---|
| 4751 | * Layout is SX_LSCALAR <length> <data>, with SX_LSCALAR already read.
|
|---|
| 4752 | * The scalar is "long" in that <length> is larger than LG_SCALAR so it
|
|---|
| 4753 | * was not stored on a single byte.
|
|---|
| 4754 | */
|
|---|
| 4755 | static SV *retrieve_lscalar(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4756 | {
|
|---|
| 4757 | I32 len;
|
|---|
| 4758 | SV *sv;
|
|---|
| 4759 |
|
|---|
| 4760 | RLEN(len);
|
|---|
| 4761 | TRACEME(("retrieve_lscalar (#%d), len = %"IVdf, cxt->tagnum, (IV) len));
|
|---|
| 4762 |
|
|---|
| 4763 | /*
|
|---|
| 4764 | * Allocate an empty scalar of the suitable length.
|
|---|
| 4765 | */
|
|---|
| 4766 |
|
|---|
| 4767 | sv = NEWSV(10002, len);
|
|---|
| 4768 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 4769 |
|
|---|
| 4770 | /*
|
|---|
| 4771 | * WARNING: duplicates parts of sv_setpv and breaks SV data encapsulation.
|
|---|
| 4772 | *
|
|---|
| 4773 | * Now, for efficiency reasons, read data directly inside the SV buffer,
|
|---|
| 4774 | * and perform the SV final settings directly by duplicating the final
|
|---|
| 4775 | * work done by sv_setpv. Since we're going to allocate lots of scalars
|
|---|
| 4776 | * this way, it's worth the hassle and risk.
|
|---|
| 4777 | */
|
|---|
| 4778 |
|
|---|
| 4779 | SAFEREAD(SvPVX(sv), len, sv);
|
|---|
| 4780 | SvCUR_set(sv, len); /* Record C string length */
|
|---|
| 4781 | *SvEND(sv) = '\0'; /* Ensure it's null terminated anyway */
|
|---|
| 4782 | (void) SvPOK_only(sv); /* Validate string pointer */
|
|---|
| 4783 | if (cxt->s_tainted) /* Is input source tainted? */
|
|---|
| 4784 | SvTAINT(sv); /* External data cannot be trusted */
|
|---|
| 4785 |
|
|---|
| 4786 | TRACEME(("large scalar len %"IVdf" '%s'", (IV) len, SvPVX(sv)));
|
|---|
| 4787 | TRACEME(("ok (retrieve_lscalar at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4788 |
|
|---|
| 4789 | return sv;
|
|---|
| 4790 | }
|
|---|
| 4791 |
|
|---|
| 4792 | /*
|
|---|
| 4793 | * retrieve_scalar
|
|---|
| 4794 | *
|
|---|
| 4795 | * Retrieve defined short (string) scalar.
|
|---|
| 4796 | *
|
|---|
| 4797 | * Layout is SX_SCALAR <length> <data>, with SX_SCALAR already read.
|
|---|
| 4798 | * The scalar is "short" so <length> is single byte. If it is 0, there
|
|---|
| 4799 | * is no <data> section.
|
|---|
| 4800 | */
|
|---|
| 4801 | static SV *retrieve_scalar(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4802 | {
|
|---|
| 4803 | int len;
|
|---|
| 4804 | SV *sv;
|
|---|
| 4805 |
|
|---|
| 4806 | GETMARK(len);
|
|---|
| 4807 | TRACEME(("retrieve_scalar (#%d), len = %d", cxt->tagnum, len));
|
|---|
| 4808 |
|
|---|
| 4809 | /*
|
|---|
| 4810 | * Allocate an empty scalar of the suitable length.
|
|---|
| 4811 | */
|
|---|
| 4812 |
|
|---|
| 4813 | sv = NEWSV(10002, len);
|
|---|
| 4814 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 4815 |
|
|---|
| 4816 | /*
|
|---|
| 4817 | * WARNING: duplicates parts of sv_setpv and breaks SV data encapsulation.
|
|---|
| 4818 | */
|
|---|
| 4819 |
|
|---|
| 4820 | if (len == 0) {
|
|---|
| 4821 | /*
|
|---|
| 4822 | * newSV did not upgrade to SVt_PV so the scalar is undefined.
|
|---|
| 4823 | * To make it defined with an empty length, upgrade it now...
|
|---|
| 4824 | * Don't upgrade to a PV if the original type contains more
|
|---|
| 4825 | * information than a scalar.
|
|---|
| 4826 | */
|
|---|
| 4827 | if (SvTYPE(sv) <= SVt_PV) {
|
|---|
| 4828 | sv_upgrade(sv, SVt_PV);
|
|---|
| 4829 | }
|
|---|
| 4830 | SvGROW(sv, 1);
|
|---|
| 4831 | *SvEND(sv) = '\0'; /* Ensure it's null terminated anyway */
|
|---|
| 4832 | TRACEME(("ok (retrieve_scalar empty at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4833 | } else {
|
|---|
| 4834 | /*
|
|---|
| 4835 | * Now, for efficiency reasons, read data directly inside the SV buffer,
|
|---|
| 4836 | * and perform the SV final settings directly by duplicating the final
|
|---|
| 4837 | * work done by sv_setpv. Since we're going to allocate lots of scalars
|
|---|
| 4838 | * this way, it's worth the hassle and risk.
|
|---|
| 4839 | */
|
|---|
| 4840 | SAFEREAD(SvPVX(sv), len, sv);
|
|---|
| 4841 | SvCUR_set(sv, len); /* Record C string length */
|
|---|
| 4842 | *SvEND(sv) = '\0'; /* Ensure it's null terminated anyway */
|
|---|
| 4843 | TRACEME(("small scalar len %d '%s'", len, SvPVX(sv)));
|
|---|
| 4844 | }
|
|---|
| 4845 |
|
|---|
| 4846 | (void) SvPOK_only(sv); /* Validate string pointer */
|
|---|
| 4847 | if (cxt->s_tainted) /* Is input source tainted? */
|
|---|
| 4848 | SvTAINT(sv); /* External data cannot be trusted */
|
|---|
| 4849 |
|
|---|
| 4850 | TRACEME(("ok (retrieve_scalar at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4851 | return sv;
|
|---|
| 4852 | }
|
|---|
| 4853 |
|
|---|
| 4854 | /*
|
|---|
| 4855 | * retrieve_utf8str
|
|---|
| 4856 | *
|
|---|
| 4857 | * Like retrieve_scalar(), but tag result as utf8.
|
|---|
| 4858 | * If we're retrieving UTF8 data in a non-UTF8 perl, croaks.
|
|---|
| 4859 | */
|
|---|
| 4860 | static SV *retrieve_utf8str(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4861 | {
|
|---|
| 4862 | SV *sv;
|
|---|
| 4863 |
|
|---|
| 4864 | TRACEME(("retrieve_utf8str"));
|
|---|
| 4865 |
|
|---|
| 4866 | sv = retrieve_scalar(aTHX_ cxt, cname);
|
|---|
| 4867 | if (sv) {
|
|---|
| 4868 | #ifdef HAS_UTF8_SCALARS
|
|---|
| 4869 | SvUTF8_on(sv);
|
|---|
| 4870 | #else
|
|---|
| 4871 | if (cxt->use_bytes < 0)
|
|---|
| 4872 | cxt->use_bytes
|
|---|
| 4873 | = (SvTRUE(perl_get_sv("Storable::drop_utf8", TRUE))
|
|---|
| 4874 | ? 1 : 0);
|
|---|
| 4875 | if (cxt->use_bytes == 0)
|
|---|
| 4876 | UTF8_CROAK();
|
|---|
| 4877 | #endif
|
|---|
| 4878 | }
|
|---|
| 4879 |
|
|---|
| 4880 | return sv;
|
|---|
| 4881 | }
|
|---|
| 4882 |
|
|---|
| 4883 | /*
|
|---|
| 4884 | * retrieve_lutf8str
|
|---|
| 4885 | *
|
|---|
| 4886 | * Like retrieve_lscalar(), but tag result as utf8.
|
|---|
| 4887 | * If we're retrieving UTF8 data in a non-UTF8 perl, croaks.
|
|---|
| 4888 | */
|
|---|
| 4889 | static SV *retrieve_lutf8str(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4890 | {
|
|---|
| 4891 | SV *sv;
|
|---|
| 4892 |
|
|---|
| 4893 | TRACEME(("retrieve_lutf8str"));
|
|---|
| 4894 |
|
|---|
| 4895 | sv = retrieve_lscalar(aTHX_ cxt, cname);
|
|---|
| 4896 | if (sv) {
|
|---|
| 4897 | #ifdef HAS_UTF8_SCALARS
|
|---|
| 4898 | SvUTF8_on(sv);
|
|---|
| 4899 | #else
|
|---|
| 4900 | if (cxt->use_bytes < 0)
|
|---|
| 4901 | cxt->use_bytes
|
|---|
| 4902 | = (SvTRUE(perl_get_sv("Storable::drop_utf8", TRUE))
|
|---|
| 4903 | ? 1 : 0);
|
|---|
| 4904 | if (cxt->use_bytes == 0)
|
|---|
| 4905 | UTF8_CROAK();
|
|---|
| 4906 | #endif
|
|---|
| 4907 | }
|
|---|
| 4908 | return sv;
|
|---|
| 4909 | }
|
|---|
| 4910 |
|
|---|
| 4911 | /*
|
|---|
| 4912 | * retrieve_integer
|
|---|
| 4913 | *
|
|---|
| 4914 | * Retrieve defined integer.
|
|---|
| 4915 | * Layout is SX_INTEGER <data>, whith SX_INTEGER already read.
|
|---|
| 4916 | */
|
|---|
| 4917 | static SV *retrieve_integer(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4918 | {
|
|---|
| 4919 | SV *sv;
|
|---|
| 4920 | IV iv;
|
|---|
| 4921 |
|
|---|
| 4922 | TRACEME(("retrieve_integer (#%d)", cxt->tagnum));
|
|---|
| 4923 |
|
|---|
| 4924 | READ(&iv, sizeof(iv));
|
|---|
| 4925 | sv = newSViv(iv);
|
|---|
| 4926 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 4927 |
|
|---|
| 4928 | TRACEME(("integer %"IVdf, iv));
|
|---|
| 4929 | TRACEME(("ok (retrieve_integer at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4930 |
|
|---|
| 4931 | return sv;
|
|---|
| 4932 | }
|
|---|
| 4933 |
|
|---|
| 4934 | /*
|
|---|
| 4935 | * retrieve_netint
|
|---|
| 4936 | *
|
|---|
| 4937 | * Retrieve defined integer in network order.
|
|---|
| 4938 | * Layout is SX_NETINT <data>, whith SX_NETINT already read.
|
|---|
| 4939 | */
|
|---|
| 4940 | static SV *retrieve_netint(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4941 | {
|
|---|
| 4942 | SV *sv;
|
|---|
| 4943 | I32 iv;
|
|---|
| 4944 |
|
|---|
| 4945 | TRACEME(("retrieve_netint (#%d)", cxt->tagnum));
|
|---|
| 4946 |
|
|---|
| 4947 | READ_I32(iv);
|
|---|
| 4948 | #ifdef HAS_NTOHL
|
|---|
| 4949 | sv = newSViv((int) ntohl(iv));
|
|---|
| 4950 | TRACEME(("network integer %d", (int) ntohl(iv)));
|
|---|
| 4951 | #else
|
|---|
| 4952 | sv = newSViv(iv);
|
|---|
| 4953 | TRACEME(("network integer (as-is) %d", iv));
|
|---|
| 4954 | #endif
|
|---|
| 4955 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 4956 |
|
|---|
| 4957 | TRACEME(("ok (retrieve_netint at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4958 |
|
|---|
| 4959 | return sv;
|
|---|
| 4960 | }
|
|---|
| 4961 |
|
|---|
| 4962 | /*
|
|---|
| 4963 | * retrieve_double
|
|---|
| 4964 | *
|
|---|
| 4965 | * Retrieve defined double.
|
|---|
| 4966 | * Layout is SX_DOUBLE <data>, whith SX_DOUBLE already read.
|
|---|
| 4967 | */
|
|---|
| 4968 | static SV *retrieve_double(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4969 | {
|
|---|
| 4970 | SV *sv;
|
|---|
| 4971 | NV nv;
|
|---|
| 4972 |
|
|---|
| 4973 | TRACEME(("retrieve_double (#%d)", cxt->tagnum));
|
|---|
| 4974 |
|
|---|
| 4975 | READ(&nv, sizeof(nv));
|
|---|
| 4976 | sv = newSVnv(nv);
|
|---|
| 4977 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 4978 |
|
|---|
| 4979 | TRACEME(("double %"NVff, nv));
|
|---|
| 4980 | TRACEME(("ok (retrieve_double at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 4981 |
|
|---|
| 4982 | return sv;
|
|---|
| 4983 | }
|
|---|
| 4984 |
|
|---|
| 4985 | /*
|
|---|
| 4986 | * retrieve_byte
|
|---|
| 4987 | *
|
|---|
| 4988 | * Retrieve defined byte (small integer within the [-128, +127] range).
|
|---|
| 4989 | * Layout is SX_BYTE <data>, whith SX_BYTE already read.
|
|---|
| 4990 | */
|
|---|
| 4991 | static SV *retrieve_byte(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 4992 | {
|
|---|
| 4993 | SV *sv;
|
|---|
| 4994 | int siv;
|
|---|
| 4995 | signed char tmp; /* Workaround for AIX cc bug --H.Merijn Brand */
|
|---|
| 4996 |
|
|---|
| 4997 | TRACEME(("retrieve_byte (#%d)", cxt->tagnum));
|
|---|
| 4998 |
|
|---|
| 4999 | GETMARK(siv);
|
|---|
| 5000 | TRACEME(("small integer read as %d", (unsigned char) siv));
|
|---|
| 5001 | tmp = (unsigned char) siv - 128;
|
|---|
| 5002 | sv = newSViv(tmp);
|
|---|
| 5003 | SEEN(sv, cname, 0); /* Associate this new scalar with tag "tagnum" */
|
|---|
| 5004 |
|
|---|
| 5005 | TRACEME(("byte %d", tmp));
|
|---|
| 5006 | TRACEME(("ok (retrieve_byte at 0x%"UVxf")", PTR2UV(sv)));
|
|---|
| 5007 |
|
|---|
| 5008 | return sv;
|
|---|
| 5009 | }
|
|---|
| 5010 |
|
|---|
| 5011 | /*
|
|---|
| 5012 | * retrieve_undef
|
|---|
| 5013 | *
|
|---|
| 5014 | * Return the undefined value.
|
|---|
| 5015 | */
|
|---|
| 5016 | static SV *retrieve_undef(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5017 | {
|
|---|
| 5018 | SV* sv;
|
|---|
| 5019 |
|
|---|
| 5020 | TRACEME(("retrieve_undef"));
|
|---|
| 5021 |
|
|---|
| 5022 | sv = newSV(0);
|
|---|
| 5023 | SEEN(sv, cname, 0);
|
|---|
| 5024 |
|
|---|
| 5025 | return sv;
|
|---|
| 5026 | }
|
|---|
| 5027 |
|
|---|
| 5028 | /*
|
|---|
| 5029 | * retrieve_sv_undef
|
|---|
| 5030 | *
|
|---|
| 5031 | * Return the immortal undefined value.
|
|---|
| 5032 | */
|
|---|
| 5033 | static SV *retrieve_sv_undef(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5034 | {
|
|---|
| 5035 | SV *sv = &PL_sv_undef;
|
|---|
| 5036 |
|
|---|
| 5037 | TRACEME(("retrieve_sv_undef"));
|
|---|
| 5038 |
|
|---|
| 5039 | /* Special case PL_sv_undef, as av_fetch uses it internally to mark
|
|---|
| 5040 | deleted elements, and will return NULL (fetch failed) whenever it
|
|---|
| 5041 | is fetched. */
|
|---|
| 5042 | if (cxt->where_is_undef == -1) {
|
|---|
| 5043 | cxt->where_is_undef = cxt->tagnum;
|
|---|
| 5044 | }
|
|---|
| 5045 | SEEN(sv, cname, 1);
|
|---|
| 5046 | return sv;
|
|---|
| 5047 | }
|
|---|
| 5048 |
|
|---|
| 5049 | /*
|
|---|
| 5050 | * retrieve_sv_yes
|
|---|
| 5051 | *
|
|---|
| 5052 | * Return the immortal yes value.
|
|---|
| 5053 | */
|
|---|
| 5054 | static SV *retrieve_sv_yes(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5055 | {
|
|---|
| 5056 | SV *sv = &PL_sv_yes;
|
|---|
| 5057 |
|
|---|
| 5058 | TRACEME(("retrieve_sv_yes"));
|
|---|
| 5059 |
|
|---|
| 5060 | SEEN(sv, cname, 1);
|
|---|
| 5061 | return sv;
|
|---|
| 5062 | }
|
|---|
| 5063 |
|
|---|
| 5064 | /*
|
|---|
| 5065 | * retrieve_sv_no
|
|---|
| 5066 | *
|
|---|
| 5067 | * Return the immortal no value.
|
|---|
| 5068 | */
|
|---|
| 5069 | static SV *retrieve_sv_no(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5070 | {
|
|---|
| 5071 | SV *sv = &PL_sv_no;
|
|---|
| 5072 |
|
|---|
| 5073 | TRACEME(("retrieve_sv_no"));
|
|---|
| 5074 |
|
|---|
| 5075 | SEEN(sv, cname, 1);
|
|---|
| 5076 | return sv;
|
|---|
| 5077 | }
|
|---|
| 5078 |
|
|---|
| 5079 | /*
|
|---|
| 5080 | * retrieve_array
|
|---|
| 5081 | *
|
|---|
| 5082 | * Retrieve a whole array.
|
|---|
| 5083 | * Layout is SX_ARRAY <size> followed by each item, in increading index order.
|
|---|
| 5084 | * Each item is stored as <object>.
|
|---|
| 5085 | *
|
|---|
| 5086 | * When we come here, SX_ARRAY has been read already.
|
|---|
| 5087 | */
|
|---|
| 5088 | static SV *retrieve_array(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5089 | {
|
|---|
| 5090 | I32 len;
|
|---|
| 5091 | I32 i;
|
|---|
| 5092 | AV *av;
|
|---|
| 5093 | SV *sv;
|
|---|
| 5094 |
|
|---|
| 5095 | TRACEME(("retrieve_array (#%d)", cxt->tagnum));
|
|---|
| 5096 |
|
|---|
| 5097 | /*
|
|---|
| 5098 | * Read length, and allocate array, then pre-extend it.
|
|---|
| 5099 | */
|
|---|
| 5100 |
|
|---|
| 5101 | RLEN(len);
|
|---|
| 5102 | TRACEME(("size = %d", len));
|
|---|
| 5103 | av = newAV();
|
|---|
| 5104 | SEEN(av, cname, 0); /* Will return if array not allocated nicely */
|
|---|
| 5105 | if (len)
|
|---|
| 5106 | av_extend(av, len);
|
|---|
| 5107 | else
|
|---|
| 5108 | return (SV *) av; /* No data follow if array is empty */
|
|---|
| 5109 |
|
|---|
| 5110 | /*
|
|---|
| 5111 | * Now get each item in turn...
|
|---|
| 5112 | */
|
|---|
| 5113 |
|
|---|
| 5114 | for (i = 0; i < len; i++) {
|
|---|
| 5115 | TRACEME(("(#%d) item", i));
|
|---|
| 5116 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve item */
|
|---|
| 5117 | if (!sv)
|
|---|
| 5118 | return (SV *) 0;
|
|---|
| 5119 | if (av_store(av, i, sv) == 0)
|
|---|
| 5120 | return (SV *) 0;
|
|---|
| 5121 | }
|
|---|
| 5122 |
|
|---|
| 5123 | TRACEME(("ok (retrieve_array at 0x%"UVxf")", PTR2UV(av)));
|
|---|
| 5124 |
|
|---|
| 5125 | return (SV *) av;
|
|---|
| 5126 | }
|
|---|
| 5127 |
|
|---|
| 5128 | /*
|
|---|
| 5129 | * retrieve_hash
|
|---|
| 5130 | *
|
|---|
| 5131 | * Retrieve a whole hash table.
|
|---|
| 5132 | * Layout is SX_HASH <size> followed by each key/value pair, in random order.
|
|---|
| 5133 | * Keys are stored as <length> <data>, the <data> section being omitted
|
|---|
| 5134 | * if length is 0.
|
|---|
| 5135 | * Values are stored as <object>.
|
|---|
| 5136 | *
|
|---|
| 5137 | * When we come here, SX_HASH has been read already.
|
|---|
| 5138 | */
|
|---|
| 5139 | static SV *retrieve_hash(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5140 | {
|
|---|
| 5141 | I32 len;
|
|---|
| 5142 | I32 size;
|
|---|
| 5143 | I32 i;
|
|---|
| 5144 | HV *hv;
|
|---|
| 5145 | SV *sv;
|
|---|
| 5146 |
|
|---|
| 5147 | TRACEME(("retrieve_hash (#%d)", cxt->tagnum));
|
|---|
| 5148 |
|
|---|
| 5149 | /*
|
|---|
| 5150 | * Read length, allocate table.
|
|---|
| 5151 | */
|
|---|
| 5152 |
|
|---|
| 5153 | RLEN(len);
|
|---|
| 5154 | TRACEME(("size = %d", len));
|
|---|
| 5155 | hv = newHV();
|
|---|
| 5156 | SEEN(hv, cname, 0); /* Will return if table not allocated properly */
|
|---|
| 5157 | if (len == 0)
|
|---|
| 5158 | return (SV *) hv; /* No data follow if table empty */
|
|---|
| 5159 | hv_ksplit(hv, len); /* pre-extend hash to save multiple splits */
|
|---|
| 5160 |
|
|---|
| 5161 | /*
|
|---|
| 5162 | * Now get each key/value pair in turn...
|
|---|
| 5163 | */
|
|---|
| 5164 |
|
|---|
| 5165 | for (i = 0; i < len; i++) {
|
|---|
| 5166 | /*
|
|---|
| 5167 | * Get value first.
|
|---|
| 5168 | */
|
|---|
| 5169 |
|
|---|
| 5170 | TRACEME(("(#%d) value", i));
|
|---|
| 5171 | sv = retrieve(aTHX_ cxt, 0);
|
|---|
| 5172 | if (!sv)
|
|---|
| 5173 | return (SV *) 0;
|
|---|
| 5174 |
|
|---|
| 5175 | /*
|
|---|
| 5176 | * Get key.
|
|---|
| 5177 | * Since we're reading into kbuf, we must ensure we're not
|
|---|
| 5178 | * recursing between the read and the hv_store() where it's used.
|
|---|
| 5179 | * Hence the key comes after the value.
|
|---|
| 5180 | */
|
|---|
| 5181 |
|
|---|
| 5182 | RLEN(size); /* Get key size */
|
|---|
| 5183 | KBUFCHK((STRLEN)size); /* Grow hash key read pool if needed */
|
|---|
| 5184 | if (size)
|
|---|
| 5185 | READ(kbuf, size);
|
|---|
| 5186 | kbuf[size] = '\0'; /* Mark string end, just in case */
|
|---|
| 5187 | TRACEME(("(#%d) key '%s'", i, kbuf));
|
|---|
| 5188 |
|
|---|
| 5189 | /*
|
|---|
| 5190 | * Enter key/value pair into hash table.
|
|---|
| 5191 | */
|
|---|
| 5192 |
|
|---|
| 5193 | if (hv_store(hv, kbuf, (U32) size, sv, 0) == 0)
|
|---|
| 5194 | return (SV *) 0;
|
|---|
| 5195 | }
|
|---|
| 5196 |
|
|---|
| 5197 | TRACEME(("ok (retrieve_hash at 0x%"UVxf")", PTR2UV(hv)));
|
|---|
| 5198 |
|
|---|
| 5199 | return (SV *) hv;
|
|---|
| 5200 | }
|
|---|
| 5201 |
|
|---|
| 5202 | /*
|
|---|
| 5203 | * retrieve_hash
|
|---|
| 5204 | *
|
|---|
| 5205 | * Retrieve a whole hash table.
|
|---|
| 5206 | * Layout is SX_HASH <size> followed by each key/value pair, in random order.
|
|---|
| 5207 | * Keys are stored as <length> <data>, the <data> section being omitted
|
|---|
| 5208 | * if length is 0.
|
|---|
| 5209 | * Values are stored as <object>.
|
|---|
| 5210 | *
|
|---|
| 5211 | * When we come here, SX_HASH has been read already.
|
|---|
| 5212 | */
|
|---|
| 5213 | static SV *retrieve_flag_hash(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5214 | {
|
|---|
| 5215 | dVAR;
|
|---|
| 5216 | I32 len;
|
|---|
| 5217 | I32 size;
|
|---|
| 5218 | I32 i;
|
|---|
| 5219 | HV *hv;
|
|---|
| 5220 | SV *sv;
|
|---|
| 5221 | int hash_flags;
|
|---|
| 5222 |
|
|---|
| 5223 | GETMARK(hash_flags);
|
|---|
| 5224 | TRACEME(("retrieve_flag_hash (#%d)", cxt->tagnum));
|
|---|
| 5225 | /*
|
|---|
| 5226 | * Read length, allocate table.
|
|---|
| 5227 | */
|
|---|
| 5228 |
|
|---|
| 5229 | #ifndef HAS_RESTRICTED_HASHES
|
|---|
| 5230 | if (hash_flags & SHV_RESTRICTED) {
|
|---|
| 5231 | if (cxt->derestrict < 0)
|
|---|
| 5232 | cxt->derestrict
|
|---|
| 5233 | = (SvTRUE(perl_get_sv("Storable::downgrade_restricted", TRUE))
|
|---|
| 5234 | ? 1 : 0);
|
|---|
| 5235 | if (cxt->derestrict == 0)
|
|---|
| 5236 | RESTRICTED_HASH_CROAK();
|
|---|
| 5237 | }
|
|---|
| 5238 | #endif
|
|---|
| 5239 |
|
|---|
| 5240 | RLEN(len);
|
|---|
| 5241 | TRACEME(("size = %d, flags = %d", len, hash_flags));
|
|---|
| 5242 | hv = newHV();
|
|---|
| 5243 | SEEN(hv, cname, 0); /* Will return if table not allocated properly */
|
|---|
| 5244 | if (len == 0)
|
|---|
| 5245 | return (SV *) hv; /* No data follow if table empty */
|
|---|
| 5246 | hv_ksplit(hv, len); /* pre-extend hash to save multiple splits */
|
|---|
| 5247 |
|
|---|
| 5248 | /*
|
|---|
| 5249 | * Now get each key/value pair in turn...
|
|---|
| 5250 | */
|
|---|
| 5251 |
|
|---|
| 5252 | for (i = 0; i < len; i++) {
|
|---|
| 5253 | int flags;
|
|---|
| 5254 | int store_flags = 0;
|
|---|
| 5255 | /*
|
|---|
| 5256 | * Get value first.
|
|---|
| 5257 | */
|
|---|
| 5258 |
|
|---|
| 5259 | TRACEME(("(#%d) value", i));
|
|---|
| 5260 | sv = retrieve(aTHX_ cxt, 0);
|
|---|
| 5261 | if (!sv)
|
|---|
| 5262 | return (SV *) 0;
|
|---|
| 5263 |
|
|---|
| 5264 | GETMARK(flags);
|
|---|
| 5265 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 5266 | if ((hash_flags & SHV_RESTRICTED) && (flags & SHV_K_LOCKED))
|
|---|
| 5267 | SvREADONLY_on(sv);
|
|---|
| 5268 | #endif
|
|---|
| 5269 |
|
|---|
| 5270 | if (flags & SHV_K_ISSV) {
|
|---|
| 5271 | /* XXX you can't set a placeholder with an SV key.
|
|---|
| 5272 | Then again, you can't get an SV key.
|
|---|
| 5273 | Without messing around beyond what the API is supposed to do.
|
|---|
| 5274 | */
|
|---|
| 5275 | SV *keysv;
|
|---|
| 5276 | TRACEME(("(#%d) keysv, flags=%d", i, flags));
|
|---|
| 5277 | keysv = retrieve(aTHX_ cxt, 0);
|
|---|
| 5278 | if (!keysv)
|
|---|
| 5279 | return (SV *) 0;
|
|---|
| 5280 |
|
|---|
| 5281 | if (!hv_store_ent(hv, keysv, sv, 0))
|
|---|
| 5282 | return (SV *) 0;
|
|---|
| 5283 | } else {
|
|---|
| 5284 | /*
|
|---|
| 5285 | * Get key.
|
|---|
| 5286 | * Since we're reading into kbuf, we must ensure we're not
|
|---|
| 5287 | * recursing between the read and the hv_store() where it's used.
|
|---|
| 5288 | * Hence the key comes after the value.
|
|---|
| 5289 | */
|
|---|
| 5290 |
|
|---|
| 5291 | if (flags & SHV_K_PLACEHOLDER) {
|
|---|
| 5292 | SvREFCNT_dec (sv);
|
|---|
| 5293 | sv = &PL_sv_placeholder;
|
|---|
| 5294 | store_flags |= HVhek_PLACEHOLD;
|
|---|
| 5295 | }
|
|---|
| 5296 | if (flags & SHV_K_UTF8) {
|
|---|
| 5297 | #ifdef HAS_UTF8_HASHES
|
|---|
| 5298 | store_flags |= HVhek_UTF8;
|
|---|
| 5299 | #else
|
|---|
| 5300 | if (cxt->use_bytes < 0)
|
|---|
| 5301 | cxt->use_bytes
|
|---|
| 5302 | = (SvTRUE(perl_get_sv("Storable::drop_utf8", TRUE))
|
|---|
| 5303 | ? 1 : 0);
|
|---|
| 5304 | if (cxt->use_bytes == 0)
|
|---|
| 5305 | UTF8_CROAK();
|
|---|
| 5306 | #endif
|
|---|
| 5307 | }
|
|---|
| 5308 | #ifdef HAS_UTF8_HASHES
|
|---|
| 5309 | if (flags & SHV_K_WASUTF8)
|
|---|
| 5310 | store_flags |= HVhek_WASUTF8;
|
|---|
| 5311 | #endif
|
|---|
| 5312 |
|
|---|
| 5313 | RLEN(size); /* Get key size */
|
|---|
| 5314 | KBUFCHK((STRLEN)size); /* Grow hash key read pool if needed */
|
|---|
| 5315 | if (size)
|
|---|
| 5316 | READ(kbuf, size);
|
|---|
| 5317 | kbuf[size] = '\0'; /* Mark string end, just in case */
|
|---|
| 5318 | TRACEME(("(#%d) key '%s' flags %X store_flags %X", i, kbuf,
|
|---|
| 5319 | flags, store_flags));
|
|---|
| 5320 |
|
|---|
| 5321 | /*
|
|---|
| 5322 | * Enter key/value pair into hash table.
|
|---|
| 5323 | */
|
|---|
| 5324 |
|
|---|
| 5325 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 5326 | if (hv_store_flags(hv, kbuf, size, sv, 0, store_flags) == 0)
|
|---|
| 5327 | return (SV *) 0;
|
|---|
| 5328 | #else
|
|---|
| 5329 | if (!(store_flags & HVhek_PLACEHOLD))
|
|---|
| 5330 | if (hv_store(hv, kbuf, size, sv, 0) == 0)
|
|---|
| 5331 | return (SV *) 0;
|
|---|
| 5332 | #endif
|
|---|
| 5333 | }
|
|---|
| 5334 | }
|
|---|
| 5335 | #ifdef HAS_RESTRICTED_HASHES
|
|---|
| 5336 | if (hash_flags & SHV_RESTRICTED)
|
|---|
| 5337 | SvREADONLY_on(hv);
|
|---|
| 5338 | #endif
|
|---|
| 5339 |
|
|---|
| 5340 | TRACEME(("ok (retrieve_hash at 0x%"UVxf")", PTR2UV(hv)));
|
|---|
| 5341 |
|
|---|
| 5342 | return (SV *) hv;
|
|---|
| 5343 | }
|
|---|
| 5344 |
|
|---|
| 5345 | /*
|
|---|
| 5346 | * retrieve_code
|
|---|
| 5347 | *
|
|---|
| 5348 | * Return a code reference.
|
|---|
| 5349 | */
|
|---|
| 5350 | static SV *retrieve_code(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5351 | {
|
|---|
| 5352 | #if PERL_VERSION < 6
|
|---|
| 5353 | CROAK(("retrieve_code does not work with perl 5.005 or less\n"));
|
|---|
| 5354 | #else
|
|---|
| 5355 | dSP;
|
|---|
| 5356 | int type, count, tagnum;
|
|---|
| 5357 | SV *cv;
|
|---|
| 5358 | SV *sv, *text, *sub;
|
|---|
| 5359 |
|
|---|
| 5360 | TRACEME(("retrieve_code (#%d)", cxt->tagnum));
|
|---|
| 5361 |
|
|---|
| 5362 | /*
|
|---|
| 5363 | * Insert dummy SV in the aseen array so that we don't screw
|
|---|
| 5364 | * up the tag numbers. We would just make the internal
|
|---|
| 5365 | * scalar an untagged item in the stream, but
|
|---|
| 5366 | * retrieve_scalar() calls SEEN(). So we just increase the
|
|---|
| 5367 | * tag number.
|
|---|
| 5368 | */
|
|---|
| 5369 | tagnum = cxt->tagnum;
|
|---|
| 5370 | sv = newSViv(0);
|
|---|
| 5371 | SEEN(sv, cname, 0);
|
|---|
| 5372 |
|
|---|
| 5373 | /*
|
|---|
| 5374 | * Retrieve the source of the code reference
|
|---|
| 5375 | * as a small or large scalar
|
|---|
| 5376 | */
|
|---|
| 5377 |
|
|---|
| 5378 | GETMARK(type);
|
|---|
| 5379 | switch (type) {
|
|---|
| 5380 | case SX_SCALAR:
|
|---|
| 5381 | text = retrieve_scalar(aTHX_ cxt, cname);
|
|---|
| 5382 | break;
|
|---|
| 5383 | case SX_LSCALAR:
|
|---|
| 5384 | text = retrieve_lscalar(aTHX_ cxt, cname);
|
|---|
| 5385 | break;
|
|---|
| 5386 | default:
|
|---|
| 5387 | CROAK(("Unexpected type %d in retrieve_code\n", type));
|
|---|
| 5388 | }
|
|---|
| 5389 |
|
|---|
| 5390 | /*
|
|---|
| 5391 | * prepend "sub " to the source
|
|---|
| 5392 | */
|
|---|
| 5393 |
|
|---|
| 5394 | sub = newSVpvn("sub ", 4);
|
|---|
| 5395 | sv_catpv(sub, SvPV_nolen(text)); /* XXX no sv_catsv! */
|
|---|
| 5396 | SvREFCNT_dec(text);
|
|---|
| 5397 |
|
|---|
| 5398 | /*
|
|---|
| 5399 | * evaluate the source to a code reference and use the CV value
|
|---|
| 5400 | */
|
|---|
| 5401 |
|
|---|
| 5402 | if (cxt->eval == NULL) {
|
|---|
| 5403 | cxt->eval = perl_get_sv("Storable::Eval", TRUE);
|
|---|
| 5404 | SvREFCNT_inc(cxt->eval);
|
|---|
| 5405 | }
|
|---|
| 5406 | if (!SvTRUE(cxt->eval)) {
|
|---|
| 5407 | if (
|
|---|
| 5408 | cxt->forgive_me == 0 ||
|
|---|
| 5409 | (cxt->forgive_me < 0 && !(cxt->forgive_me =
|
|---|
| 5410 | SvTRUE(perl_get_sv("Storable::forgive_me", TRUE)) ? 1 : 0))
|
|---|
| 5411 | ) {
|
|---|
| 5412 | CROAK(("Can't eval, please set $Storable::Eval to a true value"));
|
|---|
| 5413 | } else {
|
|---|
| 5414 | sv = newSVsv(sub);
|
|---|
| 5415 | /* fix up the dummy entry... */
|
|---|
| 5416 | av_store(cxt->aseen, tagnum, SvREFCNT_inc(sv));
|
|---|
| 5417 | return sv;
|
|---|
| 5418 | }
|
|---|
| 5419 | }
|
|---|
| 5420 |
|
|---|
| 5421 | ENTER;
|
|---|
| 5422 | SAVETMPS;
|
|---|
| 5423 |
|
|---|
| 5424 | if (SvROK(cxt->eval) && SvTYPE(SvRV(cxt->eval)) == SVt_PVCV) {
|
|---|
| 5425 | SV* errsv = get_sv("@", TRUE);
|
|---|
| 5426 | sv_setpvn(errsv, "", 0); /* clear $@ */
|
|---|
| 5427 | PUSHMARK(sp);
|
|---|
| 5428 | XPUSHs(sv_2mortal(newSVsv(sub)));
|
|---|
| 5429 | PUTBACK;
|
|---|
| 5430 | count = call_sv(cxt->eval, G_SCALAR);
|
|---|
| 5431 | SPAGAIN;
|
|---|
| 5432 | if (count != 1)
|
|---|
| 5433 | CROAK(("Unexpected return value from $Storable::Eval callback\n"));
|
|---|
| 5434 | cv = POPs;
|
|---|
| 5435 | if (SvTRUE(errsv)) {
|
|---|
| 5436 | CROAK(("code %s caused an error: %s",
|
|---|
| 5437 | SvPV_nolen(sub), SvPV_nolen(errsv)));
|
|---|
| 5438 | }
|
|---|
| 5439 | PUTBACK;
|
|---|
| 5440 | } else {
|
|---|
| 5441 | cv = eval_pv(SvPV_nolen(sub), TRUE);
|
|---|
| 5442 | }
|
|---|
| 5443 | if (cv && SvROK(cv) && SvTYPE(SvRV(cv)) == SVt_PVCV) {
|
|---|
| 5444 | sv = SvRV(cv);
|
|---|
| 5445 | } else {
|
|---|
| 5446 | CROAK(("code %s did not evaluate to a subroutine reference\n", SvPV_nolen(sub)));
|
|---|
| 5447 | }
|
|---|
| 5448 |
|
|---|
| 5449 | SvREFCNT_inc(sv); /* XXX seems to be necessary */
|
|---|
| 5450 | SvREFCNT_dec(sub);
|
|---|
| 5451 |
|
|---|
| 5452 | FREETMPS;
|
|---|
| 5453 | LEAVE;
|
|---|
| 5454 | /* fix up the dummy entry... */
|
|---|
| 5455 | av_store(cxt->aseen, tagnum, SvREFCNT_inc(sv));
|
|---|
| 5456 |
|
|---|
| 5457 | return sv;
|
|---|
| 5458 | #endif
|
|---|
| 5459 | }
|
|---|
| 5460 |
|
|---|
| 5461 | /*
|
|---|
| 5462 | * old_retrieve_array
|
|---|
| 5463 | *
|
|---|
| 5464 | * Retrieve a whole array in pre-0.6 binary format.
|
|---|
| 5465 | *
|
|---|
| 5466 | * Layout is SX_ARRAY <size> followed by each item, in increading index order.
|
|---|
| 5467 | * Each item is stored as SX_ITEM <object> or SX_IT_UNDEF for "holes".
|
|---|
| 5468 | *
|
|---|
| 5469 | * When we come here, SX_ARRAY has been read already.
|
|---|
| 5470 | */
|
|---|
| 5471 | static SV *old_retrieve_array(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5472 | {
|
|---|
| 5473 | I32 len;
|
|---|
| 5474 | I32 i;
|
|---|
| 5475 | AV *av;
|
|---|
| 5476 | SV *sv;
|
|---|
| 5477 | int c;
|
|---|
| 5478 |
|
|---|
| 5479 | TRACEME(("old_retrieve_array (#%d)", cxt->tagnum));
|
|---|
| 5480 |
|
|---|
| 5481 | /*
|
|---|
| 5482 | * Read length, and allocate array, then pre-extend it.
|
|---|
| 5483 | */
|
|---|
| 5484 |
|
|---|
| 5485 | RLEN(len);
|
|---|
| 5486 | TRACEME(("size = %d", len));
|
|---|
| 5487 | av = newAV();
|
|---|
| 5488 | SEEN(av, 0, 0); /* Will return if array not allocated nicely */
|
|---|
| 5489 | if (len)
|
|---|
| 5490 | av_extend(av, len);
|
|---|
| 5491 | else
|
|---|
| 5492 | return (SV *) av; /* No data follow if array is empty */
|
|---|
| 5493 |
|
|---|
| 5494 | /*
|
|---|
| 5495 | * Now get each item in turn...
|
|---|
| 5496 | */
|
|---|
| 5497 |
|
|---|
| 5498 | for (i = 0; i < len; i++) {
|
|---|
| 5499 | GETMARK(c);
|
|---|
| 5500 | if (c == SX_IT_UNDEF) {
|
|---|
| 5501 | TRACEME(("(#%d) undef item", i));
|
|---|
| 5502 | continue; /* av_extend() already filled us with undef */
|
|---|
| 5503 | }
|
|---|
| 5504 | if (c != SX_ITEM)
|
|---|
| 5505 | (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
|
|---|
| 5506 | TRACEME(("(#%d) item", i));
|
|---|
| 5507 | sv = retrieve(aTHX_ cxt, 0); /* Retrieve item */
|
|---|
| 5508 | if (!sv)
|
|---|
| 5509 | return (SV *) 0;
|
|---|
| 5510 | if (av_store(av, i, sv) == 0)
|
|---|
| 5511 | return (SV *) 0;
|
|---|
| 5512 | }
|
|---|
| 5513 |
|
|---|
| 5514 | TRACEME(("ok (old_retrieve_array at 0x%"UVxf")", PTR2UV(av)));
|
|---|
| 5515 |
|
|---|
| 5516 | return (SV *) av;
|
|---|
| 5517 | }
|
|---|
| 5518 |
|
|---|
| 5519 | /*
|
|---|
| 5520 | * old_retrieve_hash
|
|---|
| 5521 | *
|
|---|
| 5522 | * Retrieve a whole hash table in pre-0.6 binary format.
|
|---|
| 5523 | *
|
|---|
| 5524 | * Layout is SX_HASH <size> followed by each key/value pair, in random order.
|
|---|
| 5525 | * Keys are stored as SX_KEY <length> <data>, the <data> section being omitted
|
|---|
| 5526 | * if length is 0.
|
|---|
| 5527 | * Values are stored as SX_VALUE <object> or SX_VL_UNDEF for "holes".
|
|---|
| 5528 | *
|
|---|
| 5529 | * When we come here, SX_HASH has been read already.
|
|---|
| 5530 | */
|
|---|
| 5531 | static SV *old_retrieve_hash(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5532 | {
|
|---|
| 5533 | I32 len;
|
|---|
| 5534 | I32 size;
|
|---|
| 5535 | I32 i;
|
|---|
| 5536 | HV *hv;
|
|---|
| 5537 | SV *sv = (SV *) 0;
|
|---|
| 5538 | int c;
|
|---|
| 5539 | SV *sv_h_undef = (SV *) 0; /* hv_store() bug */
|
|---|
| 5540 |
|
|---|
| 5541 | TRACEME(("old_retrieve_hash (#%d)", cxt->tagnum));
|
|---|
| 5542 |
|
|---|
| 5543 | /*
|
|---|
| 5544 | * Read length, allocate table.
|
|---|
| 5545 | */
|
|---|
| 5546 |
|
|---|
| 5547 | RLEN(len);
|
|---|
| 5548 | TRACEME(("size = %d", len));
|
|---|
| 5549 | hv = newHV();
|
|---|
| 5550 | SEEN(hv, 0, 0); /* Will return if table not allocated properly */
|
|---|
| 5551 | if (len == 0)
|
|---|
| 5552 | return (SV *) hv; /* No data follow if table empty */
|
|---|
| 5553 | hv_ksplit(hv, len); /* pre-extend hash to save multiple splits */
|
|---|
| 5554 |
|
|---|
| 5555 | /*
|
|---|
| 5556 | * Now get each key/value pair in turn...
|
|---|
| 5557 | */
|
|---|
| 5558 |
|
|---|
| 5559 | for (i = 0; i < len; i++) {
|
|---|
| 5560 | /*
|
|---|
| 5561 | * Get value first.
|
|---|
| 5562 | */
|
|---|
| 5563 |
|
|---|
| 5564 | GETMARK(c);
|
|---|
| 5565 | if (c == SX_VL_UNDEF) {
|
|---|
| 5566 | TRACEME(("(#%d) undef value", i));
|
|---|
| 5567 | /*
|
|---|
| 5568 | * Due to a bug in hv_store(), it's not possible to pass
|
|---|
| 5569 | * &PL_sv_undef to hv_store() as a value, otherwise the
|
|---|
| 5570 | * associated key will not be creatable any more. -- RAM, 14/01/97
|
|---|
| 5571 | */
|
|---|
| 5572 | if (!sv_h_undef)
|
|---|
| 5573 | sv_h_undef = newSVsv(&PL_sv_undef);
|
|---|
| 5574 | sv = SvREFCNT_inc(sv_h_undef);
|
|---|
| 5575 | } else if (c == SX_VALUE) {
|
|---|
| 5576 | TRACEME(("(#%d) value", i));
|
|---|
| 5577 | sv = retrieve(aTHX_ cxt, 0);
|
|---|
| 5578 | if (!sv)
|
|---|
| 5579 | return (SV *) 0;
|
|---|
| 5580 | } else
|
|---|
| 5581 | (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
|
|---|
| 5582 |
|
|---|
| 5583 | /*
|
|---|
| 5584 | * Get key.
|
|---|
| 5585 | * Since we're reading into kbuf, we must ensure we're not
|
|---|
| 5586 | * recursing between the read and the hv_store() where it's used.
|
|---|
| 5587 | * Hence the key comes after the value.
|
|---|
| 5588 | */
|
|---|
| 5589 |
|
|---|
| 5590 | GETMARK(c);
|
|---|
| 5591 | if (c != SX_KEY)
|
|---|
| 5592 | (void) retrieve_other(aTHX_ (stcxt_t *) 0, 0); /* Will croak out */
|
|---|
| 5593 | RLEN(size); /* Get key size */
|
|---|
| 5594 | KBUFCHK((STRLEN)size); /* Grow hash key read pool if needed */
|
|---|
| 5595 | if (size)
|
|---|
| 5596 | READ(kbuf, size);
|
|---|
| 5597 | kbuf[size] = '\0'; /* Mark string end, just in case */
|
|---|
| 5598 | TRACEME(("(#%d) key '%s'", i, kbuf));
|
|---|
| 5599 |
|
|---|
| 5600 | /*
|
|---|
| 5601 | * Enter key/value pair into hash table.
|
|---|
| 5602 | */
|
|---|
| 5603 |
|
|---|
| 5604 | if (hv_store(hv, kbuf, (U32) size, sv, 0) == 0)
|
|---|
| 5605 | return (SV *) 0;
|
|---|
| 5606 | }
|
|---|
| 5607 |
|
|---|
| 5608 | TRACEME(("ok (retrieve_hash at 0x%"UVxf")", PTR2UV(hv)));
|
|---|
| 5609 |
|
|---|
| 5610 | return (SV *) hv;
|
|---|
| 5611 | }
|
|---|
| 5612 |
|
|---|
| 5613 | /***
|
|---|
| 5614 | *** Retrieval engine.
|
|---|
| 5615 | ***/
|
|---|
| 5616 |
|
|---|
| 5617 | /*
|
|---|
| 5618 | * magic_check
|
|---|
| 5619 | *
|
|---|
| 5620 | * Make sure the stored data we're trying to retrieve has been produced
|
|---|
| 5621 | * on an ILP compatible system with the same byteorder. It croaks out in
|
|---|
| 5622 | * case an error is detected. [ILP = integer-long-pointer sizes]
|
|---|
| 5623 | * Returns null if error is detected, &PL_sv_undef otherwise.
|
|---|
| 5624 | *
|
|---|
| 5625 | * Note that there's no byte ordering info emitted when network order was
|
|---|
| 5626 | * used at store time.
|
|---|
| 5627 | */
|
|---|
| 5628 | static SV *magic_check(pTHX_ stcxt_t *cxt)
|
|---|
| 5629 | {
|
|---|
| 5630 | /* The worst case for a malicious header would be old magic (which is
|
|---|
| 5631 | longer), major, minor, byteorder length byte of 255, 255 bytes of
|
|---|
| 5632 | garbage, sizeof int, long, pointer, NV.
|
|---|
| 5633 | So the worse of that we can read is 255 bytes of garbage plus 4.
|
|---|
| 5634 | Err, I am assuming 8 bit bytes here. Please file a bug report if you're
|
|---|
| 5635 | compiling perl on a system with chars that are larger than 8 bits.
|
|---|
| 5636 | (Even Crays aren't *that* perverse).
|
|---|
| 5637 | */
|
|---|
| 5638 | unsigned char buf[4 + 255];
|
|---|
| 5639 | unsigned char *current;
|
|---|
| 5640 | int c;
|
|---|
| 5641 | int length;
|
|---|
| 5642 | int use_network_order;
|
|---|
| 5643 | int use_NV_size;
|
|---|
| 5644 | int version_major;
|
|---|
| 5645 | int version_minor = 0;
|
|---|
| 5646 |
|
|---|
| 5647 | TRACEME(("magic_check"));
|
|---|
| 5648 |
|
|---|
| 5649 | /*
|
|---|
| 5650 | * The "magic number" is only for files, not when freezing in memory.
|
|---|
| 5651 | */
|
|---|
| 5652 |
|
|---|
| 5653 | if (cxt->fio) {
|
|---|
| 5654 | /* This includes the '\0' at the end. I want to read the extra byte,
|
|---|
| 5655 | which is usually going to be the major version number. */
|
|---|
| 5656 | STRLEN len = sizeof(magicstr);
|
|---|
| 5657 | STRLEN old_len;
|
|---|
| 5658 |
|
|---|
| 5659 | READ(buf, (SSize_t)(len)); /* Not null-terminated */
|
|---|
| 5660 |
|
|---|
| 5661 | /* Point at the byte after the byte we read. */
|
|---|
| 5662 | current = buf + --len; /* Do the -- outside of macros. */
|
|---|
| 5663 |
|
|---|
| 5664 | if (memNE(buf, magicstr, len)) {
|
|---|
| 5665 | /*
|
|---|
| 5666 | * Try to read more bytes to check for the old magic number, which
|
|---|
| 5667 | * was longer.
|
|---|
| 5668 | */
|
|---|
| 5669 |
|
|---|
| 5670 | TRACEME(("trying for old magic number"));
|
|---|
| 5671 |
|
|---|
| 5672 | old_len = sizeof(old_magicstr) - 1;
|
|---|
| 5673 | READ(current + 1, (SSize_t)(old_len - len));
|
|---|
| 5674 |
|
|---|
| 5675 | if (memNE(buf, old_magicstr, old_len))
|
|---|
| 5676 | CROAK(("File is not a perl storable"));
|
|---|
| 5677 | current = buf + old_len;
|
|---|
| 5678 | }
|
|---|
| 5679 | use_network_order = *current;
|
|---|
| 5680 | } else
|
|---|
| 5681 | GETMARK(use_network_order);
|
|---|
| 5682 |
|
|---|
| 5683 | /*
|
|---|
| 5684 | * Starting with 0.6, the "use_network_order" byte flag is also used to
|
|---|
| 5685 | * indicate the version number of the binary, and therefore governs the
|
|---|
| 5686 | * setting of sv_retrieve_vtbl. See magic_write().
|
|---|
| 5687 | */
|
|---|
| 5688 |
|
|---|
| 5689 | version_major = use_network_order >> 1;
|
|---|
| 5690 | cxt->retrieve_vtbl = (SV*(**)(pTHX_ stcxt_t *cxt, char *cname)) (version_major ? sv_retrieve : sv_old_retrieve);
|
|---|
| 5691 |
|
|---|
| 5692 | TRACEME(("magic_check: netorder = 0x%x", use_network_order));
|
|---|
| 5693 |
|
|---|
| 5694 |
|
|---|
| 5695 | /*
|
|---|
| 5696 | * Starting with 0.7 (binary major 2), a full byte is dedicated to the
|
|---|
| 5697 | * minor version of the protocol. See magic_write().
|
|---|
| 5698 | */
|
|---|
| 5699 |
|
|---|
| 5700 | if (version_major > 1)
|
|---|
| 5701 | GETMARK(version_minor);
|
|---|
| 5702 |
|
|---|
| 5703 | cxt->ver_major = version_major;
|
|---|
| 5704 | cxt->ver_minor = version_minor;
|
|---|
| 5705 |
|
|---|
| 5706 | TRACEME(("binary image version is %d.%d", version_major, version_minor));
|
|---|
| 5707 |
|
|---|
| 5708 | /*
|
|---|
| 5709 | * Inter-operability sanity check: we can't retrieve something stored
|
|---|
| 5710 | * using a format more recent than ours, because we have no way to
|
|---|
| 5711 | * know what has changed, and letting retrieval go would mean a probable
|
|---|
| 5712 | * failure reporting a "corrupted" storable file.
|
|---|
| 5713 | */
|
|---|
| 5714 |
|
|---|
| 5715 | if (
|
|---|
| 5716 | version_major > STORABLE_BIN_MAJOR ||
|
|---|
| 5717 | (version_major == STORABLE_BIN_MAJOR &&
|
|---|
| 5718 | version_minor > STORABLE_BIN_MINOR)
|
|---|
| 5719 | ) {
|
|---|
| 5720 | int croak_now = 1;
|
|---|
| 5721 | TRACEME(("but I am version is %d.%d", STORABLE_BIN_MAJOR,
|
|---|
| 5722 | STORABLE_BIN_MINOR));
|
|---|
| 5723 |
|
|---|
| 5724 | if (version_major == STORABLE_BIN_MAJOR) {
|
|---|
| 5725 | TRACEME(("cxt->accept_future_minor is %d",
|
|---|
| 5726 | cxt->accept_future_minor));
|
|---|
| 5727 | if (cxt->accept_future_minor < 0)
|
|---|
| 5728 | cxt->accept_future_minor
|
|---|
| 5729 | = (SvTRUE(perl_get_sv("Storable::accept_future_minor",
|
|---|
| 5730 | TRUE))
|
|---|
| 5731 | ? 1 : 0);
|
|---|
| 5732 | if (cxt->accept_future_minor == 1)
|
|---|
| 5733 | croak_now = 0; /* Don't croak yet. */
|
|---|
| 5734 | }
|
|---|
| 5735 | if (croak_now) {
|
|---|
| 5736 | CROAK(("Storable binary image v%d.%d more recent than I am (v%d.%d)",
|
|---|
| 5737 | version_major, version_minor,
|
|---|
| 5738 | STORABLE_BIN_MAJOR, STORABLE_BIN_MINOR));
|
|---|
| 5739 | }
|
|---|
| 5740 | }
|
|---|
| 5741 |
|
|---|
| 5742 | /*
|
|---|
| 5743 | * If they stored using network order, there's no byte ordering
|
|---|
| 5744 | * information to check.
|
|---|
| 5745 | */
|
|---|
| 5746 |
|
|---|
| 5747 | if ((cxt->netorder = (use_network_order & 0x1))) /* Extra () for -Wall */
|
|---|
| 5748 | return &PL_sv_undef; /* No byte ordering info */
|
|---|
| 5749 |
|
|---|
| 5750 | /* In C truth is 1, falsehood is 0. Very convienient. */
|
|---|
| 5751 | use_NV_size = version_major >= 2 && version_minor >= 2;
|
|---|
| 5752 |
|
|---|
| 5753 | GETMARK(c);
|
|---|
| 5754 | length = c + 3 + use_NV_size;
|
|---|
| 5755 | READ(buf, length); /* Not null-terminated */
|
|---|
| 5756 |
|
|---|
| 5757 | TRACEME(("byte order '%.*s' %d", c, buf, c));
|
|---|
| 5758 |
|
|---|
| 5759 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 5760 | /* No point in caching this in the context as we only need it once per
|
|---|
| 5761 | retrieve, and we need to recheck it each read. */
|
|---|
| 5762 | if (SvTRUE(perl_get_sv("Storable::interwork_56_64bit", TRUE))) {
|
|---|
| 5763 | if ((c != (sizeof (byteorderstr_56) - 1))
|
|---|
| 5764 | || memNE(buf, byteorderstr_56, c))
|
|---|
| 5765 | CROAK(("Byte order is not compatible"));
|
|---|
| 5766 | } else
|
|---|
| 5767 | #endif
|
|---|
| 5768 | {
|
|---|
| 5769 | if ((c != (sizeof (byteorderstr) - 1)) || memNE(buf, byteorderstr, c))
|
|---|
| 5770 | CROAK(("Byte order is not compatible"));
|
|---|
| 5771 | }
|
|---|
| 5772 |
|
|---|
| 5773 | current = buf + c;
|
|---|
| 5774 |
|
|---|
| 5775 | /* sizeof(int) */
|
|---|
| 5776 | if ((int) *current++ != sizeof(int))
|
|---|
| 5777 | CROAK(("Integer size is not compatible"));
|
|---|
| 5778 |
|
|---|
| 5779 | /* sizeof(long) */
|
|---|
| 5780 | if ((int) *current++ != sizeof(long))
|
|---|
| 5781 | CROAK(("Long integer size is not compatible"));
|
|---|
| 5782 |
|
|---|
| 5783 | /* sizeof(char *) */
|
|---|
| 5784 | if ((int) *current != sizeof(char *))
|
|---|
| 5785 | CROAK(("Pointer size is not compatible"));
|
|---|
| 5786 |
|
|---|
| 5787 | if (use_NV_size) {
|
|---|
| 5788 | /* sizeof(NV) */
|
|---|
| 5789 | if ((int) *++current != sizeof(NV))
|
|---|
| 5790 | CROAK(("Double size is not compatible"));
|
|---|
| 5791 | }
|
|---|
| 5792 |
|
|---|
| 5793 | return &PL_sv_undef; /* OK */
|
|---|
| 5794 | }
|
|---|
| 5795 |
|
|---|
| 5796 | /*
|
|---|
| 5797 | * retrieve
|
|---|
| 5798 | *
|
|---|
| 5799 | * Recursively retrieve objects from the specified file and return their
|
|---|
| 5800 | * root SV (which may be an AV or an HV for what we care).
|
|---|
| 5801 | * Returns null if there is a problem.
|
|---|
| 5802 | */
|
|---|
| 5803 | static SV *retrieve(pTHX_ stcxt_t *cxt, char *cname)
|
|---|
| 5804 | {
|
|---|
| 5805 | int type;
|
|---|
| 5806 | SV **svh;
|
|---|
| 5807 | SV *sv;
|
|---|
| 5808 |
|
|---|
| 5809 | TRACEME(("retrieve"));
|
|---|
| 5810 |
|
|---|
| 5811 | /*
|
|---|
| 5812 | * Grab address tag which identifies the object if we are retrieving
|
|---|
| 5813 | * an older format. Since the new binary format counts objects and no
|
|---|
| 5814 | * longer explicitely tags them, we must keep track of the correspondance
|
|---|
| 5815 | * ourselves.
|
|---|
| 5816 | *
|
|---|
| 5817 | * The following section will disappear one day when the old format is
|
|---|
| 5818 | * no longer supported, hence the final "goto" in the "if" block.
|
|---|
| 5819 | */
|
|---|
| 5820 |
|
|---|
| 5821 | if (cxt->hseen) { /* Retrieving old binary */
|
|---|
| 5822 | stag_t tag;
|
|---|
| 5823 | if (cxt->netorder) {
|
|---|
| 5824 | I32 nettag;
|
|---|
| 5825 | READ(&nettag, sizeof(I32)); /* Ordered sequence of I32 */
|
|---|
| 5826 | tag = (stag_t) nettag;
|
|---|
| 5827 | } else
|
|---|
| 5828 | READ(&tag, sizeof(stag_t)); /* Original address of the SV */
|
|---|
| 5829 |
|
|---|
| 5830 | GETMARK(type);
|
|---|
| 5831 | if (type == SX_OBJECT) {
|
|---|
| 5832 | I32 tagn;
|
|---|
| 5833 | svh = hv_fetch(cxt->hseen, (char *) &tag, sizeof(tag), FALSE);
|
|---|
| 5834 | if (!svh)
|
|---|
| 5835 | CROAK(("Old tag 0x%"UVxf" should have been mapped already",
|
|---|
| 5836 | (UV) tag));
|
|---|
| 5837 | tagn = SvIV(*svh); /* Mapped tag number computed earlier below */
|
|---|
| 5838 |
|
|---|
| 5839 | /*
|
|---|
| 5840 | * The following code is common with the SX_OBJECT case below.
|
|---|
| 5841 | */
|
|---|
| 5842 |
|
|---|
| 5843 | svh = av_fetch(cxt->aseen, tagn, FALSE);
|
|---|
| 5844 | if (!svh)
|
|---|
| 5845 | CROAK(("Object #%"IVdf" should have been retrieved already",
|
|---|
| 5846 | (IV) tagn));
|
|---|
| 5847 | sv = *svh;
|
|---|
| 5848 | TRACEME(("has retrieved #%d at 0x%"UVxf, tagn, PTR2UV(sv)));
|
|---|
| 5849 | SvREFCNT_inc(sv); /* One more reference to this same sv */
|
|---|
| 5850 | return sv; /* The SV pointer where object was retrieved */
|
|---|
| 5851 | }
|
|---|
| 5852 |
|
|---|
| 5853 | /*
|
|---|
| 5854 | * Map new object, but don't increase tagnum. This will be done
|
|---|
| 5855 | * by each of the retrieve_* functions when they call SEEN().
|
|---|
| 5856 | *
|
|---|
| 5857 | * The mapping associates the "tag" initially present with a unique
|
|---|
| 5858 | * tag number. See test for SX_OBJECT above to see how this is perused.
|
|---|
| 5859 | */
|
|---|
| 5860 |
|
|---|
| 5861 | if (!hv_store(cxt->hseen, (char *) &tag, sizeof(tag),
|
|---|
| 5862 | newSViv(cxt->tagnum), 0))
|
|---|
| 5863 | return (SV *) 0;
|
|---|
| 5864 |
|
|---|
| 5865 | goto first_time;
|
|---|
| 5866 | }
|
|---|
| 5867 |
|
|---|
| 5868 | /*
|
|---|
| 5869 | * Regular post-0.6 binary format.
|
|---|
| 5870 | */
|
|---|
| 5871 |
|
|---|
| 5872 | GETMARK(type);
|
|---|
| 5873 |
|
|---|
| 5874 | TRACEME(("retrieve type = %d", type));
|
|---|
| 5875 |
|
|---|
| 5876 | /*
|
|---|
| 5877 | * Are we dealing with an object we should have already retrieved?
|
|---|
| 5878 | */
|
|---|
| 5879 |
|
|---|
| 5880 | if (type == SX_OBJECT) {
|
|---|
| 5881 | I32 tag;
|
|---|
| 5882 | READ_I32(tag);
|
|---|
| 5883 | tag = ntohl(tag);
|
|---|
| 5884 | svh = av_fetch(cxt->aseen, tag, FALSE);
|
|---|
| 5885 | if (!svh)
|
|---|
| 5886 | CROAK(("Object #%"IVdf" should have been retrieved already",
|
|---|
| 5887 | (IV) tag));
|
|---|
| 5888 | sv = *svh;
|
|---|
| 5889 | TRACEME(("had retrieved #%d at 0x%"UVxf, tag, PTR2UV(sv)));
|
|---|
| 5890 | SvREFCNT_inc(sv); /* One more reference to this same sv */
|
|---|
| 5891 | return sv; /* The SV pointer where object was retrieved */
|
|---|
| 5892 | } else if (type >= SX_ERROR && cxt->ver_minor > STORABLE_BIN_MINOR) {
|
|---|
| 5893 | if (cxt->accept_future_minor < 0)
|
|---|
| 5894 | cxt->accept_future_minor
|
|---|
| 5895 | = (SvTRUE(perl_get_sv("Storable::accept_future_minor",
|
|---|
| 5896 | TRUE))
|
|---|
| 5897 | ? 1 : 0);
|
|---|
| 5898 | if (cxt->accept_future_minor == 1) {
|
|---|
| 5899 | CROAK(("Storable binary image v%d.%d contains data of type %d. "
|
|---|
| 5900 | "This Storable is v%d.%d and can only handle data types up to %d",
|
|---|
| 5901 | cxt->ver_major, cxt->ver_minor, type,
|
|---|
| 5902 | STORABLE_BIN_MAJOR, STORABLE_BIN_MINOR, SX_ERROR - 1));
|
|---|
| 5903 | }
|
|---|
| 5904 | }
|
|---|
| 5905 |
|
|---|
| 5906 | first_time: /* Will disappear when support for old format is dropped */
|
|---|
| 5907 |
|
|---|
| 5908 | /*
|
|---|
| 5909 | * Okay, first time through for this one.
|
|---|
| 5910 | */
|
|---|
| 5911 |
|
|---|
| 5912 | sv = RETRIEVE(cxt, type)(aTHX_ cxt, cname);
|
|---|
| 5913 | if (!sv)
|
|---|
| 5914 | return (SV *) 0; /* Failed */
|
|---|
| 5915 |
|
|---|
| 5916 | /*
|
|---|
| 5917 | * Old binary formats (pre-0.7).
|
|---|
| 5918 | *
|
|---|
| 5919 | * Final notifications, ended by SX_STORED may now follow.
|
|---|
| 5920 | * Currently, the only pertinent notification to apply on the
|
|---|
| 5921 | * freshly retrieved object is either:
|
|---|
| 5922 | * SX_CLASS <char-len> <classname> for short classnames.
|
|---|
| 5923 | * SX_LG_CLASS <int-len> <classname> for larger one (rare!).
|
|---|
| 5924 | * Class name is then read into the key buffer pool used by
|
|---|
| 5925 | * hash table key retrieval.
|
|---|
| 5926 | */
|
|---|
| 5927 |
|
|---|
| 5928 | if (cxt->ver_major < 2) {
|
|---|
| 5929 | while ((type = GETCHAR()) != SX_STORED) {
|
|---|
| 5930 | I32 len;
|
|---|
| 5931 | switch (type) {
|
|---|
| 5932 | case SX_CLASS:
|
|---|
| 5933 | GETMARK(len); /* Length coded on a single char */
|
|---|
| 5934 | break;
|
|---|
| 5935 | case SX_LG_CLASS: /* Length coded on a regular integer */
|
|---|
| 5936 | RLEN(len);
|
|---|
| 5937 | break;
|
|---|
| 5938 | case EOF:
|
|---|
| 5939 | default:
|
|---|
| 5940 | return (SV *) 0; /* Failed */
|
|---|
| 5941 | }
|
|---|
| 5942 | KBUFCHK((STRLEN)len); /* Grow buffer as necessary */
|
|---|
| 5943 | if (len)
|
|---|
| 5944 | READ(kbuf, len);
|
|---|
| 5945 | kbuf[len] = '\0'; /* Mark string end */
|
|---|
| 5946 | BLESS(sv, kbuf);
|
|---|
| 5947 | }
|
|---|
| 5948 | }
|
|---|
| 5949 |
|
|---|
| 5950 | TRACEME(("ok (retrieved 0x%"UVxf", refcnt=%d, %s)", PTR2UV(sv),
|
|---|
| 5951 | SvREFCNT(sv) - 1, sv_reftype(sv, FALSE)));
|
|---|
| 5952 |
|
|---|
| 5953 | return sv; /* Ok */
|
|---|
| 5954 | }
|
|---|
| 5955 |
|
|---|
| 5956 | /*
|
|---|
| 5957 | * do_retrieve
|
|---|
| 5958 | *
|
|---|
| 5959 | * Retrieve data held in file and return the root object.
|
|---|
| 5960 | * Common routine for pretrieve and mretrieve.
|
|---|
| 5961 | */
|
|---|
| 5962 | static SV *do_retrieve(
|
|---|
| 5963 | pTHX_
|
|---|
| 5964 | PerlIO *f,
|
|---|
| 5965 | SV *in,
|
|---|
| 5966 | int optype)
|
|---|
| 5967 | {
|
|---|
| 5968 | dSTCXT;
|
|---|
| 5969 | SV *sv;
|
|---|
| 5970 | int is_tainted; /* Is input source tainted? */
|
|---|
| 5971 | int pre_06_fmt = 0; /* True with pre Storable 0.6 formats */
|
|---|
| 5972 |
|
|---|
| 5973 | TRACEME(("do_retrieve (optype = 0x%x)", optype));
|
|---|
| 5974 |
|
|---|
| 5975 | optype |= ST_RETRIEVE;
|
|---|
| 5976 |
|
|---|
| 5977 | /*
|
|---|
| 5978 | * Sanity assertions for retrieve dispatch tables.
|
|---|
| 5979 | */
|
|---|
| 5980 |
|
|---|
| 5981 | ASSERT(sizeof(sv_old_retrieve) == sizeof(sv_retrieve),
|
|---|
| 5982 | ("old and new retrieve dispatch table have same size"));
|
|---|
| 5983 | ASSERT(sv_old_retrieve[SX_ERROR] == retrieve_other,
|
|---|
| 5984 | ("SX_ERROR entry correctly initialized in old dispatch table"));
|
|---|
| 5985 | ASSERT(sv_retrieve[SX_ERROR] == retrieve_other,
|
|---|
| 5986 | ("SX_ERROR entry correctly initialized in new dispatch table"));
|
|---|
| 5987 |
|
|---|
| 5988 | /*
|
|---|
| 5989 | * Workaround for CROAK leak: if they enter with a "dirty" context,
|
|---|
| 5990 | * free up memory for them now.
|
|---|
| 5991 | */
|
|---|
| 5992 |
|
|---|
| 5993 | if (cxt->s_dirty)
|
|---|
| 5994 | clean_context(aTHX_ cxt);
|
|---|
| 5995 |
|
|---|
| 5996 | /*
|
|---|
| 5997 | * Now that STORABLE_xxx hooks exist, it is possible that they try to
|
|---|
| 5998 | * re-enter retrieve() via the hooks.
|
|---|
| 5999 | */
|
|---|
| 6000 |
|
|---|
| 6001 | if (cxt->entry)
|
|---|
| 6002 | cxt = allocate_context(aTHX_ cxt);
|
|---|
| 6003 |
|
|---|
| 6004 | cxt->entry++;
|
|---|
| 6005 |
|
|---|
| 6006 | ASSERT(cxt->entry == 1, ("starting new recursion"));
|
|---|
| 6007 | ASSERT(!cxt->s_dirty, ("clean context"));
|
|---|
| 6008 |
|
|---|
| 6009 | /*
|
|---|
| 6010 | * Prepare context.
|
|---|
| 6011 | *
|
|---|
| 6012 | * Data is loaded into the memory buffer when f is NULL, unless `in' is
|
|---|
| 6013 | * also NULL, in which case we're expecting the data to already lie
|
|---|
| 6014 | * in the buffer (dclone case).
|
|---|
| 6015 | */
|
|---|
| 6016 |
|
|---|
| 6017 | KBUFINIT(); /* Allocate hash key reading pool once */
|
|---|
| 6018 |
|
|---|
| 6019 | if (!f && in) {
|
|---|
| 6020 | #ifdef SvUTF8_on
|
|---|
| 6021 | if (SvUTF8(in)) {
|
|---|
| 6022 | STRLEN length;
|
|---|
| 6023 | const char *orig = SvPV(in, length);
|
|---|
| 6024 | char *asbytes;
|
|---|
| 6025 | /* This is quite deliberate. I want the UTF8 routines
|
|---|
| 6026 | to encounter the '\0' which perl adds at the end
|
|---|
| 6027 | of all scalars, so that any new string also has
|
|---|
| 6028 | this.
|
|---|
| 6029 | */
|
|---|
| 6030 | STRLEN klen_tmp = length + 1;
|
|---|
| 6031 | bool is_utf8 = TRUE;
|
|---|
| 6032 |
|
|---|
| 6033 | /* Just casting the &klen to (STRLEN) won't work
|
|---|
| 6034 | well if STRLEN and I32 are of different widths.
|
|---|
| 6035 | --jhi */
|
|---|
| 6036 | asbytes = (char*)bytes_from_utf8((U8*)orig,
|
|---|
| 6037 | &klen_tmp,
|
|---|
| 6038 | &is_utf8);
|
|---|
| 6039 | if (is_utf8) {
|
|---|
| 6040 | CROAK(("Frozen string corrupt - contains characters outside 0-255"));
|
|---|
| 6041 | }
|
|---|
| 6042 | if (asbytes != orig) {
|
|---|
| 6043 | /* String has been converted.
|
|---|
| 6044 | There is no need to keep any reference to
|
|---|
| 6045 | the old string. */
|
|---|
| 6046 | in = sv_newmortal();
|
|---|
| 6047 | /* We donate the SV the malloc()ed string
|
|---|
| 6048 | bytes_from_utf8 returned us. */
|
|---|
| 6049 | SvUPGRADE(in, SVt_PV);
|
|---|
| 6050 | SvPOK_on(in);
|
|---|
| 6051 | SvPV_set(in, asbytes);
|
|---|
| 6052 | SvLEN_set(in, klen_tmp);
|
|---|
| 6053 | SvCUR_set(in, klen_tmp - 1);
|
|---|
| 6054 | }
|
|---|
| 6055 | }
|
|---|
| 6056 | #endif
|
|---|
| 6057 | MBUF_SAVE_AND_LOAD(in);
|
|---|
| 6058 | }
|
|---|
| 6059 |
|
|---|
| 6060 | /*
|
|---|
| 6061 | * Magic number verifications.
|
|---|
| 6062 | *
|
|---|
| 6063 | * This needs to be done before calling init_retrieve_context()
|
|---|
| 6064 | * since the format indication in the file are necessary to conduct
|
|---|
| 6065 | * some of the initializations.
|
|---|
| 6066 | */
|
|---|
| 6067 |
|
|---|
| 6068 | cxt->fio = f; /* Where I/O are performed */
|
|---|
| 6069 |
|
|---|
| 6070 | if (!magic_check(aTHX_ cxt))
|
|---|
| 6071 | CROAK(("Magic number checking on storable %s failed",
|
|---|
| 6072 | cxt->fio ? "file" : "string"));
|
|---|
| 6073 |
|
|---|
| 6074 | TRACEME(("data stored in %s format",
|
|---|
| 6075 | cxt->netorder ? "net order" : "native"));
|
|---|
| 6076 |
|
|---|
| 6077 | /*
|
|---|
| 6078 | * Check whether input source is tainted, so that we don't wrongly
|
|---|
| 6079 | * taint perfectly good values...
|
|---|
| 6080 | *
|
|---|
| 6081 | * We assume file input is always tainted. If both `f' and `in' are
|
|---|
| 6082 | * NULL, then we come from dclone, and tainted is already filled in
|
|---|
| 6083 | * the context. That's a kludge, but the whole dclone() thing is
|
|---|
| 6084 | * already quite a kludge anyway! -- RAM, 15/09/2000.
|
|---|
| 6085 | */
|
|---|
| 6086 |
|
|---|
| 6087 | is_tainted = f ? 1 : (in ? SvTAINTED(in) : cxt->s_tainted);
|
|---|
| 6088 | TRACEME(("input source is %s", is_tainted ? "tainted" : "trusted"));
|
|---|
| 6089 | init_retrieve_context(aTHX_ cxt, optype, is_tainted);
|
|---|
| 6090 |
|
|---|
| 6091 | ASSERT(is_retrieving(aTHX), ("within retrieve operation"));
|
|---|
| 6092 |
|
|---|
| 6093 | sv = retrieve(aTHX_ cxt, 0); /* Recursively retrieve object, get root SV */
|
|---|
| 6094 |
|
|---|
| 6095 | /*
|
|---|
| 6096 | * Final cleanup.
|
|---|
| 6097 | */
|
|---|
| 6098 |
|
|---|
| 6099 | if (!f && in)
|
|---|
| 6100 | MBUF_RESTORE();
|
|---|
| 6101 |
|
|---|
| 6102 | pre_06_fmt = cxt->hseen != NULL; /* Before we clean context */
|
|---|
| 6103 |
|
|---|
| 6104 | /*
|
|---|
| 6105 | * The "root" context is never freed.
|
|---|
| 6106 | */
|
|---|
| 6107 |
|
|---|
| 6108 | clean_retrieve_context(aTHX_ cxt);
|
|---|
| 6109 | if (cxt->prev) /* This context was stacked */
|
|---|
| 6110 | free_context(aTHX_ cxt); /* It was not the "root" context */
|
|---|
| 6111 |
|
|---|
| 6112 | /*
|
|---|
| 6113 | * Prepare returned value.
|
|---|
| 6114 | */
|
|---|
| 6115 |
|
|---|
| 6116 | if (!sv) {
|
|---|
| 6117 | TRACEME(("retrieve ERROR"));
|
|---|
| 6118 | #if (PATCHLEVEL <= 4)
|
|---|
| 6119 | /* perl 5.00405 seems to screw up at this point with an
|
|---|
| 6120 | 'attempt to modify a read only value' error reported in the
|
|---|
| 6121 | eval { $self = pretrieve(*FILE) } in _retrieve.
|
|---|
| 6122 | I can't see what the cause of this error is, but I suspect a
|
|---|
| 6123 | bug in 5.004, as it seems to be capable of issuing spurious
|
|---|
| 6124 | errors or core dumping with matches on $@. I'm not going to
|
|---|
| 6125 | spend time on what could be a fruitless search for the cause,
|
|---|
| 6126 | so here's a bodge. If you're running 5.004 and don't like
|
|---|
| 6127 | this inefficiency, either upgrade to a newer perl, or you are
|
|---|
| 6128 | welcome to find the problem and send in a patch.
|
|---|
| 6129 | */
|
|---|
| 6130 | return newSV(0);
|
|---|
| 6131 | #else
|
|---|
| 6132 | return &PL_sv_undef; /* Something went wrong, return undef */
|
|---|
| 6133 | #endif
|
|---|
| 6134 | }
|
|---|
| 6135 |
|
|---|
| 6136 | TRACEME(("retrieve got %s(0x%"UVxf")",
|
|---|
| 6137 | sv_reftype(sv, FALSE), PTR2UV(sv)));
|
|---|
| 6138 |
|
|---|
| 6139 | /*
|
|---|
| 6140 | * Backward compatibility with Storable-0.5@9 (which we know we
|
|---|
| 6141 | * are retrieving if hseen is non-null): don't create an extra RV
|
|---|
| 6142 | * for objects since we special-cased it at store time.
|
|---|
| 6143 | *
|
|---|
| 6144 | * Build a reference to the SV returned by pretrieve even if it is
|
|---|
| 6145 | * already one and not a scalar, for consistency reasons.
|
|---|
| 6146 | */
|
|---|
| 6147 |
|
|---|
| 6148 | if (pre_06_fmt) { /* Was not handling overloading by then */
|
|---|
| 6149 | SV *rv;
|
|---|
| 6150 | TRACEME(("fixing for old formats -- pre 0.6"));
|
|---|
| 6151 | if (sv_type(aTHX_ sv) == svis_REF && (rv = SvRV(sv)) && SvOBJECT(rv)) {
|
|---|
| 6152 | TRACEME(("ended do_retrieve() with an object -- pre 0.6"));
|
|---|
| 6153 | return sv;
|
|---|
| 6154 | }
|
|---|
| 6155 | }
|
|---|
| 6156 |
|
|---|
| 6157 | /*
|
|---|
| 6158 | * If reference is overloaded, restore behaviour.
|
|---|
| 6159 | *
|
|---|
| 6160 | * NB: minor glitch here: normally, overloaded refs are stored specially
|
|---|
| 6161 | * so that we can croak when behaviour cannot be re-installed, and also
|
|---|
| 6162 | * avoid testing for overloading magic at each reference retrieval.
|
|---|
| 6163 | *
|
|---|
| 6164 | * Unfortunately, the root reference is implicitely stored, so we must
|
|---|
| 6165 | * check for possible overloading now. Furthermore, if we don't restore
|
|---|
| 6166 | * overloading, we cannot croak as if the original ref was, because we
|
|---|
| 6167 | * have no way to determine whether it was an overloaded ref or not in
|
|---|
| 6168 | * the first place.
|
|---|
| 6169 | *
|
|---|
| 6170 | * It's a pity that overloading magic is attached to the rv, and not to
|
|---|
| 6171 | * the underlying sv as blessing is.
|
|---|
| 6172 | */
|
|---|
| 6173 |
|
|---|
| 6174 | if (SvOBJECT(sv)) {
|
|---|
| 6175 | HV *stash = (HV *) SvSTASH(sv);
|
|---|
| 6176 | SV *rv = newRV_noinc(sv);
|
|---|
| 6177 | if (stash && Gv_AMG(stash)) {
|
|---|
| 6178 | SvAMAGIC_on(rv);
|
|---|
| 6179 | TRACEME(("restored overloading on root reference"));
|
|---|
| 6180 | }
|
|---|
| 6181 | TRACEME(("ended do_retrieve() with an object"));
|
|---|
| 6182 | return rv;
|
|---|
| 6183 | }
|
|---|
| 6184 |
|
|---|
| 6185 | TRACEME(("regular do_retrieve() end"));
|
|---|
| 6186 |
|
|---|
| 6187 | return newRV_noinc(sv);
|
|---|
| 6188 | }
|
|---|
| 6189 |
|
|---|
| 6190 | /*
|
|---|
| 6191 | * pretrieve
|
|---|
| 6192 | *
|
|---|
| 6193 | * Retrieve data held in file and return the root object, undef on error.
|
|---|
| 6194 | */
|
|---|
| 6195 | SV *pretrieve(pTHX_ PerlIO *f)
|
|---|
| 6196 | {
|
|---|
| 6197 | TRACEME(("pretrieve"));
|
|---|
| 6198 | return do_retrieve(aTHX_ f, Nullsv, 0);
|
|---|
| 6199 | }
|
|---|
| 6200 |
|
|---|
| 6201 | /*
|
|---|
| 6202 | * mretrieve
|
|---|
| 6203 | *
|
|---|
| 6204 | * Retrieve data held in scalar and return the root object, undef on error.
|
|---|
| 6205 | */
|
|---|
| 6206 | SV *mretrieve(pTHX_ SV *sv)
|
|---|
| 6207 | {
|
|---|
| 6208 | TRACEME(("mretrieve"));
|
|---|
| 6209 | return do_retrieve(aTHX_ (PerlIO*) 0, sv, 0);
|
|---|
| 6210 | }
|
|---|
| 6211 |
|
|---|
| 6212 | /***
|
|---|
| 6213 | *** Deep cloning
|
|---|
| 6214 | ***/
|
|---|
| 6215 |
|
|---|
| 6216 | /*
|
|---|
| 6217 | * dclone
|
|---|
| 6218 | *
|
|---|
| 6219 | * Deep clone: returns a fresh copy of the original referenced SV tree.
|
|---|
| 6220 | *
|
|---|
| 6221 | * This is achieved by storing the object in memory and restoring from
|
|---|
| 6222 | * there. Not that efficient, but it should be faster than doing it from
|
|---|
| 6223 | * pure perl anyway.
|
|---|
| 6224 | */
|
|---|
| 6225 | SV *dclone(pTHX_ SV *sv)
|
|---|
| 6226 | {
|
|---|
| 6227 | dSTCXT;
|
|---|
| 6228 | int size;
|
|---|
| 6229 | stcxt_t *real_context;
|
|---|
| 6230 | SV *out;
|
|---|
| 6231 |
|
|---|
| 6232 | TRACEME(("dclone"));
|
|---|
| 6233 |
|
|---|
| 6234 | /*
|
|---|
| 6235 | * Workaround for CROAK leak: if they enter with a "dirty" context,
|
|---|
| 6236 | * free up memory for them now.
|
|---|
| 6237 | */
|
|---|
| 6238 |
|
|---|
| 6239 | if (cxt->s_dirty)
|
|---|
| 6240 | clean_context(aTHX_ cxt);
|
|---|
| 6241 |
|
|---|
| 6242 | /*
|
|---|
| 6243 | * do_store() optimizes for dclone by not freeing its context, should
|
|---|
| 6244 | * we need to allocate one because we're deep cloning from a hook.
|
|---|
| 6245 | */
|
|---|
| 6246 |
|
|---|
| 6247 | if (!do_store(aTHX_ (PerlIO*) 0, sv, ST_CLONE, FALSE, (SV**) 0))
|
|---|
| 6248 | return &PL_sv_undef; /* Error during store */
|
|---|
| 6249 |
|
|---|
| 6250 | /*
|
|---|
| 6251 | * Because of the above optimization, we have to refresh the context,
|
|---|
| 6252 | * since a new one could have been allocated and stacked by do_store().
|
|---|
| 6253 | */
|
|---|
| 6254 |
|
|---|
| 6255 | { dSTCXT; real_context = cxt; } /* Sub-block needed for macro */
|
|---|
| 6256 | cxt = real_context; /* And we need this temporary... */
|
|---|
| 6257 |
|
|---|
| 6258 | /*
|
|---|
| 6259 | * Now, `cxt' may refer to a new context.
|
|---|
| 6260 | */
|
|---|
| 6261 |
|
|---|
| 6262 | ASSERT(!cxt->s_dirty, ("clean context"));
|
|---|
| 6263 | ASSERT(!cxt->entry, ("entry will not cause new context allocation"));
|
|---|
| 6264 |
|
|---|
| 6265 | size = MBUF_SIZE();
|
|---|
| 6266 | TRACEME(("dclone stored %d bytes", size));
|
|---|
| 6267 | MBUF_INIT(size);
|
|---|
| 6268 |
|
|---|
| 6269 | /*
|
|---|
| 6270 | * Since we're passing do_retrieve() both a NULL file and sv, we need
|
|---|
| 6271 | * to pre-compute the taintedness of the input by setting cxt->tainted
|
|---|
| 6272 | * to whatever state our own input string was. -- RAM, 15/09/2000
|
|---|
| 6273 | *
|
|---|
| 6274 | * do_retrieve() will free non-root context.
|
|---|
| 6275 | */
|
|---|
| 6276 |
|
|---|
| 6277 | cxt->s_tainted = SvTAINTED(sv);
|
|---|
| 6278 | out = do_retrieve(aTHX_ (PerlIO*) 0, Nullsv, ST_CLONE);
|
|---|
| 6279 |
|
|---|
| 6280 | TRACEME(("dclone returns 0x%"UVxf, PTR2UV(out)));
|
|---|
| 6281 |
|
|---|
| 6282 | return out;
|
|---|
| 6283 | }
|
|---|
| 6284 |
|
|---|
| 6285 | /***
|
|---|
| 6286 | *** Glue with perl.
|
|---|
| 6287 | ***/
|
|---|
| 6288 |
|
|---|
| 6289 | /*
|
|---|
| 6290 | * The Perl IO GV object distinguishes between input and output for sockets
|
|---|
| 6291 | * but not for plain files. To allow Storable to transparently work on
|
|---|
| 6292 | * plain files and sockets transparently, we have to ask xsubpp to fetch the
|
|---|
| 6293 | * right object for us. Hence the OutputStream and InputStream declarations.
|
|---|
| 6294 | *
|
|---|
| 6295 | * Before perl 5.004_05, those entries in the standard typemap are not
|
|---|
| 6296 | * defined in perl include files, so we do that here.
|
|---|
| 6297 | */
|
|---|
| 6298 |
|
|---|
| 6299 | #ifndef OutputStream
|
|---|
| 6300 | #define OutputStream PerlIO *
|
|---|
| 6301 | #define InputStream PerlIO *
|
|---|
| 6302 | #endif /* !OutputStream */
|
|---|
| 6303 |
|
|---|
| 6304 | MODULE = Storable PACKAGE = Storable::Cxt
|
|---|
| 6305 |
|
|---|
| 6306 | void
|
|---|
| 6307 | DESTROY(self)
|
|---|
| 6308 | SV *self
|
|---|
| 6309 | PREINIT:
|
|---|
| 6310 | stcxt_t *cxt = (stcxt_t *)SvPVX(SvRV(self));
|
|---|
| 6311 | PPCODE:
|
|---|
| 6312 | if (kbuf)
|
|---|
| 6313 | Safefree(kbuf);
|
|---|
| 6314 | if (!cxt->membuf_ro && mbase)
|
|---|
| 6315 | Safefree(mbase);
|
|---|
| 6316 | if (cxt->membuf_ro && (cxt->msaved).arena)
|
|---|
| 6317 | Safefree((cxt->msaved).arena);
|
|---|
| 6318 |
|
|---|
| 6319 |
|
|---|
| 6320 | MODULE = Storable PACKAGE = Storable
|
|---|
| 6321 |
|
|---|
| 6322 | PROTOTYPES: ENABLE
|
|---|
| 6323 |
|
|---|
| 6324 | BOOT:
|
|---|
| 6325 | init_perinterp(aTHX);
|
|---|
| 6326 | gv_fetchpv("Storable::drop_utf8", GV_ADDMULTI, SVt_PV);
|
|---|
| 6327 | #ifdef DEBUGME
|
|---|
| 6328 | /* Only disable the used only once warning if we are in debugging mode. */
|
|---|
| 6329 | gv_fetchpv("Storable::DEBUGME", GV_ADDMULTI, SVt_PV);
|
|---|
| 6330 | #endif
|
|---|
| 6331 | #ifdef USE_56_INTERWORK_KLUDGE
|
|---|
| 6332 | gv_fetchpv("Storable::interwork_56_64bit", GV_ADDMULTI, SVt_PV);
|
|---|
| 6333 | #endif
|
|---|
| 6334 |
|
|---|
| 6335 | void
|
|---|
| 6336 | init_perinterp()
|
|---|
| 6337 | CODE:
|
|---|
| 6338 | init_perinterp(aTHX);
|
|---|
| 6339 |
|
|---|
| 6340 | int
|
|---|
| 6341 | pstore(f,obj)
|
|---|
| 6342 | OutputStream f
|
|---|
| 6343 | SV * obj
|
|---|
| 6344 | CODE:
|
|---|
| 6345 | RETVAL = pstore(aTHX_ f, obj);
|
|---|
| 6346 | OUTPUT:
|
|---|
| 6347 | RETVAL
|
|---|
| 6348 |
|
|---|
| 6349 | int
|
|---|
| 6350 | net_pstore(f,obj)
|
|---|
| 6351 | OutputStream f
|
|---|
| 6352 | SV * obj
|
|---|
| 6353 | CODE:
|
|---|
| 6354 | RETVAL = net_pstore(aTHX_ f, obj);
|
|---|
| 6355 | OUTPUT:
|
|---|
| 6356 | RETVAL
|
|---|
| 6357 |
|
|---|
| 6358 | SV *
|
|---|
| 6359 | mstore(obj)
|
|---|
| 6360 | SV * obj
|
|---|
| 6361 | CODE:
|
|---|
| 6362 | RETVAL = mstore(aTHX_ obj);
|
|---|
| 6363 | OUTPUT:
|
|---|
| 6364 | RETVAL
|
|---|
| 6365 |
|
|---|
| 6366 | SV *
|
|---|
| 6367 | net_mstore(obj)
|
|---|
| 6368 | SV * obj
|
|---|
| 6369 | CODE:
|
|---|
| 6370 | RETVAL = net_mstore(aTHX_ obj);
|
|---|
| 6371 | OUTPUT:
|
|---|
| 6372 | RETVAL
|
|---|
| 6373 |
|
|---|
| 6374 | SV *
|
|---|
| 6375 | pretrieve(f)
|
|---|
| 6376 | InputStream f
|
|---|
| 6377 | CODE:
|
|---|
| 6378 | RETVAL = pretrieve(aTHX_ f);
|
|---|
| 6379 | OUTPUT:
|
|---|
| 6380 | RETVAL
|
|---|
| 6381 |
|
|---|
| 6382 | SV *
|
|---|
| 6383 | mretrieve(sv)
|
|---|
| 6384 | SV * sv
|
|---|
| 6385 | CODE:
|
|---|
| 6386 | RETVAL = mretrieve(aTHX_ sv);
|
|---|
| 6387 | OUTPUT:
|
|---|
| 6388 | RETVAL
|
|---|
| 6389 |
|
|---|
| 6390 | SV *
|
|---|
| 6391 | dclone(sv)
|
|---|
| 6392 | SV * sv
|
|---|
| 6393 | CODE:
|
|---|
| 6394 | RETVAL = dclone(aTHX_ sv);
|
|---|
| 6395 | OUTPUT:
|
|---|
| 6396 | RETVAL
|
|---|
| 6397 |
|
|---|
| 6398 | int
|
|---|
| 6399 | last_op_in_netorder()
|
|---|
| 6400 | CODE:
|
|---|
| 6401 | RETVAL = last_op_in_netorder(aTHX);
|
|---|
| 6402 | OUTPUT:
|
|---|
| 6403 | RETVAL
|
|---|
| 6404 |
|
|---|
| 6405 | int
|
|---|
| 6406 | is_storing()
|
|---|
| 6407 | CODE:
|
|---|
| 6408 | RETVAL = is_storing(aTHX);
|
|---|
| 6409 | OUTPUT:
|
|---|
| 6410 | RETVAL
|
|---|
| 6411 |
|
|---|
| 6412 | int
|
|---|
| 6413 | is_retrieving()
|
|---|
| 6414 | CODE:
|
|---|
| 6415 | RETVAL = is_retrieving(aTHX);
|
|---|
| 6416 | OUTPUT:
|
|---|
| 6417 | RETVAL
|
|---|