/* The following 2 arrays hide the above details in a pair of
lookup-tables, allowing us to be body-type agnostic.
- sizeof_body_by_svtype[] maps svtype to its body's allocated size.
- offset_by_type[] maps svtype to the body-pointer adjustment needed
+ size maps svtype to its body's allocated size.
+ offset maps svtype to the body-pointer adjustment needed
NB: elements in latter are 0 or <0, and are added during
allocation, and subtracted during deallocation. It may be clearer
to invert the values, and call it shrinkage_by_svtype.
*/
-static int sizeof_body_by_svtype[] = {
- 0, /* SVt_NULLs, SVt_IVs, SVt_NVs, SVt_RVs have no body */
- 0,
- sizeof(xpv_allocated), /* 8 bytes on 686 */
- 0,
- sizeof(xpv_allocated), /* 8 bytes on 686 */
- sizeof(xpviv_allocated), /* 12 */
- sizeof(XPVNV), /* 20 */
- sizeof(XPVMG), /* 28 */
- sizeof(XPVBM), /* 36 */
- sizeof(XPVGV), /* 48 */
- sizeof(XPVLV), /* 64 */
- sizeof(xpvav_allocated), /* 20 */
- sizeof(xpvhv_allocated), /* 20 */
- sizeof(XPVCV), /* 76 */
- sizeof(XPVFM), /* 80 */
- sizeof(XPVIO) /* 84 */
+struct body_details {
+ size_t size;
+ int offset;
};
-#define SIZE_SVTYPES sizeof(sizeof_body_by_svtype)
-
-static int offset_by_svtype[] = {
- 0,
- 0,
- 0,
- 0,
- STRUCT_OFFSET(xpv_allocated, xpv_cur) - STRUCT_OFFSET(XPV, xpv_cur),
- STRUCT_OFFSET(xpviv_allocated, xpv_cur) - STRUCT_OFFSET(XPVIV, xpv_cur),
- 0,
- 0,
- 0,
- 0,
- 0,
- STRUCT_OFFSET(xpvav_allocated, xav_fill) - STRUCT_OFFSET(XPVAV, xav_fill),
- STRUCT_OFFSET(xpvhv_allocated, xhv_fill) - STRUCT_OFFSET(XPVHV, xhv_fill),
- 0,
- 0,
- 0,
-};
-#define SIZE_OFFSETS sizeof(sizeof_body_by_svtype)
-
-/* they better stay synchronized, but this doesnt do it.
- #if SIZE_SVTYPES != SIZE_OFFSETS
- #error "declaration problem: sizeof_body_by_svtype != sizeof(offset_by_svtype)"
- #endif
-*/
+struct body_details bodies_by_type[] = {
+ {0, 0},
+ {0, 0},
+ {sizeof(NV), 0}, /* 8 bytes on most ILP32 with IEEE doubles */
+ {0, 0},
+ {sizeof(xpv_allocated), /* 8 bytes on most ILP32 with IEEE doubles */
+ STRUCT_OFFSET(xpv_allocated, xpv_cur) - STRUCT_OFFSET(XPV, xpv_cur)},
+ {sizeof(xpviv_allocated), /* 12 */
+ STRUCT_OFFSET(xpviv_allocated, xpv_cur) - STRUCT_OFFSET(XPVIV, xpv_cur)},
+ {sizeof(XPVNV), 0}, /* 20 */
+ {sizeof(XPVMG), 0}, /* 28 */
+ {sizeof(XPVBM), 0}, /* 36 */
+ {sizeof(XPVGV), 0}, /* 48 */
+ {sizeof(XPVLV), 0}, /* 64 */
+ {sizeof(xpvav_allocated), /* 20 */
+ STRUCT_OFFSET(xpvav_allocated, xav_fill)
+ - STRUCT_OFFSET(XPVAV, xav_fill)},
+ {sizeof(xpvhv_allocated), /* 20 */
+ STRUCT_OFFSET(xpvhv_allocated, xhv_fill)
+ - STRUCT_OFFSET(XPVHV, xhv_fill)},
+ {sizeof(XPVCV), 0}, /* 76 */
+ {sizeof(XPVFM), 0}, /* 80 */
+ {sizeof(XPVIO), 0} /* 84 */
+};
#define new_body_type(sv_type) \
- (void *)((char *)S_new_body(aTHX_ sizeof_body_by_svtype[sv_type], sv_type)\
- + offset_by_svtype[sv_type])
+ (void *)((char *)S_new_body(aTHX_ bodies_by_type[sv_type].size, sv_type)\
+ + bodies_by_type[sv_type].offset)
#define del_body_type(p, sv_type) \
del_body(p, &PL_body_roots[sv_type])
#define new_body_allocated(sv_type) \
- (void *)((char *)S_new_body(aTHX_ sizeof_body_by_svtype[sv_type], sv_type)\
- + offset_by_svtype[sv_type])
+ (void *)((char *)S_new_body(aTHX_ bodies_by_type[sv_type].size, sv_type)\
+ + bodies_by_type[sv_type].offset)
#define del_body_allocated(p, sv_type) \
- del_body(p - offset_by_svtype[sv_type], &PL_body_roots[sv_type])
+ del_body(p - bodies_by_type[sv_type].offset, &PL_body_roots[sv_type])
#define my_safemalloc(s) (void*)safemalloc(s)
break;
case SVt_PV:
old_body_arena = &PL_body_roots[SVt_PV];
- old_body_offset = - offset_by_svtype[SVt_PVIV];
+ old_body_offset = - bodies_by_type[SVt_PVIV].offset;
old_body_length = STRUCT_OFFSET(XPV, xpv_len)
+ sizeof (((XPV*)SvANY(sv))->xpv_len)
- old_body_offset;
break;
case SVt_PVIV:
old_body_arena = &PL_body_roots[SVt_PVIV];
- old_body_offset = - offset_by_svtype[SVt_PVIV];
+ old_body_offset = - bodies_by_type[SVt_PVIV].offset;
old_body_length = STRUCT_OFFSET(XPVIV, xiv_u);
old_body_length += sizeof (((XPVIV*)SvANY(sv))->xiv_u);
old_body_length -= old_body_offset;
case SVt_PVLV:
case SVt_PVMG:
case SVt_PVNV:
- new_body_length = sizeof_body_by_svtype[mt];
+ new_body_length = bodies_by_type[mt].size;
new_body_arena = &PL_body_roots[mt];
new_body_arenaroot = &PL_body_arenaroots[mt];
goto new_body;
case SVt_PVIV:
- new_body_offset = - offset_by_svtype[SVt_PVIV];
+ new_body_offset = - bodies_by_type[SVt_PVIV].offset;
new_body_length = sizeof(XPVIV) - new_body_offset;
new_body_arena = &PL_body_roots[SVt_PVIV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PVIV];
SvNOK_off(sv);
goto new_body_no_NV;
case SVt_PV:
- new_body_offset = - offset_by_svtype[SVt_PV];
+ new_body_offset = - bodies_by_type[SVt_PV].offset;
new_body_length = sizeof(XPV) - new_body_offset;
new_body_arena = &PL_body_roots[SVt_PV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PV];
case SVt_PVHV:
new_body_arena = &PL_body_roots[SVt_PVHV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PVHV];
- new_body_offset = - offset_by_svtype[SVt_PVHV];
+ new_body_offset = - bodies_by_type[SVt_PVHV].offset;
new_body_length = STRUCT_OFFSET(XPVHV, xmg_stash)
+ sizeof (((XPVHV*)SvANY(sstr))->xmg_stash)
case SVt_PVAV:
new_body_arena = &PL_body_roots[SVt_PVAV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PVAV];
- new_body_offset = - offset_by_svtype[SVt_PVAV];
+ new_body_offset = - bodies_by_type[SVt_PVAV].offset;
new_body_length = STRUCT_OFFSET(XPVHV, xmg_stash)
+ sizeof (((XPVHV*)SvANY(sstr))->xmg_stash)
case SVt_PVLV:
case SVt_PVMG:
case SVt_PVNV:
- new_body_length = sizeof_body_by_svtype[sv_type];
+ new_body_length = bodies_by_type[sv_type].size;
new_body_arena = &PL_body_roots[sv_type];
new_body_arenaroot = &PL_body_arenaroots[sv_type];
goto new_body;
case SVt_PVIV:
- new_body_offset = - offset_by_svtype[SVt_PVIV];
+ new_body_offset = - bodies_by_type[SVt_PVIV].offset;
new_body_length = sizeof(XPVIV) - new_body_offset;
new_body_arena = &PL_body_roots[SVt_PVIV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PVIV];
goto new_body;
case SVt_PV:
- new_body_offset = - offset_by_svtype[SVt_PV];
+ new_body_offset = - bodies_by_type[SVt_PV].offset;
new_body_length = sizeof(XPV) - new_body_offset;
new_body_arena = &PL_body_roots[SVt_PV];
new_body_arenaroot = &PL_body_arenaroots[SVt_PV];