Representaciones C de los Tipos de Perl

Cada variable Perl tiene una representación en forma de estructura de datos C en el intérprete (Véase [9]). Por ejemplo, el tipo escalar es representado mediante una estructura que se encuentra en el fichero sv.h :

lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne 
         '$x = 1 if /struct sv/; print if $x; exit if $x && /}/' sv.h
struct STRUCT_SV {              /* struct sv { */
    void*       sv_any;         /* pointer to something */
    U32         sv_refcnt;      /* how many references to us */
    U32         sv_flags;       /* what we are */
};
El módulo Devel::Peek permite acceder a parte de la información en dicha estructura de datos desde un programa Perl:
lhp@nereida:~/Lperl/src/XSUB/Example$ perl -MDevel::Peek -de 0
Loading DB routines from perl5db.pl version 1.28
main::(-e:1):   0
  DB<1> $a = 5
  DB<2> Dump $a
SV = IV(0x83833b8) at 0x8437350
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 5

sv_any

El tipo SV es usado para representar un escalar. La dirección entre paréntesis se refiere al lugar en el que se encuentra almacenado el valor, el cual es apuntado por el campo sv_any . Se nos informa que contiene un tipo de datos entero: las siglas IV vienen de Integer Value. La información proveída indica que $a esta en la dirección 0x8437350.

REFCNT

El campo REFCNT ( sv_refcnt ) de la estructura lleva el numero de referencias al valor. Es usado por el sistema de gestión de memoria de Perl: si el contador de referencia de un valor vale cero la memoria ocupada por dicho valor puede ser liberada. En efecto, si a continuación hacemos:

  DB<3> $b = \$a
  DB<4> Dump $a
SV = IV(0x83833b8) at 0x8437350
  REFCNT = 2
  FLAGS = (IOK,pIOK)
  IV = 5
Observamos que REFCNT pasa a valer 2 indicando ahora que dicho valor esta siendo referenciado mediante dos ligaduras: a través de $a e indirectamente a través de $b.

FLAGS

Perl lleva la información sobre el estado de uso de una variable en un campo FLAGS . El módulo Devel::Peek nos permite observar el estado de las flags o banderas.

Después de hacer la asignación $a = 5 vimos que el campo sv_any apuntaba a la estructura de datos de tipo IV que contiene la información necesaria y que las banderas IOK y pIOK están activas.

Continuando nuestra sesión, asignemos una cadena a $a:

  DB<6> $a = "hola"
  DB<7> Dump $a
SV = PVIV(0x8151e80) at 0x8437350
  REFCNT = 2
  FLAGS = (POK,pPOK)
  IV = 5
  PV = 0x824d750 "hola"\0
  CUR = 4
  LEN = 8

PVIV

Después de la asignación $a = "Hola" los flags cambian a FLAGS = (POK,pPOK) indicando que ahora la interpretación válida del escalar es como cadena. No sólo cambia la dirección apuntada por el campo sv_any sino que también lo hace el tipo de lo apuntado: PVIV . El tipo PVIV indica que el valor puede ser una cadena o un número. El tipo PVIV se implanta en el intérprete mediante una estructura de datos con nombre xpviv:

lhp@nereida:~/Lperl/src/perlcompilerssource/perl-5.8.8$ perl -ne 
          '$x = 1 if /struct xpviv/; print if $x; exit if $x && /}/' sv.h
struct xpviv {
    char *      xpv_pv;         /* pointer to malloced string */
    STRLEN      xpv_cur;        /* length of xpv_pv as a C string */
    STRLEN      xpv_len;        /* allocated size */
    IV          xiv_iv;         /* integer value or pv offset */
};

El campo CUR (xpv_cur) contiene la longitud de la cadena mientras que el campo LEN (xpv_len) informa de la cantidad de memoria reservada para la misma.



Subsecciones
Casiano Rodríguez León
2012-02-29