in reply to Re^4: SvUV vs SvIV for pointers in SVs, typemap
in thread SvUV vs SvIV for pointers in SVs, typemap

One just needs to cast it back to a pointer before using it.

This assumes that "one" is writing the code that is manipulating the pointers that are stored in, and manipulated as, SvIVs.

Have you tried running Perl on a 32-bit system configured for /3GB?

See also Re: Memory usage in Perl on Windows systems.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
  • Comment on Re^5: SvUV vs SvIV for pointers in SVs, typemap

Replies are listed 'Best First'.
Re^6: SvUV vs SvIV for pointers in SVs, typemap
by ikegami (Patriarch) on Feb 21, 2011 at 01:32 UTC

    The SV is not intended to be modifiable. It's just a container for an opaque value. The only "manipulation" being done is to cast the value back to a pointer.

    Have you tried running Perl on a 32-bit system configured for /3GB?

    No. Are you saying that sv = (SV*)(IV)sv fails then? If so, that's a bug. IV is guaranteed to be large enough to hold a pointer.

      You are still assuming that you (or "the programmer") would be in control of all the code that might operate upon pointer values stored within an SV.

      Ask yourself how and why a pointer value might end up in the IV slot of an SV.

        I'm making no such assumption. I'm saying nothing should be operating on the SV. If something does play with the internals of this object, it's their own fault if they mess something up.

        Ask yourself how and why a pointer value might end up in the IV slot of an SV.

        The XS library is creating a handle that will later be passed back to it.

        In Windows, is HANDLE signed or unsigned? The answer is that it doesn't matter.

        Update: Example use of that typemap:

        $ cat a.pl use strict; use warnings; use Inline C => <<'__EOI__', PREFIX => 'M_'; #include <stdio.h> typedef struct { int i; int j; } foo_t; foo_t* M_get() { foo_t* foo = (foo_t*)malloc(sizeof(foo_t)); printf("get: %p\n", foo); return foo; } void M_free(foo_t* foo) { printf("free(%p)\n", foo); free(foo); } __EOI__ my $o = get(); free($o); $ cat typemap TYPEMAP foo_t* T_PTRREF $ perl -MInline=FORCE,NOISY,NOCLEAN a.pl ... get: 0x91ab70 free(0x91ab70)
        #!/usr/bin/perl -w use Devel::Peek; $ptrUV = unpack('J',pack('P[12]',"Hello World")); $ptrIV = unpack('j',pack('P[12]',"Hello World")); print Dump($ptrUV); print Dump($ptrIV); $ptrUV += 2**31; print Dump($ptrUV);


        SV = IV(0x182a260) at 0x182a264 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 28545556 SV = IV(0x182a3e0) at 0x182a3e4 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 26107564 SV = IV(0x182a260) at 0x182a264 REFCNT = 1 FLAGS = (IOK,pIOK,IsUV) UV = 2176029204
        Perl keeps all unsigneds as IVs until they are greater than IV_MAX (~ +2 billion), then it uses the UV flag/UV mode. [sv.c#l1620 in perl.git] But, if the pointer is larger than 2 billion, and the user manipulates the pointer, for struct offsets for example, before passing it to unpack, or passes the scalar with the pointer inside it to an XSUB that takes a pointer (bad XSUB design right?)