Stas Bekman <[EMAIL PROTECTED]> writes:
[...]
> Thanks for the drawing. Now I don't understand how do you get to the
> apreq_value_t pointer from table_entry->val. Do you just subtract the
> size of the apreq_value_t struct and based on the knowledge that the
> memory allocation is continues, you magically retrieve the whole struct?
Essentially, yes. That's one of the things the offsetof macro is
good for. For specifics, see how apreq_attr_to_type is defined in apreq.h.
> I think I understand the trick now. it wasn't obvious at all ;)
Yeah, it took me a month to get used to it. You seem to have figured it
out in far less time :-).
> and since newSVpv copies the string, you no longer can get to the
> beginning of the struct. Now I understand why you wanted to mark it as
> SvFAKE (that would prevent the copy).
>
> Now that I understand this thing I can think intelligently ;) For
> example how about making SV into a dual-var, ala $!. it might not work
> if IV slot is used to store the original pointer, since using val in
> the numeric context will need to make use of this field. Same with NV?
> I'm just thinking how can we save the overhead of messing with MAGIC
> if we can.
Yeah, me too. The patch just adds an sv_magic() call whenever newSVpv
is called, which shouldn't be too costly (no magic lookups are caused
by APR::Tables, just the overhead of adding magic to any returned scalars).
> So you say that due to the bug we can't sub-class get() to do newSVpv
> while using the pointer to apreq_value_t and then setting SvCUR to the
> real string?
The bug I was referring to is tickled by the numeric tests (4,6,8,14) in
modperl/env.t when I used this definition of mpxs_apr_table_str_2sv:
MP_INLINE static SV *mpxs_apr_table_str_2sv(pTHX_ const char *str)
{
SV *sv;
if (str == NULL)
return &PL_sv_undef;
sv = newSV(0);
SvUPGRADE(sv, SVt_PV);
SvCUR(sv) = strlen(str);
SvPVX(sv) = (char *)str;
SvPOK_on(sv);
/* LEAVE SvLEN == 0 */
return sv_2mortal(sv);
}
IMO, this would be (close to the) ideal approach, because a few
nice things happen behind the scenes:
SvLEN = 0 prevents perl from attempting to call Safefree()
on the SvPVX during sv_free, which would cause a segfault
since that memory was malloced from an apr_pool. SvLEN = 0 also
prevents perl from "stealing" the SvPVX during assignment, (an
optimization in sv_setsv). SvLEN = 0 causes assignment to induce a
string copy, which is _perfectly fine_ since the apreq subclass'
action can happen right on the return stack, *before* any perl
assignment is made.
The real problem with SvLEN=0 is sv_2iv, which would normally
upgrade the SVt_PV to a numeric type, balks at having SvLEN = 0.
sv_2iv winds up converting *any* such string to having a numeric 0
IV. That breaks the numeric tests in modperl/env.t, at least with
perl 5.8.0.
--
Joe Schaefer
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]