Steve Hay <[EMAIL PROTECTED]> writes:
>>So looking at Perl_sv_magicext() in sv.c  (which is good 
>>entry point to use if your perl is new enough to have it and 
>>you are adding a vtable), saves the problem of the mg_find()
>>finding someone elses MAGIC *.
>>
>It's certainly much easier, but I want this to work from 5.6.0 onwards; 

Ok then.

>sv_magicext() was added in 5.7.3, 

I know, I added it ;-)

>so I still need to use sv_magic(), at 
>least for the older Perls.
>
>And it's only easier w.r.t. adding new magic, isn't it?  

Yes.

>It doesn't help 
>when you come to retrieve the MAGIC * later to actually use it.

True.

>
>>
>>Second arg becomes mg_obj it is usually  
>>REFCNTed when you add the magic and SvREFCNT_dec on unmagic.
>>This can be handy. It is used to hold the "object" behind a 'tie'
>>for example. If mg_obj is SV itself or for certain kinds of 'how'
>>and in some cases for GV * REFCNT is skipped. 
>>
>Revised version (attached) now passes the SV itself again.  Then I can 
>check that mg->mg_obj == sv after using mg_find() to see if I've found 
>the right MAGIC *.  Am I kidding myself here, or does that work OK?  

It will work, but adding SV as mg_obj is quite common.
Only 100% fool proof scheme I can think of is to store the MAGIC *
back into "your struct" - but then you don't need to use mg_find anyway ;-)

>Is 
>it necessary anyway in cases such as this where I've only just created 
>the SV.  

That is almost certainly safe if you add the magic right away.

>Surely nobody else could have assigned any other magic to it, 
>so how could it find the wrong magic anyway?

Also MAGIC * is a linked list for mg_find() will return most 
recently added MAGIC * of that 'how' - which is likely yours.

We only go on about finding correct MAGIC * as "we" have been 
burned by obscure bugs when magic is used by multiple XS modules.
(e.g. Tk does -varabiable on $foo, and $foo is tie-d to something
and is also "tainted", and has UTF-8 char position cache, and ...) 

>
>I've also followed some examples I found in Perl/Tk's objGlue.c and 
>tkGlue.c and Perl's perlio.c, and called SvRMAGICAL_off(sv) before 
>finding the magic and assigning the vtbl and then called mg_magical(sv) 
>afterwards.  What is the purpose of turning the magic status off and 
>then back on again, and do I need to do it?  

With sv_magic() and PERL_MAGIC_ext you need that trick if you have get/set.
sv_magic calls mg_magical() which sets Sv?MAGICAL flags based on entries 
in the vtable.
As sv_magic() doesn't set a vtable for PERL_MAGIC_ext it gets them 
wrong if a vtable is going to be set. Hence the invention 
of sv_magicext() so that vtable _IS_ valid at time flags are set.

>Indeed, is it safe to do 
>it, given that SvRMAGICAL_off() isn't documented in perlapi and there 
>doesn't appear to be any other way of doing it?

Major modules like Tk and DBI do what they do. 
perl5.x is unlikely to change in a way that breaks them.
Perl6 (and possibly ponie) is another whole crate of cans-of-worms...

>>The char * and len can be used (almost) as you see fit. The char * may 
>>be the place to save a pointer to the struct. If you do that length 
>>should be 0.
>>If length is positive then mg_ptr is a _copy_ of string you pass in.
>>
>Sounds like a neat idea.

>
>Perlguts says that a malloc()'ed copy of name is stored in mg_ptr if 
>namelen >= 0 [sic].  It seems to work OK (and doesn't leak) with namelen 
>== 0, though, so I guess perlguts is wrong there.  

So long as you only access 0 chars it doesn't matter than the pointer 
is invalid ;-)

>Looking at sv.c, 
>Perl_sv_magic() doesn't touch name/namelen -- it delegates the handling 
>of that to Perl_sv_magicext() which behaves exactly as you say.

And sv_magicext() was created by a cut/paste from perl5.6-ish sv_magic().
So the logic hasn't changed. The current code base has grown 
a bit of code _after_ call to sv_magicext() which worries me slightly. 

>>
>Not sure I like that since behaviour when namelen < 0 isn't documented.  
>So I've added an I32 signature member to my struct and check that it has 
>the correct value after retrieving the magic when it is being used later.

If you use the MAGIC * as the "signature" it can't fail ;-)


Reply via email to