GoGPT Best VPN GoSearch

Icône de favori OnWorks

perlguts - En ligne dans le cloud

Exécutez perlguts dans le fournisseur d'hébergement gratuit OnWorks sur Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS

Il s'agit de la commande perlguts qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'une de nos multiples stations de travail en ligne gratuites telles que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS.

PROGRAMME:

Nom


perlguts - Introduction à l'API Perl

DESCRIPTION


Ce document tente de décrire comment utiliser l'API Perl, ainsi que de fournir quelques
des informations sur le fonctionnement de base du noyau Perl. Il est loin d'être terminé et probablement
contient de nombreuses erreurs. Veuillez adresser vos questions ou commentaires à l'auteur ci-dessous.

Variables


Types de données
Perl a trois typedefs qui gèrent les trois principaux types de données de Perl :

Valeur scalaire SV
Valeur du tableau AV
Valeur de hachage HV

Chaque typedef possède des routines spécifiques qui manipulent les différents types de données.

Organisateur Ce que is an "IV" ?
Perl utilise un typedef IV spécial qui est un type entier signé simple qui est garanti
être suffisamment grand pour contenir un pointeur (ainsi qu'un entier). De plus, il y a les UV,
qui est simplement un IV non signé.

Perl utilise également deux typedefs spéciaux, I32 et I16, qui seront toujours d'au moins 32 bits.
et 16 bits de long, respectivement. (Encore une fois, il y a aussi les U32 et les U16.) Ils
ont généralement une longueur exacte de 32 et 16 bits, mais sur Crays, ils seront tous deux de 64 bits.

Working : un espace de travail commun avec SV
Un SV peut être créé et chargé avec une seule commande. Il existe cinq types de valeurs qui peuvent
être chargé : une valeur entière (IV), une valeur entière non signée (UV), un double (NV), une chaîne
(PV) et un autre scalaire (SV). ("PV" signifie "Pointer Value". Vous pourriez penser que cela
est mal nommé car il est décrit comme pointant uniquement vers des chaînes. Cependant, il est possible
pour qu'il pointe vers d'autres choses. Par exemple, cela pourrait pointer vers un ensemble d’UV. Mais,
son utilisation pour des non-chaînes nécessite des précautions, car l'hypothèse sous-jacente d'une grande partie de la
les éléments internes sont que les PV sont uniquement destinés aux chaînes. Souvent, par exemple, un « NUL » final est
cloué automatiquement. L'utilisation sans chaîne est documentée uniquement dans ce paragraphe.)

Les sept routines sont :

SV* nouveauSViv(IV);
SV* nouveauSVuv(UV);
SV* nouveauSVnv(double);
SV* nouveauSVpv(const char*, STRLEN);
SV* newSVpvn(const char*, STRLEN);
SV* nouveauSVpvf(const char*, ...);
SV* nouveauSVsv(SV*);

"STRLEN" est un type entier (Size_t, généralement défini comme size_t dans config.h) garanti à
être suffisamment grand pour représenter la taille de n'importe quelle chaîne que Perl peut gérer.

Dans le cas peu probable où un SV nécessiterait une initialisation plus complexe, vous pouvez créer un
SV vide avec newSV(len). Si "len" vaut 0, un SV vide de type NULL est renvoyé, sinon un SV
de type PV est renvoyé avec len + 1 (pour le "NUL") octets de stockage alloués, accessibles
via SvPVX. Dans les deux cas, le SV a la valeur undef.

SV *sv = nouveauSV(0); /* aucun espace de stockage alloué */
SV *sv = nouveauSV(dix); /* 10 (+10) octets de stockage non initialisé
* attribué */

Pour modifier la valeur d'un déjà existante SV, il y a huit routines :

void sv_setiv(SV*, IV);
void sv_setuv(SV*,UV);
void sv_setnv(SV*, double);
void sv_setpv(SV*, const char*);
void sv_setpvn(SV*, const char*, STRLEN)
void sv_setpvf(SV*, const char*, ...);
void sv_vsetpvfn(SV*, const char*, STRLEN, va_list *,
SV **, I32, booléen *);
void sv_setsv(SV*, SV*);

Notez que vous pouvez choisir de spécifier la longueur de la chaîne à attribuer en utilisant
"sv_setpvn", "newSVpvn" ou "newSVpv", ou vous pouvez autoriser Perl à calculer la longueur en
en utilisant "sv_setpv" ou en spécifiant 0 comme deuxième argument de "newSVpv". Être averti,
cependant, Perl déterminera la longueur de la chaîne en utilisant "strlen", qui dépend de
la chaîne se terminant par un caractère "NUL" et ne contenant pas de NUL.

Les arguments de "sv_setpvf" sont traités comme "sprintf", et la sortie formatée
devient la valeur.

"sv_vsetpvfn" est un analogue de "vsprintf", mais il permet de spécifier soit un pointeur
à une liste d’arguments variables ou à l’adresse et à la longueur d’un tableau de SV. Le dernier
l'argument pointe vers un booléen ; au retour, si ce booléen est vrai, alors spécifique aux paramètres régionaux
des informations ont été utilisées pour formater la chaîne et le contenu de la chaîne est donc
peu fiable (voir perlsec). Ce pointeur peut être NULL si cette information n'est pas
important. Notez que cette fonction nécessite de spécifier la longueur du format.

Les fonctions "sv_set*()" ne sont pas assez génériques pour opérer sur des valeurs qui ont de la "magie".
Voir « Tables virtuelles magiques » plus loin dans ce document.

Tous les SV contenant des chaînes doivent se terminer par un caractère « NUL ». Si ce n'est pas le cas
Terminé par "NUL", il existe un risque de vidages de mémoire et de corruption du code qui passe le
chaîne aux fonctions C ou aux appels système qui attendent une chaîne terminée par "NUL". Celui de Perl
les fonctions ajoutent généralement un « NUL » final pour cette raison. Néanmoins, vous devriez être
très prudent lorsque vous transmettez une chaîne stockée dans un SV à une fonction C ou à un appel système.

Pour accéder à la valeur réelle vers laquelle pointe un SV, vous pouvez utiliser les macros :

SVIV(SV*)
SVUV(SV*)
SVNV(SV*)
SvPV(SV*, STRLENlen)
SvPV_nolen(SV*)

qui contraindra automatiquement le type scalaire réel en IV, UV, double ou chaîne.

Dans la macro "SvPV", la longueur de la chaîne renvoyée est placée dans la variable "len"
(c'est une macro, donc vous le faites pas utilisez &len). Si vous ne vous souciez pas de la longueur des données
c'est-à-dire, utilisez la macro "SvPV_nolen". Historiquement la macro "SvPV" avec la variable globale
"PL_na" a été utilisé dans ce cas. Mais cela peut s'avérer assez inefficace car "PL_na"
doit être accessible dans le stockage local du thread en Perl threadé. Dans tous les cas, rappelez-vous que
Perl autorise des chaînes de données arbitraires qui peuvent à la fois contenir des valeurs NUL et ne pas l'être.
terminé par un "NUL".

N'oubliez pas non plus que C ne vous permet pas de dire en toute sécurité "foo(SvPV(s, len), len);". Cela pourrait
travaillez avec votre compilateur, mais cela ne fonctionnera pas pour tout le monde. Décomposez ce genre de déclaration
en missions distinctes :

SV *s ;
STRLEN len;
char *ptr;
ptr = SvPV(s, len);
foo(ptr, len);

Si vous voulez savoir si la valeur scalaire est VRAI, vous pouvez utiliser :

SvVRAI(SV*)

Bien que Perl agrandisse automatiquement les chaînes pour vous, si vous devez forcer Perl à
allouez plus de mémoire pour votre SV, vous pouvez utiliser la macro

SvGROW(SV*, STRLEN newlen)

qui déterminera si plus de mémoire doit être allouée. Si c'est le cas, il appellera le
fonction "sv_grow". Notez que "SvGROW" ne peut qu'augmenter, et non diminuer, le montant alloué
mémoire d'un SV et qu'il n'ajoute pas automatiquement d'espace pour l'octet "NUL" de fin
(les propres fonctions de chaîne de Perl font généralement "SvGROW(sv, len + 1)").

Si vous souhaitez écrire dans le tampon d'un SV existant et définir sa valeur sur une chaîne, utilisez
SvPV_force() ou une de ses variantes pour forcer le SV à être un PV. Cela supprimera l'un des
divers types de non-stringness du SV tout en préservant le contenu du SV dans le
PV. Cela peut être utilisé, par exemple, pour ajouter des données d'une fonction API à un tampon
sans copie supplémentaire :

(void)SvPVbyte_force(sv, len);
s = SvGROW(sv, len + aiguille + 1);
/* quelque chose qui modifie jusqu'à Needlen octets à s+len, mais
modifie les octets newlen
par exemple. newlen = read(fd, s + len, aiguilles);
ignorer les erreurs pour ces exemples
*/
s[len + newlen] = '\0';
SvCUR_set(sv, len + newlen);
SvUTF8_off(sv);
SvSETMAGIC(sv);

Si vous avez déjà les données en mémoire ou si vous souhaitez garder votre code simple, vous pouvez
utilisez l'une des variantes sv_cat*(), telle que sv_catpvn(). Si vous souhaitez insérer n'importe où dans
la chaîne que vous pouvez utiliser sv_insert() or sv_insert_flags().

Si vous n'avez pas besoin du contenu existant du SV, vous pouvez éviter certaines copies avec :

sv_setpvn(sv, "", 0);
s = SvGROW(sv, aiguille + 1);
/* quelque chose qui modifie jusqu'à octets aiguilles en s, mais modifie
nouveaux octets
par exemple. newlen = read(fd, s.aiguillen);
*/
s[newlen] = '\0';
SvCUR_set(sv, newlen);
SvPOK_only(sv); /* efface également SVf_UTF8 */
SvSETMAGIC(sv);

Encore une fois, si vous avez déjà les données en mémoire ou si vous souhaitez éviter la complexité du
ci-dessus, vous pouvez utiliser sv_setpvn().

Si vous avez un tampon alloué avec Nouveaux() et que vous souhaitez définir cela comme valeur du SV, vous pouvez
utilisé sv_usepvn_flags(). Cela a certaines exigences si vous voulez éviter la réallocation de Perl
le tampon pour s'adapter au NUL final :

Newx(buf, somesize+1, char);
/* ... remplir buf ... */
buf[une taille] = '\0';
sv_usepvn_flags(sv, buf, somesize, SV_SMAGIC | SV_HAS_TRAILING_NUL);
/* buf appartient maintenant à Perl, ne le publiez pas */

Si vous avez un SV et que vous voulez savoir quel type de données Perl pense y être stocké, vous pouvez
utilisez les macros suivantes pour vérifier le type de SV dont vous disposez.

SVIOK(SV*)
SvNOK(SV*)
SvPOK(SV*)

Vous pouvez obtenir et définir la longueur actuelle de la chaîne stockée dans un SV avec ce qui suit
macro :

SVCUR(SV*)
SvCUR_set(SV*, valeur I32)

Vous pouvez également obtenir un pointeur vers la fin de la chaîne stockée dans le SV avec la macro :

Suède(SV*)

Mais notez que ces trois dernières macros ne sont valides que si « SvPOK() » est vrai.

Si vous souhaitez ajouter quelque chose à la fin d'une chaîne stockée dans un "SV*", vous pouvez utiliser le
fonctions suivantes:

void sv_catpv(SV*, const char*);
void sv_catpvn(SV*, const char*, STRLEN);
void sv_catpvf(SV*, const char*, ...);
void sv_vcatpvfn(SV*, const char*, STRLEN, va_list *, SV **,
I32, booléen);
void sv_catsv(SV*, SV*);

La première fonction calcule la longueur de la chaîne à ajouter en utilisant « strlen ».
Dans la seconde, vous spécifiez vous-même la longueur de la chaîne. La troisième fonction
traite ses arguments comme "sprintf" et ajoute la sortie formatée. Le quatrième
la fonction fonctionne comme "vsprintf". Vous pouvez spécifier l'adresse et la longueur d'un tableau de SV
au lieu de l'argument va_list. La cinquième fonction étend la chaîne stockée dans le
premier SV avec la chaîne stockée dans le deuxième SV. Cela oblige également le deuxième SV à être
interprété comme une chaîne.

Les fonctions "sv_cat*()" ne sont pas assez génériques pour opérer sur des valeurs qui ont de la "magie".
Voir « Tables virtuelles magiques » plus loin dans ce document.

Si vous connaissez le nom d'une variable scalaire, vous pouvez obtenir un pointeur vers son SV en utilisant la commande
Suivante à la suite:

SV* get_sv("package::varname", 0);

Cela renvoie NULL si la variable n'existe pas.

Si vous voulez savoir si cette variable (ou tout autre SV) est réellement "définie", vous pouvez
appel:

SVOK(SV*)

La valeur scalaire « undef » est stockée dans une instance SV appelée « PL_sv_undef ».

Son adresse peut être utilisée chaque fois qu'un "SV*" est nécessaire. Assurez-vous de ne pas essayer de
comparez un sv aléatoire avec &PL_sv_undef. Par exemple, lors de l'interface avec du code Perl, cela fonctionnera
correctement pour :

foo(undef);

Mais cela ne fonctionnera pas lorsqu'il est appelé comme :

$x = non défini ;
foo($x);

Donc, pour répéter, utilisez toujours SvOK() pour vérifier si un sv est défini.

Vous devez également être prudent lorsque vous utilisez &PL_sv_undef comme valeur dans AVs ou HVs (voir "AVs,
HV et valeurs non définies").

Il existe également les deux valeurs "PL_sv_yes" et "PL_sv_no", qui contiennent les booléens TRUE et
Valeurs FAUX, respectivement. Comme "PL_sv_undef", leurs adresses peuvent être utilisées à chaque fois qu'un
"SV*" est nécessaire.

Ne vous laissez pas tromper en pensant que "(SV *) 0" est identique à &PL_sv_undef. Prends ça
code:

SV* sv = (SV*) 0 ;
if (je-suis-pour-retourner-une-valeur-réelle) {
sv = sv_2mortel(nouveauSViv(42));
}
sv_setsv(ST(0), sv);

Ce code tente de renvoyer un nouveau SV (qui contient la valeur 42) s'il doit renvoyer un
valeur réelle, ou undef autrement. Au lieu de cela, il a renvoyé un pointeur NULL qui, quelque part
en fin de compte, cela entraînera une violation de segmentation, une erreur de bus ou simplement des résultats étranges.
Changez le zéro en &PL_sv_undef dans la première ligne et tout ira bien.

Pour libérer un SV que vous avez créé, appelez "SvREFCNT_dec(SV*)". Normalement, cet appel n'est pas
nécessaire (voir « Nombres de référence et mortalité »).

Décalages
Perl fournit la fonction "sv_chop" pour supprimer efficacement les caractères depuis le début
d'une chaîne; vous lui donnez un SV et un pointeur quelque part à l'intérieur du PV, et il se débarrasse
tout avant le pointeur. L'efficacité vient d'un petit hack : au lieu de
en supprimant réellement les caractères, "sv_chop" définit le drapeau "OOK" (offset OK) pour signaler
d'autres fonctions que le hack de décalage est en vigueur, et il déplace le pointeur PV (appelé
"SvPVX") avance du nombre d'octets coupés et ajuste "SvCUR" et "SvLEN"
par conséquent. (Une partie de l'espace entre l'ancien et le nouveau pointeur PV est utilisée pour stocker
le nombre d'octets hachés.)

Par conséquent, à ce stade, le début du tampon que nous avons alloué se situe à "SvPVX(sv) -
SvIV(sv)" en mémoire et le pointeur PV pointe vers le milieu de cette zone allouée.
espace de rangement.

Ceci est mieux démontré par l’exemple. Normalement, la copie sur écriture empêchera le
substitution de l'opérateur d'utiliser ce hack, mais si vous pouvez créer une chaîne pour laquelle
la copie sur écriture n'est pas possible, vous pouvez le voir en jeu. Dans la mise en œuvre actuelle, le
Le dernier octet d'un tampon de chaîne est utilisé comme décompte de référence de copie sur écriture. Si le tampon
n'est pas assez grand, alors la copie sur écriture est ignorée. Jetez d’abord un œil à une chaîne vide :

% ./perl -Ilib -MDevel::Peek -le '$a=""; $a .= ""; Dump $a'
SV = PV(0x7ffb7c008a70) at 0x7ffb7c030390
REFCNT = 1
DRAPEAUX = (POK,pPOK)
PV = 0x7ffb7bc05b50 ""\0
CUR = 0
LON = 10

Notez ici que le LEN est de 10. (Il peut différer selon votre plate-forme.) Prolongez la longueur du
chaîne à un inférieur à 10 et effectuez une substitution :

% ./perl -Ilib -MDevel::Peek -le '$a=""; $a.="123456789"; $a=~s/.//; Vider ($a)'
SV = PV(0x7ffa04008a70) at 0x7ffa04030390
REFCNT = 1
DRAPEAUX = (POK,OOK,pPOK)
DÉCALAGE = 1
PV = 0x7ffa03c05b61 ( "\1" . ) "23456789"\0
CUR = 8
LON = 9

Ici, le nombre d'octets coupés (1) est affiché ensuite comme OFFSET. La partie du
la chaîne entre le "vrai" et le "faux" début est affichée entre parenthèses, et le
les valeurs de "SvCUR" et "SvLEN" reflètent le faux début, pas le vrai. (La première
Le caractère du tampon de chaîne a été changé en "\1" ici, et non en "1", car le
l'implémentation actuelle stocke le nombre de décalages dans le tampon de chaîne. Ceci est soumis à
changement.)

Quelque chose de similaire au hack offset est effectué sur les AV pour permettre un changement de vitesse efficace et
séparer le début du tableau ; tandis que "AvARRAY" pointe vers le premier élément de
le tableau visible depuis Perl, "AvALLOC" pointe vers le début réel du tableau C.
Ce sont généralement les mêmes, mais une opération de « shift » peut être effectuée en augmentant
"AvARRAY" de un et "AvFILL" et "AvMAX" décroissants. Encore une fois, l'emplacement du réel
le début du tableau C n'intervient que lors de la libération du tableau. Voir "av_shift" dans av.c.

Ce qui est Vraiment Stocké in an SV ?
Rappelez-vous que la méthode habituelle pour déterminer le type de scalaire dont vous disposez est d'utiliser "Sv*OK"
macros. Etant donné qu'un scalaire peut être à la fois un nombre et une chaîne, ces macros
renvoie toujours TRUE et l'appel des macros "Sv*V" effectuera la conversion appropriée de
chaîne en entier/double ou entier/double en chaîne.

Si vous vraiment besoin de savoir si vous avez un pointeur entier, double ou chaîne dans un SV, vous
Vous pouvez utiliser les trois macros suivantes :

SvIOKp(SV*)
SvNOKp(SV*)
SvPOKp(SV*)

Ceux-ci vous diront si vous avez réellement un pointeur entier, double ou chaîne stocké dans votre fichier.
SV. Le "p" signifie privé.

Les drapeaux privés et publics peuvent différer de différentes manières. Par exemple, dans
perl 5.16 et versions antérieures, un SV lié peut avoir une valeur sous-jacente valide dans l'emplacement IV (donc
SvIOKp est vrai), mais les données doivent être accessibles via la routine FETCH plutôt que
directement, donc SvIOK est faux. (À partir de Perl 5.18, les scalaires liés utilisent les drapeaux de la même manière.
manière comme des scalaires déliés.) Une autre solution est lorsque la conversion numérique a eu lieu et que la précision a
été perdu : seul le flag privé est défini sur des valeurs "avec perte". Ainsi, lorsqu'un NV est converti en
un IV avec perte, SvIOKp, SvNOKp et SvNOK seront définis, alors que SvIOK ne le sera pas.

En général, cependant, il est préférable d'utiliser les macros "Sv*V".

Working : un espace de travail commun avec AV
Il existe deux manières de créer et de charger un AV. La première méthode crée un AV vide :

AV* nouveauAV();

La deuxième méthode crée à la fois l'AV et le remplit initialement avec des SV :

AV* av_make(SSize_t num, SV **ptr);

Le deuxième argument pointe vers un tableau contenant des "num" "SV*". Une fois que l'AV a été
créés, les SV peuvent être détruits, si vous le souhaitez.

Une fois l'AV créé, les opérations suivantes sont possibles sur celui-ci :

void av_push(AV*, SV*);
SV* av_pop(AV*);
SV* av_shift(AV*);
void av_unshift(AV*, SSize_t num);

Il devrait s'agir d'opérations familières, à l'exception de "av_unshift". Cette routine
ajoute les éléments "num" au début du tableau avec la valeur "undef". Vous devez alors utiliser
"av_store" (décrit ci-dessous) pour attribuer des valeurs à ces nouveaux éléments.

Voici quelques autres fonctions :

SSize_t av_top_index(AV*);
SV** av_fetch(AV*, clé SSize_t, I32 lval);
SV** av_store(AV*, clé SSize_t, SV* val);

La fonction "av_top_index" renvoie la valeur d'index la plus élevée dans un tableau (tout comme $#array
en Perl). Si le tableau est vide, -1 est renvoyé. La fonction "av_fetch" renvoie le
valeur à l'index "key", mais si "lval" est différent de zéro, alors "av_fetch" stockera une valeur undef
à cet indice. La fonction "av_store" stocke la valeur "val" à l'index "key", et fait
n'incrémente pas le nombre de références de "val". L'appelant est donc responsable de prendre
attention à cela, et si "av_store" renvoie NULL, l'appelant devra décrémenter le
nombre de références pour éviter une fuite de mémoire. Notez que "av_fetch" et "av_store" renvoient tous deux
"SV**", pas "SV*" comme valeur de retour.

Un peu plus:

void av_clear(AV*);
void av_undef(AV*);
void av_extend(AV*, clé SSize_t);

La fonction "av_clear" supprime tous les éléments du tableau AV*, mais ne les supprime pas réellement.
supprimez le tableau lui-même. La fonction "av_undef" supprimera tous les éléments du
tableau plus le tableau lui-même. La fonction "av_extend" étend le tableau pour qu'il
contient au moins des éléments "key+1". Si "clé+1" est inférieur à la valeur actuellement allouée
longueur du tableau, alors rien n'est fait.

Si vous connaissez le nom d'une variable de tableau, vous pouvez obtenir un pointeur vers son AV en utilisant la commande
Suivante à la suite:

AV* get_av("package::varname", 0);

Cela renvoie NULL si la variable n'existe pas.

Voir « Comprendre la magie des hachages et des tableaux liés » pour plus d'informations sur l'utilisation
les fonctions d'accès aux tableaux sur les tableaux liés.

Working : un espace de travail commun avec HT
Pour créer un HV, vous utilisez la routine suivante :

HV* nouveauHV();

Une fois la HT créée, les opérations suivantes sont possibles sur celle-ci :

SV** hv_store(HV*, clé const char*, clé U32, valeur SV*, hachage U32) ;
SV** hv_fetch(HV*, clé const char*, U32 klen, I32 lval);

Le paramètre "klen" est la longueur de la clé transmise (notez que vous ne pouvez pas transmettre 0
comme valeur de "klen" pour indiquer à Perl de mesurer la longueur de la clé). Le "val"
L'argument contient le pointeur SV vers le scalaire stocké, et "hash" est le précalculé
valeur de hachage (zéro si vous souhaitez que "hv_store" la calcule pour vous). Le paramètre "lval"
indique si cette récupération fait réellement partie d'une opération de stockage, auquel cas un nouveau
une valeur non définie sera ajoutée au HV avec la clé fournie et "hv_fetch" reviendra
comme si la valeur existait déjà.

N'oubliez pas que "hv_store" et "hv_fetch" renvoient des "SV**" et pas seulement "SV*". Pour accéder au
valeur scalaire, vous devez d’abord déréférencer la valeur de retour. Cependant, vous devriez vérifier auprès de
assurez-vous que la valeur de retour n'est pas NULL avant de la déréférencer.

La première de ces deux fonctions vérifie si une entrée de table de hachage existe, et la seconde
le supprime.

bool hv_exists(HV*, clé const char*, clé U32);
SV* hv_delete (HV*, clé const char*, klen U32, drapeaux I32) ;

Si "flags" n'inclut pas l'indicateur "G_DISCARD", alors "hv_delete" créera et renverra un
copie mortelle de la valeur supprimée.

Et d'autres fonctions diverses :

void hv_clear(HV*);
void hv_undef(HV*);

Comme leurs homologues AV, "hv_clear" supprime toutes les entrées de la table de hachage mais ne
pas réellement supprimer la table de hachage. Le "hv_undef" supprime à la fois les entrées et le hachage
table elle-même.

Perl conserve les données réelles dans une liste chaînée de structures avec une définition de type HE. Ces
contiennent les pointeurs de clé et de valeur réels (plus une surcharge administrative supplémentaire). La clé
est un pointeur de chaîne ; la valeur est un "SV*". Cependant, une fois que vous avez un "HE*", pour obtenir le
clé et valeur réelles, utilisez les routines spécifiées ci-dessous.

I32 hv_iterinit(HV*);
/* Prépare le point de départ pour parcourir la table de hachage */
HE* hv_iternext(HV*);
/* Récupère l'entrée suivante et renvoie un pointeur vers un
structure qui a à la fois la clé et la valeur */
char* hv_iterkey(Entrée HE*, I32* retlen);
/* Récupère la clé d'une structure HE et renvoie également
la longueur de la chaîne clé */
SV* hv_iterval(entrée HV*, HE*);
/* Renvoie un pointeur SV sur la valeur du HE
structure */
SV* hv_iternextsv(HV*, clé char**, I32* retlen);
/* Cette routine pratique combine hv_iternext,
hv_iterkey et hv_iterval. La clé et le relen
les arguments sont des valeurs de retour pour la clé et ses
longueur. La valeur est renvoyée dans l'argument SV* */

Si vous connaissez le nom d'une variable de hachage, vous pouvez obtenir un pointeur vers sa HV en utilisant la commande
Suivante à la suite:

HV* get_hv("package::varname", 0);

Cela renvoie NULL si la variable n'existe pas.

L'algorithme de hachage est défini dans la macro "PERL_HASH" :

PERL_HASH(hachage, clé, klen)

L'implémentation exacte de cette macro varie selon l'architecture et la version de Perl, et le
la valeur de retour peut changer à chaque appel, donc la valeur n'est valable que pour la durée d'un
processus Perl unique.

Voir « Comprendre la magie des hachages et des tableaux liés » pour plus d'informations sur l'utilisation
les fonctions d'accès au hachage sur les hachages liés.

Hash API Extensions
À partir de la version 5.004, les fonctions suivantes sont également prises en charge :

HE* hv_fetch_ent (HV* tb, clé SV*, I32 lval, hachage U32) ;
HE* hv_store_ent (HV* tb, clé SV*, SV* val, hachage U32) ;

bool hv_exists_ent (HV* tb, clé SV*, hachage U32) ;
SV* hv_delete_ent (HV* tb, clé SV*, indicateurs I32, hachage U32) ;

SV* hv_iterkeysv (entrée HE*) ;

Notez que ces fonctions prennent les touches "SV*", ce qui simplifie l'écriture du code d'extension qui
traite des structures de hachage. Ces fonctions permettent également de passer des touches "SV*" pour "attacher"
fonctions sans vous obliger à chaîner les touches (contrairement à l'ensemble précédent de
les fonctions).

Ils renvoient et acceptent également les entrées de hachage entières ("HE*"), ce qui rend leur utilisation plus efficace.
(puisque le numéro de hachage d'une chaîne particulière n'a pas besoin d'être recalculé à chaque fois).
Voir perlapi pour des descriptions détaillées.

Les macros suivantes doivent toujours être utilisées pour accéder au contenu des entrées de hachage. Note
que les arguments de ces macros doivent être des variables simples, car elles peuvent être évaluées
plus d'une fois. Voir perlapi pour des descriptions détaillées de ces macros.

HePV(IL* il, STRLEN len)
HéVAL(IL* il)
IlHASH(IL* il)
HeSVKEY(IL* il)
HeSVKEY_force(IL* il)
HeSVKEY_set(HE* il, SV* sv)

Ces deux macros de niveau inférieur sont définies, mais ne doivent être utilisées que lorsqu'il s'agit de clés
qui ne sont pas des "SV*" :

HeKEY(IL* il)
HeKLEN(IL* il)

Notez que "hv_store" et "hv_store_ent" n'incrémentent pas le nombre de références du
"val" stocké, ce qui relève de la responsabilité de l'appelant. Si ces fonctions renvoient un NULL
valeur, l'appelant devra généralement décrémenter le nombre de références de "val" pour éviter un
fuite de mémoire.

les AV, HT et indéfini valeurs
Parfois, vous devez stocker des valeurs non définies dans des AV ou des HV. Même si cela peut être rare
Dans ce cas, cela peut être délicat. C'est parce que vous avez l'habitude d'utiliser &PL_sv_undef si vous avez besoin d'un
SV indéfini.

Par exemple, l'intuition vous dit que ce code XS :

AV *av = nouveauAV();
av_store( av, 0, &PL_sv_undef );

est équivalent à ce code Perl :

mon @av ;
$av[0] = non défini ;

Malheureusement, ce n'est pas vrai. En Perl 5.18 et versions antérieures, les AV utilisent &PL_sv_undef comme
marqueur pour indiquer qu'un élément du tableau n'a pas encore été initialisé. Ainsi, « il existe
$av[0]" serait vrai pour le code Perl ci-dessus, mais faux pour le tableau généré par XS
code. En Perl 5.20, stocker &PL_sv_undef créera un élément en lecture seule, car le
le scalaire &PL_sv_undef lui-même est stocké, pas une copie.

Des problèmes similaires peuvent survenir lors du stockage de &PL_sv_undef dans des HV :

hv_store( hv, "clé", 3, &PL_sv_undef, 0 );

Cela rendra effectivement la valeur "undef", mais si vous essayez de modifier la valeur de "key",
vous obtiendrez l'erreur suivante :

Tentative de modification d'une valeur de hachage non créable

Dans Perl 5.8.0, &PL_sv_undef était également utilisé pour marquer des espaces réservés dans les hachages restreints. Ce
fait que ces entrées de hachage n'apparaissent pas lors de l'itération sur le hachage ou lors de la vérification de
les clés avec la fonction "hv_exists".

Vous pouvez rencontrer des problèmes similaires lorsque vous stockez &PL_sv_yes ou &PL_sv_no dans des AV ou des HV.
Essayer de modifier ces éléments vous donnera l’erreur suivante :

Tentative de modification d'une valeur en lecture seule

Pour faire court, vous pouvez utiliser les variables spéciales &PL_sv_undef, &PL_sv_yes et
&PL_sv_no avec les AV et les HV, mais vous devez vous assurer de savoir ce que vous faites.

Généralement, si vous souhaitez stocker une valeur non définie dans un AV ou un HV, vous ne devez pas utiliser
&PL_sv_undef, mais créez plutôt une nouvelle valeur non définie à l'aide de la fonction "newSV", par exemple
Exemple:

av_store( av, 42, nouveauSV(0) );
hv_store( hv, "foo", 3, nouveauSV(0), 0 );

Références
Les références sont un type spécial de scalaire qui pointe vers d'autres types de données (y compris d'autres
les références).

Pour créer une référence, utilisez l'une des fonctions suivantes :

SV* newRV_inc((SV*) chose);
SV* newRV_noinc((SV*) chose);

L'argument "chose" peut être "SV*", "AV*" ou "HV*". Les fonctions sont identiques
sauf que "newRV_inc" incrémente le compteur de références de la "chose", tandis que "newRV_noinc"
ne fait pas. Pour des raisons historiques, « newRV » est synonyme de « newRV_inc ».

Une fois que vous avez une référence, vous pouvez utiliser la macro suivante pour déréférencer la référence :

SVR(SV*)

puis appelez les routines appropriées, en convertissant le "SV*" renvoyé en "AV*" ou
« HT* », si nécessaire.

Pour déterminer si un SV est une référence, vous pouvez utiliser la macro suivante :

SVROK(SV*)

Pour découvrir à quel type de valeur la référence fait référence, utilisez la macro suivante, puis
vérifiez la valeur de retour.

TYPESv(SvRV(SV*))

Les types les plus utiles qui seront renvoyés sont :

< SVt_PVAV Scalaire
Tableau SVt_PVAV
Hachage SVt_PVHV
Code SVt_PVCV
SVt_PVGV Glob (éventuellement un descripteur de fichier)

Voir "svtype" dans perlapi pour plus de détails.

Béni Références et Classe Objets
Les références sont également utilisées pour prendre en charge la programmation orientée objet. Dans le lexique OO de Perl, un
object est simplement une référence qui a été insérée dans un package (ou une classe). Une fois
Bienheureux, le programmeur peut désormais utiliser la référence pour accéder aux différentes méthodes du
classe.

Une référence peut être intégrée dans un package avec la fonction suivante :

SV* sv_bless(SV* sv, cachette HV*);

L'argument "sv" doit être une valeur de référence. L'argument "stash" spécifie quelle classe
la référence appartiendra à. Voir « Stashes et Globs » pour plus d'informations sur la conversion de classe
noms dans des caches.

/* Toujours en construction */

La fonction suivante met à niveau rv vers la référence si ce n'est déjà fait. Crée un nouveau SV pour
rv à pointer. Si "classname" n'est pas nul, le SV est intégré dans la classe spécifiée.
SV est renvoyé.

SV* newSVrv(SV* rv, const char* nom de classe);

Les trois fonctions suivantes copient un entier, un entier non signé ou un double dans un SV dont
la référence est "rv". SV est béni si "classname" n'est pas nul.

SV* sv_setref_iv(SV* rv, const char* nom de classe, IV iv);
SV* sv_setref_uv(SV* rv, const char* nom de classe, UV uv);
SV* sv_setref_nv(SV* rv, const char* nom de classe, NV iv);

La fonction suivante copie la valeur du pointeur (le adresse, pas le chaîne!) dans un SV
dont la référence est rv. SV est béni si "classname" n'est pas nul.

SV* sv_setref_pv(SV* rv, const char* nom de classe, void* pv);

La fonction suivante copie une chaîne dans un SV dont la référence est "rv". Réglez la longueur sur
0 pour laisser Perl calculer la longueur de la chaîne. SV est béni si "classname" n'est pas nul.

SV* sv_setref_pvn(SV* rv, const char* nom de classe, char* pv,
longueur STRLEN);

La fonction suivante teste si le SV est béni dans la classe spécifiée. Cela fait
ne vérifie pas les relations d'héritage.

int sv_isa(SV* sv, const char* nom);

La fonction suivante teste si le SV est une référence à un objet béni.

int sv_isobject(SV* sv);

La fonction suivante teste si le SV est dérivé de la classe spécifiée. SV peut
être soit une référence à un objet béni, soit une chaîne contenant un nom de classe. C'est
la fonction implémentant la fonctionnalité "UNIVERSAL::isa".

bool sv_derived_from(SV* sv, const char* nom);

Pour vérifier si vous avez un objet dérivé d'une classe spécifique, vous devez écrire :

if (sv_isobject(sv) && sv_derived_from(sv, class)) { ... }

La création New Variables
Pour créer une nouvelle variable Perl avec une valeur undef accessible depuis votre Perl
script, utilisez les routines suivantes, en fonction du type de variable.

SV* get_sv("package::varname", GV_ADD);
AV* get_av("package::varname", GV_ADD);
HV* get_hv("package::varname", GV_ADD);

Notez l'utilisation de GV_ADD comme deuxième paramètre. La nouvelle variable peut maintenant être définie en utilisant
les routines appropriées au type de données.

Il existe des macros supplémentaires dont les valeurs peuvent être combinées en OU au niveau du bit avec l'argument "GV_ADD".
pour activer certaines fonctionnalités supplémentaires. Ces bits sont :

GV_ADDMULTI
Marque la variable comme définie de manière multiple, empêchant ainsi :

Nom utilisé une seule fois : faute de frappe possible

Attention.

GV_ADDWARN
Émet l'avertissement :

J'ai dû créer de façon inattendue

si la variable n'existait pas avant l'appel de la fonction.

Si vous ne spécifiez pas de nom de package, la variable est créée dans le package actuel.

Références comtes et Mortalité
Perl utilise un mécanisme de garbage collection basé sur le nombre de références. SV, AV ou HV (xV pour
court dans ce qui suit) commencent leur vie avec un compte de référence de 1. Si la référence
le nombre d'un xV tombe à 0, alors il sera détruit et sa mémoire rendue disponible
pour réutilisation.

Cela ne se produit normalement pas au niveau Perl, sauf si une variable n'est pas définie ou si la dernière variable est définie.
La variable contenant une référence à celle-ci est modifiée ou écrasée. Au niveau interne,
cependant, les décomptes de références peuvent être manipulés avec les macros suivantes :

int SvREFCNT(SV* sv);
SV* SvREFCNT_inc(SV* sv);
void SvREFCNT_dec(SV* sv);

Cependant, il existe une autre fonction qui manipule le décompte de références de son
argument. La fonction "newRV_inc", rappelez-vous, crée une référence au spécifié
argument. Comme effet secondaire, cela incrémente le nombre de références de l’argument. Si ce n'est pas
ce que vous voulez, utilisez plutôt "newRV_noinc".

Par exemple, imaginez que vous souhaitiez renvoyer une référence à partir d'une fonction XSUB. À l'intérieur de
Routine XSUB, vous créez un SV qui a initialement un nombre de références de un. Alors vous
appelez "newRV_inc", en lui passant le SV qui vient d'être créé. Cela renvoie la référence en tant que nouveau SV,
mais le nombre de références du SV que vous avez transmis à "newRV_inc" a été incrémenté à deux.
Maintenant, vous renvoyez la référence de la routine XSUB et oubliez le SV. Mais Perl
non ! Chaque fois que la référence renvoyée est détruite, le nombre de références de la référence originale
SV est réduit à un et rien ne se passe. Le SV va traîner sans aucun moyen de
accédez-y jusqu'à ce que Perl lui-même se termine. Il s'agit d'une fuite de mémoire.

La procédure correcte consiste donc à utiliser "newRV_noinc" au lieu de "newRV_inc". Alors, si et
lorsque la dernière référence est détruite, le compteur de références du SV passe à zéro et il
sera détruit, arrêtant toute fuite de mémoire.

Certaines fonctions pratiques sont disponibles et peuvent aider à la destruction des XV.
Ces fonctions introduisent la notion de « mortalité ». Un XV qui est mortel a eu son
nombre de références marqué pour être décrémenté, mais pas réellement décrémenté, jusqu'à ce qu'"un court
temps plus tard". Généralement, le terme "peu de temps plus tard" désigne une seule instruction Perl, telle que
un appel à une fonction XSUB. Le véritable déterminant du moment où les XV mortels ont leur
le nombre de références décrémenté dépend de deux macros, SAVETMPS et FREETMPS. Voir Perlcall
et perlxs pour plus de détails sur ces macros.

La « mortalisation » est alors dans sa forme la plus simple un « SvREFCNT_dec » différé. Cependant, si vous
mortalisez une variable deux fois, le nombre de références sera ensuite décrémenté deux fois.

Les SV "Mortel" sont principalement utilisés pour les SV placés sur la pile de Perl. Par exemple un SV
qui est créé juste pour transmettre un numéro à un sous appelé est rendu mortel pour le nettoyer
automatiquement lorsqu'il est retiré de la pile. De même, les résultats renvoyés par les XSUB
(qui sont poussés sur la pile) sont souvent rendus mortels.

Pour créer une variable mortelle, utilisez les fonctions :

SV* sv_nouveaumortel()
SV* sv_2mortel(SV*)
SV* sv_mortalcopy(SV*)

Le premier appel crée un SV mortel (sans valeur), le second convertit un SV existant en
un SV mortel (et diffère ainsi un appel à "SvREFCNT_dec"), et le troisième crée un SV mortel
copie d'un SV existant. Parce que "sv_newmortal" ne donne aucune valeur au nouveau SV, il doit
normalement en recevoir un via "sv_setpv", "sv_setiv", etc. :

SV *tmp = sv_newmortal();
sv_setiv(tmp, an_integer);

Comme il s'agit de plusieurs instructions C, c'est assez courant, alors voyez plutôt cet idiome :

SV *tmp = sv_2mortal(newSViv(an_integer));

Vous devez faire attention lorsque vous créez des variables mortelles. Des choses étranges peuvent arriver si vous
rendre la même valeur mortelle dans plusieurs contextes, ou si vous rendez une variable mortelle
plusieurs fois. Considérer la « Mortalisation » comme un « SvREFCNT_dec » différé devrait aider à
minimiser ces problèmes. Par exemple, si vous dépassez un SV que vous savoir a un high
suffisamment de REFCNT pour survivre à son utilisation sur la pile, vous n'avez besoin d'aucune mortalisation. Si tu
je ne suis pas sûr, alors faire un "SvREFCNT_inc" et "sv_2mortal", ou faire un "sv_mortalcopy" est
plus sûr.

Les routines mortelles ne sont pas réservées aux SV ; Les AV et les HV peuvent devenir mortels en passant leur
adresse (transtypée en "SV*") vers les routines "sv_2mortal" ou "sv_mortalcopy".

Caches et Globes
A planque est un hachage qui contient toutes les variables définies dans un package. Chaque clé
de la cachette est un nom de symbole (partagé par tous les différents types d'objets qui ont le
même nom), et chaque valeur de la table de hachage est une GV (Glob Value). Ce GV à son tour
contient des références aux différents objets de ce nom, y compris (mais sans s'y limiter)
ce qui suit:

Valeur scalaire
Valeur du tableau
Valeur de hachage
Poignée E/S
Format
Sous-programme

Il existe une seule réserve appelée "PL_defstash" qui contient les éléments qui existent dans le "main"
emballer. Pour accéder aux éléments d'autres packages, ajoutez la chaîne "::" au package
nom. Les éléments du package "Foo" se trouvent dans la cache "Foo ::" dans PL_defstash. Les objets
dans le package "Bar::Baz" se trouvent dans la cachette "Baz::" dans la cachette de "Bar::".

Pour obtenir le pointeur de cache pour un package particulier, utilisez la fonction :

HV* gv_stashpv(const char* nom, indicateurs I32)
HV* gv_stashsv(SV*, indicateurs I32)

La première fonction prend une chaîne littérale, la seconde utilise la chaîne stockée dans le SV.
N'oubliez pas qu'une cachette n'est qu'une table de hachage, vous récupérez donc un "HV*". Le drapeau "drapeaux"
créera un nouveau package s'il est défini sur GV_ADD.

Le nom souhaité par "gv_stash*v" est le nom du package dont vous souhaitez la table des symboles.
Le package par défaut est appelé « main ». Si vous avez plusieurs packages imbriqués, transmettez leur
noms à "gv_stash*v", séparés par "::" comme dans le langage Perl lui-même.

Alternativement, si vous avez un SV qui est une référence bénie, vous pouvez découvrir la cachette
pointeur en utilisant :

HV* SvSTASH(SvRV(SV*));

puis utilisez ce qui suit pour obtenir le nom du package lui-même :

char* HvNAME(HV* cachette);

Si vous devez bénir ou re-bénir un objet vous pouvez utiliser la fonction suivante :

SV* sv_bless(SV*, réserve HV*)

où le premier argument, un "SV*", doit être une référence, et le deuxième argument est un
planque. Le "SV*" renvoyé peut désormais être utilisé de la même manière que n'importe quel autre SV.

Pour plus d’informations sur les références et les bénédictions, consultez perlref.

Double typage SV
Les variables scalaires contiennent normalement un seul type de valeur, un entier, un double, un pointeur ou
référence. Perl convertira automatiquement les données scalaires réelles du type stocké
dans le type demandé.

Certaines variables scalaires contiennent plusieurs types de données scalaires. Par exemple, le
variable $ ! contient soit la valeur numérique de « errno », soit sa chaîne équivalente à partir de
soit "strerror" ou "sys_errlist[]".

Pour forcer plusieurs valeurs de données dans un SV, vous devez faire deux choses : utiliser le "sv_set*v"
routines pour ajouter le type scalaire supplémentaire, puis définir un indicateur pour que Perl le croie
contient plus d’un type de données. Les quatre macros pour définir les indicateurs sont :

SvIOK_on
SvNOK_on
SvPOK_on
SvROK_on

La macro particulière que vous devez utiliser dépend de la routine "sv_set*v" que vous avez appelée en premier.
C'est parce que chaque routine "sv_set*v" active uniquement le bit pour le type particulier de
les données sont définies et désactive tout le reste.

Par exemple, pour créer une nouvelle variable Perl appelée "dberror" qui contient à la fois le chiffre
et les valeurs d'erreur de chaîne descriptives, vous pouvez utiliser le code suivant :

extern int erreur ;
char externe *dberror_list;

SV* sv = get_sv("dberror", GV_ADD);
sv_setiv(sv, (IV) erreur);
sv_setpv(sv, dberror_list[dberror]);
SvIOK_on(sv);

Si l'ordre de "sv_setiv" et "sv_setpv" avait été inversé, alors la macro "SvPOK_on"
devrait être appelé à la place de "SvIOK_on".

Lecture seulement Nos valeurs
Dans Perl 5.16 et versions antérieures, la copie sur écriture (voir la section suivante) partageait un bit d'indicateur avec
scalaires en lecture seule. Ainsi, la seule façon de tester si "sv_setsv", etc., générera un
L'erreur "Modification d'une valeur en lecture seule" dans ces versions est :

SvREADONLY(sv) && !SvIsCOW(sv)

Sous Perl 5.18 et versions ultérieures, SvREADONLY s'applique uniquement aux variables en lecture seule et, sous
5.20, les scalaires de copie sur écriture peuvent également être en lecture seule, donc la vérification ci-dessus est incorrecte. Toi
je veux juste:

SvREADONLY(sv)

Si vous devez effectuer cette vérification souvent, définissez votre propre macro comme ceci :

#si PERL_VERSION >= 18
# définir SvTRULYREADONLY(sv) SvREADONLY(sv)
#else
# définir SvTRULYREADONLY(sv) (SvREADONLY(sv) && !SvIsCOW(sv))
#endif

Copier on Écrire
Perl implémente un mécanisme de copie sur écriture (COW) pour les scalaires, dans lequel les copies de chaînes sont
pas immédiatement effectués sur demande, mais sont différés jusqu'à ce que cela soit rendu nécessaire par l'un ou l'autre
autre changement scalaire. C'est en grande partie transparent, mais il faut faire attention à ne pas modifier
tampons de chaîne partagés par plusieurs SV.

Vous pouvez tester si un SV utilise la copie sur écriture avec "SvIsCOW(sv)".

Vous pouvez forcer un SV à créer sa propre copie de son tampon de chaîne en appelant
"sv_force_normal(sv)" ou SvPV_force_nolen(sv).

Si vous souhaitez que le SV supprime son tampon de chaîne, utilisez "sv_force_normal_flags(sv,
SV_COW_DROP_PV)" ou simplement "sv_setsv(sv, NULL)".

Toutes ces fonctions croassent sur les scalaires en lecture seule (voir la section précédente pour plus d'informations).
sur ceux-là).

Pour tester que votre code se comporte correctement et ne modifie pas les tampons COW, sur les systèmes
ce soutien mmap(2) (c'est-à-dire Unix), vous pouvez configurer Perl avec
"-Accflags=-DPERL_DEBUG_READONLY_COW" et cela transformera les violations de tampon en crash.
Vous le trouverez merveilleusement lent, vous souhaiterez donc peut-être ignorer les propres tests de Perl.

la magie Variables
[Cette section est encore en construction. Ignorez tout ici. Ne publiez aucune facture.
Tout ce qui n'est pas permis est interdit.]

Tout SV peut être magique, c'est-à-dire qu'il possède des caractéristiques spéciales qu'un SV normal n'a pas.
Ces fonctionnalités sont stockées dans la structure SV dans une liste chaînée de "struct magic",
tapé en "MAGIC".

structurer la magie {
MAGIE* mg_moremagic;
MGVTBL* mg_virtual ;
U16 mg_privé ;
char mg_type;
U8mg_flags;
I32 mg_len;
SV* mg_obj;
char* mg_ptr;
};

Notez que ceci est à jour au niveau de patch 0 et peut changer à tout moment.

Attribution la magie
Perl ajoute de la magie à un SV en utilisant la fonction sv_magic :

void sv_magic(SV* sv, SV* obj, int comment, const char* nom, I32 namlen);

L'argument "sv" est un pointeur vers le SV qui doit acquérir une nouvelle fonctionnalité magique.

Si "sv" n'est pas déjà magique, Perl utilise la macro "SvUPGRADE" pour convertir "sv" en type
"SVt_PVMG". Perl continue ensuite en ajoutant une nouvelle magie au début de la liste chaînée
de fonctionnalités magiques. Toute entrée antérieure du même type de magie est supprimée. Noter que
cela peut être annulé et plusieurs instances du même type de magie peuvent être associées
avec un SV.

Les arguments "name" et "namlen" sont utilisés pour associer une chaîne à la magie, généralement
le nom d'une variable. "namlen" est stocké dans le champ "mg_len" et si "name" n'est pas
null alors soit une copie "savepvn" de "name" ou "name" lui-même est stockée dans "mg_ptr"
champ, selon que "namlen" est respectivement supérieur à zéro ou égal à zéro.
Comme cas particulier, si "(name && namlen == HEf_SVKEY)", alors "name" est supposé contenir un
"SV*" et est stocké tel quel avec son REFCNT incrémenté.

La fonction sv_magic utilise "comment" pour déterminer quel "Magic Virtual" prédéfini, le cas échéant,
Table" doit être assigné au champ "mg_virtual". Voir les "Magic Virtual Tables".
section ci-dessous. L'argument "comment" est également stocké dans le champ "mg_type". La valeur de
"comment" doit être choisi parmi l'ensemble de macros "PERL_MAGIC_foo" trouvées dans perl.h. Noter que
avant l'ajout de ces macros, les composants internes de Perl utilisaient directement des caractères littéraux, donc
vous pouvez parfois rencontrer du vieux code ou de la documentation faisant plutôt référence à la magie « U »
que "PERL_MAGIC_uvar" par exemple.

L'argument "obj" est stocké dans le champ "mg_obj" de la structure "MAGIC". Si ce n'est pas le cas
comme pour l'argument "sv", le nombre de références de l'objet "obj" est incrémenté. Si
c'est pareil, ou si l'argument "comment" est "PERL_MAGIC_arylen", ou si c'est un NULL
pointeur, alors "obj" est simplement stocké, sans que le décompte de références soit incrémenté.

Voir aussi "sv_magicext" dans perlapi pour une manière plus flexible d'ajouter de la magie à un SV.

Il existe également une fonction pour ajouter de la magie à un "HV" :

void hv_magic(HV *hv, GV *gv, int comment);

Cela appelle simplement "sv_magic" et contraint l'argument "gv" en "SV".

Pour supprimer la magie d'un SV, appelez la fonction sv_unmagic :

int sv_unmagic(SV *sv, type int);

L'argument "type" doit être égal à la valeur "comment" lors de la création initiale du "SV".
magique.

Cependant, notez que "sv_unmagic" supprime toute magie d'un certain "type" du "SV". Si
vous souhaitez supprimer uniquement certaines magies d'un "type" basé sur la table virtuelle magique, utilisez
"sv_unmagicext" à la place :

int sv_unmagicext(SV *sv, type int, MGVTBL *vtbl);

la magie Salle de conférence virtuelle Tableaux
Le champ "mg_virtual" dans la structure "MAGIC" est un pointeur vers un "MGVTBL", qui est un
structure de pointeurs de fonction et signifie "Magic Virtual Table" pour gérer les différents
opérations qui pourraient être appliquées à cette variable.

Le « MGVTBL » comporte cinq (ou parfois huit) pointeurs vers les types de routines suivants :

int (*svt_get)(SV* sv, MAGIC* mg);
int (*svt_set)(SV* sv, MAGIC* mg);
U32 (*svt_len)(SV* sv, MAGIC* mg) ;
int (*svt_clear)(SV* sv, MAGIC* mg);
int (*svt_free)(SV* sv, MAGIC* mg);

int (*svt_copy)(SV *sv, MAGIC* mg, SV *nsv,
const char *nom, I32 nom);
int (*svt_dup)(MAGIQUE *mg, CLONE_PARAMS *param);
int (*svt_local)(SV *nsv, MAGIE *mg);

Cette structure MGVTBL est définie au moment de la compilation dans perl.h et il existe actuellement 32 types.
Ces différentes structures contiennent des pointeurs vers diverses routines qui effectuent des tâches supplémentaires.
actions en fonction de la fonction appelée.

Pointeur de fonction Action entreprise
---------------- ------------
svt_get Faire quelque chose avant que la valeur du SV ne soit
récupéré.
svt_set Faire quelque chose après que le SV ait reçu une valeur.
svt_len Rapport sur la longueur du SV.
svt_clear Efface quelque chose que le SV représente.
svt_free Libère tout espace de stockage supplémentaire associé au SV.

svt_copy copie la magie de la variable liée à un élément lié
svt_dup duplique une structure magique lors du clonage de threads
svt_local copie la magie vers la valeur locale pendant 'local'

Par exemple, la structure MGVTBL appelée "vtbl_sv" (qui correspond à un "mg_type" de
"PERL_MAGIC_sv") contient :

{ magic_get, magic_set, magic_len, 0, 0 }

Ainsi, lorsqu'un SV est déterminé comme étant magique et de type "PERL_MAGIC_sv", si un get
l'opération est en cours, la routine "magic_get" est appelée. Toutes les différentes routines
car les différents types magiques commencent par "magic_". REMARQUE : les routines magiques ne sont pas
considéré comme faisant partie de l'API Perl et ne peut pas être exporté par la bibliothèque Perl.

Les trois derniers emplacements sont un ajout récent et, pour des raisons de compatibilité du code source, ils sont
vérifié uniquement si l'un des trois indicateurs MGf_COPY, MGf_DUP ou MGf_LOCAL est défini dans
mg_flags. Cela signifie que la plupart du code peut continuer à déclarer une table virtuelle comme une valeur à 5 éléments.
Ces trois éléments sont actuellement utilisés exclusivement par le code de threading et sont fortement soumis
à changer.

Les types actuels de tables virtuelles magiques sont :

type_mg
(char et macro à l'ancienne) MGVTBL Type de magie
-------------------------- ------ -------------
\0 PERL_MAGIC_sv vtbl_sv Variable scalaire spéciale
# PERL_MAGIC_arylen vtbl_arylen Longueur du tableau ($#ary)
% PERL_MAGIC_rhash (aucun) Données supplémentaires pour les accès restreints
hashes
* PERL_MAGIC_debugvar vtbl_debugvar $DB::single, signal, trace
vars
. PERL_MAGIC_pos vtbl_pos pos() lvalue
: PERL_MAGIC_symtab (aucun) Données supplémentaires pour le symbole
les tables
< PERL_MAGIC_backref vtbl_backref Pour les données de référence faibles
@ PERL_MAGIC_arylen_p (aucun) Pour déplacer Arylen hors de XPVAV
B PERL_MAGIC_bm vtbl_regexp Boyer-Moore
(recherche rapide de chaîne)
c PERL_MAGIC_overload_table vtbl_ovrld Contient la table de surcharge
(AMT) sur la réserve
D PERL_MAGIC_regdata vtbl_regdata Données de position de correspondance Regex
(@+ et @-vars)
d PERL_MAGIC_regdatum vtbl_regdatum Données de position de correspondance Regex
un élément
E PERL_MAGIC_env vtbl_env hachage %ENV
e élément de hachage PERL_MAGIC_envelem vtbl_envelem %ENV
f PERL_MAGIC_fm vtbl_regexp Ligne de formulaire
(format 'compilé')
g PERL_MAGIC_regex_global vtbl_mglob m//g cible
H PERL_MAGIC_hints vtbl_hints %^H hachage
h PERL_MAGIC_hintselem vtbl_hintselem %^H élément de hachage
Je PERL_MAGIC_isa vtbl_isa @ISA tableau
i PERL_MAGIC_isaelem vtbl_isaelem @ISA élément de tableau
k PERL_MAGIC_nkeys vtbl_nkeys scalaire(keys()) lvalue
L PERL_MAGIC_dbfile (aucun) Débogueur %_
l PERL_MAGIC_dbline vtbl_dbline Débogueur %_
un élément
N PERL_MAGIC_shared (aucun) Partagé entre les threads
n PERL_MAGIC_shared_scalar (aucun) Partagé entre les threads
o PERL_MAGIC_collxfrm vtbl_collxfrm Transformation locale
P PERL_MAGIC_tied vtbl_pack Tableau ou hachage lié
p PERL_MAGIC_tiedelem vtbl_packelem Tableau lié ou élément de hachage
q PERL_MAGIC_tiedscalar vtbl_packelem Scalaire ou handle lié
r PERL_MAGIC_qr vtbl_regexp Qr// regex précompilé
S PERL_MAGIC_sig (aucun) Hachage %SIG
s PERL_MAGIC_sigelem vtbl_sigelem Élément de hachage %SIG
t PERL_MAGIC_taint vtbl_taint Soucoupe
U PERL_MAGIC_uvar vtbl_uvar Disponible pour utilisation par
extensions
u PERL_MAGIC_uvar_elem (aucun) Réservé à l'usage de
extensions
V PERL_MAGIC_vstring (aucun) SV était un littéral vstring
v PERL_MAGIC_vec vtbl_vec vec() lvalue
w PERL_MAGIC_utf8 vtbl_utf8 Informations UTF-8 mises en cache
x PERL_MAGIC_substr vtbl_substr substr() lvalue
y PERL_MAGIC_defelem vtbl_defelem Itérateur Shadow "foreach"
paramètre variable/intelligent
vivification
\ PERL_MAGIC_lvref vtbl_lvref Référence Lvalue
constructeur
] PERL_MAGIC_checkcall vtbl_checkcall Inlining/mutation d'appel
à ce CV
~ PERL_MAGIC_ext (aucun) Disponible pour une utilisation par
extensions

Lorsqu'une lettre majuscule et une lettre minuscule existent toutes deux dans le tableau, alors la lettre majuscule
est généralement utilisé pour représenter une sorte de type composite (une liste ou un hachage), et le
la lettre minuscule est utilisée pour représenter un élément de ce type composite. Quelques éléments internes
le code utilise cette relation de cas. Cependant, 'v' et 'V' (vec et v-string) sont dans
aucun rapport.

Les types de magie "PERL_MAGIC_ext" et "PERL_MAGIC_uvar" sont définis spécifiquement pour être utilisés par
extensions et ne sera pas utilisé par Perl lui-même. Les extensions peuvent utiliser la magie "PERL_MAGIC_ext"
pour « attacher » des informations privées à des variables (généralement des objets). C'est particulièrement
utile car il n'y a aucun moyen pour le code Perl normal de corrompre ces informations privées
(contrairement à l'utilisation d'éléments supplémentaires d'un objet de hachage).

De même, la magie "PERL_MAGIC_uvar" peut être utilisée un peu comme attacher() appeler une fonction C n'importe quel
heure à laquelle la valeur d'un scalaire est utilisée ou modifiée. Le champ "mg_ptr" du "MAGIC" pointe vers un
Structure "ufuncs":

structure ufuncs {
I32 (*uf_val)(pTHX_IV, SV*);
I32 (*uf_set)(pTHX_IV, SV*);
IVuf_index ;
};

Lorsque le SV est lu ou écrit, la fonction "uf_val" ou "uf_set" sera appelée
avec "uf_index" comme premier argument et un pointeur vers le SV comme second. Un exemple simple
La façon d'ajouter la magie "PERL_MAGIC_uvar" est présentée ci-dessous. Notez que la structure ufuncs est
copié par sv_magic, afin que vous puissiez l'allouer en toute sécurité sur la pile.

annuler
Umagique(sv)
SV *sv;
PREINIT :
struct ufuncs uf ;
CODE:
uf.uf_val = &my_get_fn;
uf.uf_set = &my_set_fn;
uf.uf_index = 0 ;
sv_magic(sv, 0, PERL_MAGIC_uvar, (char*)&uf, sizeof(uf));

Attacher "PERL_MAGIC_uvar" aux tableaux est autorisé mais n'a aucun effet.

Pour les hachages, il existe un hook spécialisé qui permet de contrôler les clés de hachage (mais pas les valeurs).
Ce hook appelle "PERL_MAGIC_uvar" 'get' magic si la fonction "set" dans "ufuncs"
la structure est NULLe. Le hook est activé chaque fois que le hachage est accessible avec une clé
spécifié comme "SV" via les fonctions "hv_store_ent", "hv_fetch_ent",
"hv_delete_ent" et "hv_exists_ent". Accéder à la clé sous forme de chaîne via les fonctions
sans le suffixe "..._ent" contourne le crochet. Voir "GUTS" dans Hash :: Util :: FieldHash
pour une description détaillée.

Notez que, comme plusieurs extensions peuvent utiliser "PERL_MAGIC_ext" ou "PERL_MAGIC_uvar",
par magie, il est important que les extensions fassent très attention pour éviter les conflits. Typiquement
utiliser la magie uniquement sur des objets bénis dans la même classe que celle de l'extension
suffisant. Pour la magie "PERL_MAGIC_ext", c'est généralement une bonne idée de définir un "MGVTBL",
même si tous ses champs seront 0, de sorte que les pointeurs individuels "MAGIC" puissent être identifiés comme
un type particulier de magie grâce à leur table virtuelle magique. "mg_findext" fournit un moyen simple
façon de faire :

STATIQUE MGVTBL mon_vtbl = { 0, 0, 0, 0, 0, 0, 0, 0 } ;

MAGIE *mg;
if ((mg = mg_findext(sv, PERL_MAGIC_ext, &my_vtbl))) {
/* c'est vraiment le nôtre, pas le PERL_MAGIC_ext d'un autre module */
my_priv_data_t *priv = (my_priv_data_t *)mg->mg_ptr;
...
}

Notez également que les fonctions "sv_set*()" et "sv_cat*()" décrites précédemment pas invoquer
« mettre » de la magie sur leurs cibles. Cela doit être fait par l'utilisateur soit en appelant le
Macro "SvSETMAGIC()" après avoir appelé ces fonctions, ou en utilisant l'un des "sv_set*_mg()"
ou les fonctions "sv_cat*_mg()". De même, le code C générique doit appeler la macro "SvGETMAGIC()"
pour invoquer toute magie « obtenir » s'ils utilisent un SV obtenu à partir de sources externes dans les fonctions
qui ne gère pas la magie. Voir perlapi pour une description de ces fonctions. Par exemple,
les appels aux fonctions "sv_cat*()" doivent généralement être suivis de "SvSETMAGIC()", mais
ils n'ont pas besoin d'un "SvGETMAGIC()" préalable puisque leur implémentation gère la magie "get".

Trouver la magie
MAGIE *mg_find(SV *sv, type int); /* Trouve le pointeur magique de cela
* taper */

Cette routine renvoie un pointeur vers une structure "MAGIC" stockée dans le SV. Si le SV le fait
n'ont pas cette fonctionnalité magique, "NULL" est renvoyé. Si le SV a plusieurs instances de
cette fonctionnalité magique, la première sera restituée. "mg_findext" peut être utilisé pour trouver un
Structure "MAGIQUE" d'un SV basée à la fois sur son type magique et sur sa table virtuelle magique :

MAGIE *mg_findext(SV *sv, type int, MGVTBL *vtbl);

De plus, si le SV passé à "mg_find" ou "mg_findext" n'est pas du type SVt_PVMG, Perl peut
déverser.

int mg_copy(SV* sv, SV* nsv, clé const char*, STRLEN klen);

Cette routine vérifie quels types de magie possède "sv". Si le champ mg_type est un
lettre majuscule, alors le mg_obj est copié dans "nsv", mais le champ mg_type est remplacé par
être la lettre minuscule.

LUMIÈRE SUR NOS le la magie of Attaché Des hachis et Arrays
Les hachages et tableaux liés sont des bêtes magiques du type magique "PERL_MAGIC_tied".

AVERTISSEMENT : à partir de la version 5.004, l'utilisation appropriée des fonctions d'accès au tableau et au hachage
nécessite de comprendre quelques mises en garde. Certaines de ces mises en garde sont en fait considérées comme des bugs
dans l'API, qui seront corrigés dans les versions ultérieures, et sont entourés de [MAYCHANGE] ci-dessous. Si
vous vous retrouvez à appliquer réellement ces informations dans cette section, sachez que le
le comportement peut changer à l’avenir, euh, sans avertissement.

La fonction perl tie associe une variable à un objet qui implémente les différentes
Méthodes GET, SET, etc. Pour effectuer l'équivalent de la fonction perl tie à partir d'un XSUB,
vous devez imiter ce comportement. Le code ci-dessous effectue les étapes nécessaires -- d'abord
il crée un nouveau hachage, puis crée un deuxième hachage qu'il bénit dans la classe
qui mettra en œuvre les méthodes de cravate. Enfin, il relie les deux hachages et renvoie
une référence au nouveau hachage lié. Notez que le code ci-dessous n'appelle PAS le TIEHASH
méthode dans la classe MyTie - voir "Appel de routines Perl depuis des programmes C" pour plus de détails
sur la façon de le faire.

VS*
mytie()
PREINIT :
HV *hachage ;
HV *cache ;
SV *égalité;
CODE:
hachage = newHV();
tie = newRV_noinc((SV*)newHV());
cachette = gv_stashpv("MaTie", GV_ADD);
sv_bless(cravate, cachette);
hv_magic(hash, (GV*)tie, PERL_MAGIC_tied);
RETVAL = newRV_noinc(hash);
SORTIE:
RETOUR

La fonction "av_store", lorsqu'on lui donne un argument de tableau lié, copie simplement la magie du
tableau sur la valeur à "stocker", en utilisant "mg_copy". Il peut également renvoyer NULL, indiquant
que la valeur n'avait pas réellement besoin d'être stockée dans le tableau. [PEUTCHANGER] Après un appel
vers "av_store" sur un tableau lié, l'appelant devra généralement appeler "mg_set(val)" pour
invoquez en fait la méthode "STORE" de niveau Perl sur l'objet TIEARRAY. Si "av_store" l'a fait
renvoie NULL, un appel à "SvREFCNT_dec(val)" sera aussi généralement nécessaire pour éviter un
fuite de mémoire. [/PEUT CHANGER]

Le paragraphe précédent s'applique textuellement à l'accès au hachage lié à l'aide de "hv_store" et
"hv_store_ent" fonctionne également.

"av_fetch" et les fonctions de hachage correspondantes "hv_fetch" et "hv_fetch_ent" en fait
renvoie une valeur mortelle indéfinie dont la magie a été initialisée à l'aide de "mg_copy". Note
la valeur ainsi renvoyée n'a pas besoin d'être désallouée, car elle est déjà mortelle.
[MAYCHANGE] Mais vous devrez appeler "mg_get()" sur la valeur renvoyée afin de
invoquez en fait la méthode "FETCH" de niveau Perl sur l'objet TIE sous-jacent. De la même manière,
vous pouvez également appeler "mg_set()" sur la valeur de retour après avoir éventuellement attribué une valeur appropriée
en utilisant "sv_setsv", qui invoquera la méthode "STORE" sur l'objet TIE.
[/PEUT CHANGER]

[MAYCHANGE] En d'autres termes, les fonctions de récupération/stockage de tableau ou de hachage ne récupèrent pas vraiment et
stocker les valeurs réelles dans le cas de tableaux et de hachages liés. Ils appellent simplement "mg_copy" pour
attachez de la magie aux valeurs qui étaient censées être « stockées » ou « récupérées ». Appels ultérieurs à
"mg_get" et "mg_set" font en fait le travail d'invoquer les méthodes TIE sur le sous-jacent
objets. Ainsi le mécanisme magique implémente actuellement une sorte d'accès paresseux aux tableaux
et des hachages.

Actuellement (à partir de la version Perl 5.004), l'utilisation des fonctions d'accès au hachage et au tableau nécessite
l'utilisateur de savoir s'il opère sur des hachages et des tableaux "normaux", ou sur
leurs variantes liées. L'API peut être modifiée pour fournir un accès plus transparent aux deux
types de données liés et normaux dans les versions futures. [/PEUT CHANGER]

Vous feriez bien de comprendre que les interfaces TIEARRAY et TIEHASH ne sont que du sucre pour
invoquez certains appels de méthode Perl tout en utilisant la syntaxe uniforme de hachage et de tableau. L'utilisation de
ce sucre impose une certaine surcharge (généralement environ deux à quatre opcodes supplémentaires par
Opération FETCH/STORE, en plus de la création de toutes les variables mortelles nécessaires à
invoquer les méthodes). Cette surcharge sera relativement faible si les méthodes TIE sont
eux-mêmes substantiels, mais s'ils ne comportent que quelques instructions, la surcharge ne sera pas
être insignifiant.

Localisation change
Perl a une construction très pratique

{
local $var = 2 ;
...
}

Cette construction est d'environ équivalente à

{
mon $oldvar = $var;
$var = 2;
...
$var = $anciennevar;
}

La plus grande différence est que la première construction rétablirait la valeur initiale de
$var, quelle que soit la façon dont le contrôle quitte le bloc : "goto", "return", "die"/"eval", etc.
C'est aussi un peu plus efficace.

Il existe un moyen de réaliser une tâche similaire à partir de C via l'API Perl : créer un pseudo-blocet
faire en sorte que certaines modifications soient automatiquement annulées à la fin, soit explicites, soit
via une sortie non locale (via mourir()). A bloc-une construction de type est créée par une paire de
Macros "ENTER"/"LEAVE" (voir "Retourner un scalaire" dans perlcall). Une telle construction peut être
créé spécialement pour une tâche localisée importante, ou une tâche existante (comme les limites
de sous-programme/bloc Perl englobant, ou une paire existante pour libérer les TMP) peut être utilisée.
(Dans le second cas, les frais généraux liés à une localisation supplémentaire doivent être presque négligeables.)
Notez que tout XSUB est automatiquement enfermé dans une paire "ENTER"/"LEAVE".

À l'intérieur d'un tel pseudo-bloc le service suivant est disponible :

"SAVEINT(int i)"
"SAUVEGARDER IV (IV i)"
"ENREGISTRER32(I32i)"
" SAVELONG (long i) "
Ces macros organisent les choses pour restaurer la valeur de la variable entière "i" à la fin de
enfermant pseudo-bloc.

SAVESPTR(s)
SAVEPPTR(p)
Ces macros organisent les choses pour restaurer la valeur des pointeurs "s" et "p". "s" doit être
un pointeur d'un type qui survit à la conversion en "SV*" et inversement, "p" devrait pouvoir
survivre à la conversion en "char*" et inversement.

"ENREGISTRER GRATUITEMENT(SV *sv)"
Le recompte de "sv" serait décrémenté à la fin de pseudo-bloc. C'est pareil
à "sv_2mortal" en ce sens qu'il s'agit également d'un mécanisme permettant d'effectuer un "SvREFCNT_dec" retardé.
Cependant, alors que « sv_2mortal » prolonge la durée de vie de « sv » jusqu'au début du
L'instruction suivante, "SAVEFREESV", l'étend jusqu'à la fin de la portée englobante. Ces
les vies peuvent être très différentes.

Comparez également "SAVEMORTALIZESV".

"SAVEMORTALIZESV(SV *sv)"
Tout comme "SAVEFREESV", mais mortalise "sv" à la fin de la portée actuelle au lieu de
décrémenter son compte de référence. Cela a généralement pour effet de maintenir "sv" en vie
jusqu'à ce que l'instruction qui a appelé la portée actuellement active ait fini de s'exécuter.

"ENREGISTRERFREEOP(OP *op)"
Le "OP *" est op_free()ed à la fin de pseudo-bloc.

ENREGISTRERFREEPV(p)
La partie de la mémoire désignée par "p" est Sans sécurité()ed à la fin de pseudo-
bloc.

"SAVECLEARSV(SV *sv)"
Efface un emplacement dans le bloc-notes actuel qui correspond à "sv" à la fin de
pseudo-bloc.

"SAVEDELETE(HV *hv, char *key, longueur I32)"
La clé "key" de "hv" est supprimée à la fin de pseudo-bloc. La chaîne pointée par
"clé" est Sans sécurité()éd. Si l'on a un clé en stockage de courte durée, le correspondant
la chaîne peut être réaffectée comme ceci :

SAVEDELETE(PL_defstash, savepv(tmpbuf), strlen(tmpbuf));

"SAVEDESTRUCTOR(DESTRUCTORFUNC_NOCONTEXT_t f, void *p)"
A la fin de pseudo-bloc la fonction "f" est appelée avec pour seul argument "p".

"SAVEDESTRUCTOR_X(DESTRUCTORFUNC_t f, vide *p)"
A la fin de pseudo-bloc la fonction "f" est appelée avec le contexte implicite
argument (le cas échéant) et "p".

"SAVESTACK_POS()"
L'offset actuel sur la pile interne Perl (cf. "SP") est restauré en fin de
pseudo-bloc.

La liste d'API suivante contient des fonctions, il faut donc fournir des pointeurs vers les
données modifiables explicitement (soit des pointeurs C, soit des "GV *" Perlish). Où ce qui précède
les macros prennent "int", une fonction similaire prend "int *".

"SV* save_scalar(GV *gv)"
Équivalent au code Perl "local $gv".

"AV* save_ary(GV *gv)"
"HV* save_hash(GV *gv)"
Similaire à "save_scalar", mais localisez @gv et %gv.

"void save_item(SV *item)"
Duplique la valeur actuelle de "SV", à la sortie du courant "ENTER"/"LEAVE"
pseudo-bloc restaurera la valeur de "SV" en utilisant la valeur stockée. Ça ne gère pas
la magie. Utilisez "save_scalar" si la magie est affectée.

"void save_list(SV **sarg, I32 maxsarg)"
Une variante de "save_item" qui prend plusieurs arguments via un tableau "sarg" de "SV*"
de longueur "maxsarg".

"SV* save_svref(SV **sptr)"
Similaire à "save_scalar", mais rétablira un "SV *".

"void save_aptr(AV **aptr)"
"void save_hptr(HV **hptr)"
Similaire à "save_svref", mais localise "AV *" et "HV *".

Le module "Alias" implémente la localisation des types de base au sein du l'appelant portée.
Les personnes intéressées par la façon de localiser les éléments dans la portée conteneur devraient prendre un
regarde là aussi.

Sous-programmes


XSUB et le Argument Stack
Le mécanisme XSUB est un moyen simple pour les programmes Perl d'accéder aux sous-programmes C. Un XSUB
routine aura une pile contenant les arguments du programme Perl et un moyen de
mapper les structures de données Perl vers un équivalent C.

Les arguments de la pile sont accessibles via la macro ST(n), qui renvoie la "n"ème pile
argument. L'argument 0 est le premier argument passé dans l'appel du sous-programme Perl. Ces
les arguments sont "SV*" et peuvent être utilisés partout où un "SV*" est utilisé.

La plupart du temps, la sortie de la routine C peut être gérée via l'utilisation des commandes RETVAL et
Directives de SORTIE. Cependant, il existe des cas où la pile d'arguments n'est pas déjà
assez long pour gérer toutes les valeurs de retour. Un exemple est le POSIX tzname() appeler, ce qui
ne prend aucun argument, mais en renvoie deux, l'heure standard du fuseau horaire local et l'heure d'été
abréviations.

Pour gérer cette situation, la directive PPCODE est utilisée et la pile est étendue à l'aide de la
macro :

EXTEND(SP, num);

où "SP" est la macro qui représente la copie locale du pointeur de pile et "num" est
le nombre d'éléments par lesquels la pile doit être étendue.

Maintenant qu'il y a de la place sur la pile, les valeurs peuvent y être poussées à l'aide de la macro "PUSHs". Le
les valeurs poussées devront souvent être « mortelles » (voir « Nombre de références et mortalité ») :

PUSH (sv_2mortal (newSViv (an_integer)))
PUSH (sv_2mortal (newSVuv (an_unsigned_integer)))
PUSH (sv_2mortal (newSVnv (a_double)))
PUSH(sv_2mortal(newSVpv("Une chaîne",0)))
/* Bien que le dernier exemple soit mieux écrit car plus
* efficace: */
PUSH(newSVpvs_flags("Une chaîne", SVs_TEMP))

Et maintenant le programme Perl appelant "tzname", les deux valeurs seront assignées comme dans :

($standard_abbrev, $summer_abbrev) = POSIX::tzname;

Une méthode alternative (et peut-être plus simple) pour pousser les valeurs sur la pile consiste à utiliser le
macro :

XPUSH (SV*)

Cette macro ajuste automatiquement la pile pour vous, si nécessaire. Ainsi, vous n'avez pas besoin de
appelez "EXTEND" pour étendre la pile.

Malgré leurs suggestions dans les versions antérieures de ce document, les macros "(X)PUSH[iunp]"
sommes-nous pas adapté aux XSUB qui renvoient plusieurs résultats. Pour cela, soit s'en tenir au
Macros "(X)PUSHs" présentées ci-dessus, ou utilisez plutôt les nouvelles macros "m(X)PUSH[iunp]" ; voir
"Mettre une valeur C sur la pile Perl".

Pour plus d'informations, consultez perlxs et perlxstut.

Chargement automatique avec XSUB
Si une routine AUTOLOAD est un XSUB, comme c'est le cas pour les sous-programmes Perl, Perl place le nom pleinement qualifié
nom du sous-programme chargé automatiquement dans la variable $AUTOLOAD du package XSUB.

Mais il met également les mêmes informations dans certains champs du XSUB lui-même :

HV *cache = CvSTASH(cv);
const char *sous-nom = SvPVX(cv);
STRLEN nom_longueur = SvCUR(cv); /* en octets */
U32 is_utf8 = SvUTF8(cv);

"SvPVX(cv)" contient uniquement le sous-nom lui-même, sans compter le package. Pour un AUTOLOAD
routine dans UNIVERSAL ou l'une de ses superclasses, "CvSTASH(cv)" renvoie NULL lors d'un
appel de méthode sur un package inexistant.

Note: Le paramètre $AUTOLOAD a cessé de fonctionner dans la version 5.6.1, qui ne prenait pas en charge les sous-marins XS AUTOLOAD
du tout. Perl 5.8.0 a introduit l'utilisation de champs dans le XSUB lui-même. Perl 5.16.0 restauré
le réglage de $AUTOLOAD. Si vous devez prendre en charge 5.8-5.14, utilisez les champs du XSUB.

appel Perl Routines à partir de dans les C Programmes
Il existe quatre routines qui peuvent être utilisées pour appeler un sous-programme Perl à partir d'un langage C.
programme. Ces quatre sont :

I32 call_sv(SV*, I32);
I32 call_pv(const char*, I32);
I32 call_method(const char*, I32);
I32 call_argv(const char*, I32, char**);

La routine la plus souvent utilisée est "call_sv". L'argument "SV*" contient soit le nom de
le sous-programme Perl à appeler, ou une référence au sous-programme. Le deuxième argument
se compose d'indicateurs qui contrôlent le contexte dans lequel le sous-programme est appelé, que ce soit ou non.
ce n'est pas le sous-programme qui reçoit les arguments, comment les erreurs doivent être interceptées et comment
traiter les valeurs de retour.

Les quatre routines renvoient le nombre d'arguments que le sous-programme a renvoyé sur Perl
association.

Ces routines étaient appelées "perl_call_sv", etc., avant Perl v5.6.0, mais ces noms
sont désormais obsolètes ; des macros du même nom sont fournies pour des raisons de compatibilité.

Lors de l'utilisation de l'une de ces routines (sauf "call_argv"), le programmeur doit manipuler le
Pile Perl. Celles-ci incluent les macros et fonctions suivantes :

dSP
SP
MARQUE-POUSSOIR()
REMETTRE
ESPAGNE
ENTRER
SAUVEGARDERTMPS
GRATUITTMPS
FEUILLES DE TEMPS
XPUSH*()
POPULAIRE*()

Pour une description détaillée des conventions d'appel de C vers Perl, consultez perlcall.

Putting a C valeur on Perl empiler
De nombreux opcodes (il s'agit d'une opération élémentaire dans la machine à pile Perl interne) mettent
un SV* sur la pile. Cependant, à titre d'optimisation, le SV correspondant n'est (généralement) pas
recréé à chaque fois. Les opcodes réutilisent des SV spécialement attribués (l'objectifs) qui sont (en tant que
corollaire) pas constamment libéré/créé.

Chacune des cibles n'est créée qu'une seule fois (mais voir "Scratchpads et récursivité" ci-dessous), et
lorsqu'un opcode doit mettre un entier, un double ou une chaîne sur la pile, il définit simplement le
parties correspondantes de son l'objectif et met le l'objectif sur pile.

La macro pour mettre cette cible sur la pile est "PUSHTARG", et elle est directement utilisée dans certains
opcodes, ainsi qu'indirectement dans des millions d'autres, qui l'utilisent via "(X)PUSH[iunp]".

Étant donné que la cible est réutilisée, vous devez être prudent lorsque vous transmettez plusieurs valeurs sur le
empiler. Le code suivant ne fera pas ce que vous pensez :

XPUSHi(10);
XPUSHi(20);

Cela se traduit par "réglez "TARG" sur 10, poussez un pointeur vers "TARG" sur la pile ; définissez "TARG"
à 20, poussez un pointeur vers "TARG" sur la pile". A la fin de l'opération, la pile
ne contient pas les valeurs 10 et 20, mais contient en fait deux pointeurs vers "TARG", qui
nous avons fixé à 20.

Si vous devez pousser plusieurs valeurs différentes, vous devez soit utiliser les "(X)PUSHs"
ou bien utiliser les nouvelles macros "m(X)PUSH[iunp]", dont aucune n'utilise "TARG".
Les macros "(X)PUSHs" poussent simplement un SV* sur la pile, ce qui, comme indiqué sous "XSUBs et
la pile d'arguments", devra souvent être "mortel". Les nouvelles macros "m(X)PUSH[iunp]" permettent
c'est un peu plus facile à réaliser en créant un nouveau mortel pour vous (via "(X)PUSHmortal"),
en le poussant sur la pile (en l'étendant si nécessaire dans le cas du "mXPUSH[iunp]"
macros), puis en définissant sa valeur. Ainsi, au lieu d'écrire ceci pour "corriger" l'exemple
au dessus de:

XPUSH(sv_2mortal(nouveauSViv(dix)))
XPUSH(sv_2mortal(nouveauSViv(dix)))

vous pouvez simplement écrire :

mXPUSHi(10)
mXPUSHi(20)

Dans le même ordre d'idées, si vous utilisez "(X)PUSH[iunp]", alors vous aurez besoin d'un "dTARG" dans
vos déclarations de variables afin que les macros "*PUSH*" puissent utiliser la variable locale
"TARG". Voir également « dTARGET » et « dXSTARG ».

Bloc-notes
La question reste de savoir quand les SV qui sont l'objectifdes s pour les opcodes sont créés. Le
La réponse est qu'ils sont créés lorsque l'unité actuelle - un sous-programme ou un fichier (pour les opcodes)
pour les instructions en dehors des sous-programmes) - est compilé. Pendant ce temps, un anonyme spécial
Un tableau Perl est créé, appelé bloc-notes pour l'unité actuelle.

Un bloc-notes conserve les SV qui sont des lexicaux pour l'unité actuelle et sont des cibles pour
les opcodes. Une version précédente de ce document indiquait qu'on pouvait en déduire qu'un SV vit
sur un bloc-notes en regardant ses drapeaux : les lexicaux ont "SVs_PADMY" défini, et l'objectifs ont
Ensemble "SVs_PADTMP". Mais cela n’a jamais été pleinement vrai. "SVs_PADMY" peut être défini sur un
variable qui ne réside plus dans aucun pad. Alors que l'objectifSi "SVs_PADTMP" est défini, il
peut également être défini sur des variables qui n'ont jamais résidé dans un pad, mais qui agissent néanmoins comme
l'objectifs. Depuis Perl 5.21.5, l'indicateur "SVs_PADMY" n'est plus utilisé et est défini à 0.
"SvPADMY()" renvoie désormais true pour tout ce qui ne concerne pas "SVs_PADTMP".

La correspondance entre les PO et l'objectifs n'est pas 1 pour 1. Différents OP dans la compilation
L'arbre de l'unité peut utiliser la même cible, si cela n'entre pas en conflit avec le résultat attendu.
vie du temporaire.

Bloc-notes et récursion
En fait, il n'est pas vrai à 100% qu'une unité compilée contienne un pointeur vers le scratchpad AV.
En fait, il contient un pointeur vers un AV d'un (initialement) élément, et cet élément est le
bloc-notes AV. Pourquoi avons-nous besoin d’un niveau supplémentaire d’indirection ?

La réponse est récursion, et peut-être discussions. Ces deux éléments peuvent créer plusieurs exécutions
pointeurs entrant dans le même sous-programme. Pour que le sous-programme enfant n'écrive pas sur le
des temporaires pour le sous-programme-parent (dont la durée de vie couvre l'appel à l'enfant),
le parent et l'enfant doivent avoir des blocs-notes différents. (Et les lexicaux devraient être
séparez-vous quand même !)

Ainsi, chaque sous-programme naît avec un tableau de blocs-notes (de longueur 1). A chaque entrée dans
le sous-programme, on vérifie que la profondeur actuelle de la récursion n'est pas supérieure à la
longueur de ce tableau, et si c'est le cas, un nouveau bloc-notes est créé et inséré dans le tableau.

Le l'objectifles s sur ce bloc-notes sont des "undef", mais ils sont déjà marqués avec le correct
drapeaux.

Mémoire Allocation


Allocation
Toute la mémoire destinée à être utilisée avec les fonctions de l'API Perl doit être manipulée à l'aide du
macros décrites dans cette section. Les macros assurent la transparence nécessaire entre
différences dans l'implémentation réelle de malloc utilisée dans Perl.

Il est suggéré d'activer la version de malloc distribuée avec Perl. Il
conserve des pools de différentes tailles de mémoire non allouée afin de satisfaire les demandes d'allocation
plus vite. Cependant, sur certaines plates-formes, cela peut provoquer des mallocs parasites ou des erreurs gratuites.

Les trois macros suivantes sont utilisées pour allouer initialement de la mémoire :

Newx(pointeur, nombre, type);
Newxc(pointeur, nombre, type, cast);
Newxz(pointeur, nombre, type);

Le premier argument "pointeur" doit être le nom d'une variable qui pointera vers le nouveau
mémoire allouée.

Les deuxième et troisième arguments "numéro" et "type" spécifient combien du type spécifié
de la structure des données doit être allouée. L'argument "type" est passé à "sizeof". Le
l'argument final de "Newxc", "cast", doit être utilisé si l'argument "pointeur" est différent
à partir de l'argument "type".

Contrairement aux macros "Newx" et "Newxc", la macro "Newxz" appelle "memzero" pour mettre à zéro tous les éléments.
la mémoire nouvellement allouée.

Réallocation
Renouveler (pointeur, numéro, type);
Renewc(pointeur, nombre, type, cast);
Safefree (pointeur)

Ces trois macros permettent de modifier la taille d'un tampon mémoire ou de libérer un morceau de mémoire non
plus nécessaire. Les arguments de "Renew" et "Renewc" correspondent à ceux de "New" et "Newc" avec
à l'exception de ne pas avoir besoin de l'argument "cookie magique".

Aller de l'avant
Déplacer (source, destination, numéro, type) ;
Copier(source, destination, numéro, type) ;
Zéro(destination, nombre, type) ;

Ces trois macros sont utilisées pour déplacer, copier ou mettre à zéro la mémoire précédemment allouée. Le
Les arguments "source" et "dest" pointent vers les points de départ source et destination. Perl
déplacera, copiera ou mettra à zéro les instances "nombre" de la taille de la structure de données "type"
(en utilisant la fonction "sizeof").

PerlIO


Les versions de développement les plus récentes de Perl ont expérimenté la suppression des fonctionnalités de Perl.
dépendance à la suite d'E/S standard "normale" et permettant à d'autres implémentations stdio de
être utilisé. Cela implique de créer une nouvelle couche d'abstraction qui appelle ensuite celle
l'implémentation de stdio Perl a été compilée avec. Tous les XSUB devraient désormais utiliser les fonctions de
la couche d'abstraction PerlIO et ne faire aucune hypothèse sur le type de stdio
utilisé.

Pour une description complète de l'abstraction PerlIO, consultez perlapio.

Compilé code


Code arbre
Nous décrivons ici la forme interne vers laquelle votre code est converti par Perl. Commencez par un simple
Exemple:

$a = $b + $c ;

Ceci est converti en un arbre similaire à celui-ci :

affecter à
/ \
+ $a
/ \
$b $c

(mais un peu plus compliqué). Cet arbre reflète la façon dont Perl a analysé votre code, mais
n'a rien à voir avec l'ordre d'exécution. Il y a un "thread" supplémentaire qui passe
les nœuds de l'arbre qui montre l'ordre d'exécution des nœuds. Dans notre version simplifiée
exemple ci-dessus, cela ressemble à :

$b ---> $c ---> + ---> $a ---> attribuer à

Mais avec l'arbre de compilation actuel pour "$a = $b + $c", c'est différent : certains nœuds optimisé
et. En corollaire, bien que l'arbre réel contienne plus de nœuds que notre arbre simplifié
Par exemple, l'ordre d'exécution est le même que dans notre exemple.

Examiner le arbre
Si votre Perl est compilé pour le débogage (généralement effectué avec "-DDEBUGGING" sur le
ligne de commande "Configurer"), vous pouvez examiner l'arborescence compilée en spécifiant "-Dx" sur le
Ligne de commande Perl. La sortie prend plusieurs lignes par nœud, et pour "$b+$c", cela ressemble à
ce:

5 TYPE = ajouter ===> 6
CIBLE = 1
DRAPEAUX = (SCALAIRE, ENFANTS)
{
TYPE = nul ===> (4)
(était rv2sv)
DRAPEAUX = (SCALAIRE, ENFANTS)
{
3 TYPE = gvsv ===> 4
DRAPEAUX = (SCALAIRE)
GV = principal ::b
}
}
{
TYPE = nul ===> (5)
(était rv2sv)
DRAPEAUX = (SCALAIRE, ENFANTS)
{
4 TYPE = gvsv ===> 5
DRAPEAUX = (SCALAIRE)
GV = principal ::c
}
}

Cet arbre comporte 5 nœuds (un par spécificateur "TYPE"), seuls 3 d'entre eux ne sont pas optimisés
(un par numéro dans la colonne de gauche). Les enfants immédiats du nœud donné correspondent
à des paires "{}" sur le même niveau d'indentation, donc ce listing correspond à l'arborescence :

ajouter
/ \
null Null
| |
gvsv gvsv

L'ordre d'exécution est indiqué par des marques "===>", il s'agit donc de "3 4 5 6" (le nœud 6 n'est pas
inclus dans la liste ci-dessus), c'est-à-dire "gvsv gvsv ajoute n'importe quoi".

Chacun de ces nœuds représente une opération, une opération fondamentale à l'intérieur du noyau Perl. Le
le code qui implémente chaque opération peut être trouvé dans le pp*.c des dossiers; la fonction qui
implémente l'opération de type "gvsv" est "pp_gvsv", et ainsi de suite. Comme le montre l’arbre ci-dessus,
différentes opérations ont un nombre différent d'enfants : "ajouter" est un opérateur binaire, comme on le ferait
attendez-vous, tout comme deux enfants. Pour accueillir les différents nombres de
enfants, il existe différents types de structures de données opérationnelles, et elles sont liées entre elles dans
différentes façons.

Le type de structure op le plus simple est "OP" : il n'a pas d'enfant. Opérateurs unaires,
Les "UNOP" ont un enfant, et celui-ci est indiqué par le champ "op_first". Opérateurs binaires
Les ("BINOP") ont non seulement un champ "op_first" mais aussi un champ "op_last". Le plus
Le type d'opération complexe est un "LISTOP", qui a un nombre quelconque d'enfants. Dans ce cas, le
le premier enfant est pointé par "op_first" et le dernier enfant par "op_last". Les enfants dans
between peut être trouvé en suivant itérativement le pointeur "OpSIBLING" du premier enfant
jusqu'au dernier (mais voir ci-dessous).

Il existe également d'autres types d'opérations : un "PMOP" contient une expression régulière et n'a pas d'expression régulière.
des enfants, et une "LOOP" peut ou non avoir des enfants. Si le champ "op_children" est non-
zéro, il se comporte comme un "LISTOP". Pour compliquer les choses, si un "UNOP" est en réalité un "null"
op après optimisation (voir "Compile pass 2 : propagation du contexte"), il aura toujours
enfants conformément à son ancien type.

Enfin, il existe un "LOGOP", ou opération logique. Comme un "LISTOP", celui-ci a un ou plusieurs enfants,
mais il n'a pas de champ "op_last" : il faut donc suivre "op_first" puis le
"OpSIBLING" s'enchaîne pour retrouver le dernier enfant. Au lieu de cela, il comporte un champ "op_other", qui
est comparable au champ "op_next" décrit ci-dessous et représente un champ alternatif
chemin d'exécution. Les opérateurs comme « et », « ou » et « ? sont des "LOGOP". Notez qu'en général,
"op_other" ne peut pointer vers aucun des enfants directs de "LOGOP".

À partir de la version 5.21.2, Perls construit avec la définition expérimentale "-DPERL_OP_PARENT"
ajoutez un indicateur booléen supplémentaire pour chaque opération, "op_moresib". Lorsqu'il n'est pas défini, cela indique que
c'est la dernière opération d'une chaîne "OpSIBLING". Cela libère le champ "op_sibling" sur le
dernier frère à pointer vers l'opération parent. Sous cette version, ce champ est également renommé
"op_sibparent" pour refléter son rôle commun. La macro OpSIBLING(o) enveloppe ce spécial
comportement, et renvoie toujours NULL sur le dernier frère. Avec cette construction, le op_parent(o)
La fonction peut être utilisée pour trouver le parent de n’importe quelle opération. Ainsi, pour une compatibilité ascendante, vous
doit toujours utiliser la macro OpSIBLING(o) plutôt que d'accéder directement à "op_sibling".

Une autre façon d'examiner l'arborescence consiste à utiliser un module back-end du compilateur, tel que B::Concise.

Compiler pass 1: choisissez routines
L'arborescence est créée par le compilateur tandis que yacc le code le nourrit, les constructions le
reconnaît. Depuis yacc fonctionne de bas en haut, tout comme la première passe de compilation Perl.

Ce qui rend cette passe intéressante pour les développeurs Perl, c'est qu'une certaine optimisation peut être
effectué sur cette passe. Il s'agit d'une optimisation par ce que l'on appelle des « routines de contrôle ». Le
la correspondance entre les noms de nœuds et les routines de vérification correspondantes est décrite dans
opcode.pl (n'oubliez pas de lancer "make regen_headers" si vous modifiez ce fichier).

Une routine de vérification est appelée lorsque le nœud est entièrement construit, à l'exception de l'exécution.
fil de commande. Puisqu'à l'heure actuelle, il n'y a aucun lien retour vers le site actuellement construit
nœud, on peut effectuer presque toutes les opérations sur le nœud de niveau supérieur, y compris le libérer et/ou
créer de nouveaux nœuds au-dessus/en dessous.

La routine de vérification renvoie le nœud qui doit être inséré dans l'arborescence (si le sommet
le nœud de niveau n'a pas été modifié, la routine de vérification renvoie son argument).

Par convention, les routines de contrôle portent des noms « ck_* ». Ils sont généralement appelés depuis "new*OP"
sous-programmes (ou "convert") (qui à leur tour sont appelés depuis perly.y).

Compiler pass 1a: constant pliage
Immédiatement après l'appel de la routine de vérification, le nœud renvoyé est vérifié pour être
exécutable au moment de la compilation. Si c'est le cas (la valeur est jugée constante), c'est immédiatement
exécuté, et un constant le nœud avec la "valeur de retour" du sous-arbre correspondant est
remplacé à la place. Le sous-arbre est supprimé.

Si le pliage constant n’a pas été effectué, le thread d’ordre d’exécution est créé.

Compiler pass 2: aux contextes propagation
Lorsqu'un contexte pour une partie de l'arborescence de compilation est connu, il est propagé à travers le
arbre. A ce moment le contexte peut avoir 5 valeurs (au lieu de 2 pour le contexte d'exécution) :
void, booléen, scalaire, liste et lvalue. Contrairement à la passe 1, cette passe est
traité de haut en bas : le contexte d'un nœud détermine le contexte de ses enfants.

Des optimisations supplémentaires dépendant du contexte sont effectuées à ce stade. Depuis à ce moment
moment où l'arborescence de compilation contient des références arrière (via des pointeurs "thread"), les nœuds ne peuvent pas être
libre()d maintenant. Pour permettre l'optimisation des nœuds à ce stade, ces nœuds sont nul()ifié
au lieu de libre()ing (c'est-à-dire que leur type est changé en OP_NULL).

Compiler pass 3: judas recherche
Après la création de l'arborescence de compilation d'un sous-programme (ou d'un "eval" ou d'un fichier), un
un passage supplémentaire sur le code est effectué. Cette passe n'est ni descendante ni ascendante,
mais dans l'ordre d'exécution (avec des complications supplémentaires pour les conditions).
Les optimisations effectuées à ce stade sont soumises aux mêmes restrictions que lors de la passe
2.

Les optimisations des judas se font en appelant la fonction pointée par la variable globale
"PL_peepp". Par défaut, "PL_peepp" appelle simplement la fonction pointée par le global
variable "PL_rpeepp". Par défaut, cela effectue certaines corrections et optimisations opérationnelles de base
le long de la chaîne opérationnelle d'ordre d'exécution et appelle récursivement "PL_rpeepp" pour chaque chaîne latérale
d'opérations (résultant de conditions). Les extensions peuvent fournir des optimisations supplémentaires ou
corrections, s'accrochant à l'étape par sous-programme ou récursive, comme ceci :

peep_t statique prev_peepp ;
vide statique my_peep (pTHX_ OP *o)
{
/* L'optimisation personnalisée par sous-programme va ici */
prev_peepp(aTHX_o);
/* L'optimisation personnalisée par sous-programme peut également être effectuée ici */
}
BATEAU:
prev_peepp = PL_peepp;
PL_peepp = mon_peep;

peep_t statique prev_rpeepp ;
vide statique my_rpeep(pTHX_ OP *o)
{
OP *orig_o = o;
pour(;o;o = o->op_next) {
/* L'optimisation per-op personnalisée va ici */
}
prev_rpeepp(aTHX_orig_o);
}
BATEAU:
prev_rpeepp = PL_rpeepp;
PL_rpeepp = mon_rpeep;

Enfichable runops
L'arborescence de compilation est exécutée dans une fonction runops. Il existe deux fonctions runops, dans
exécuter.c et dans décharge.c. "Perl_runops_debug" est utilisé avec DEBUGGING et
"Perl_runops_standard" est utilisé autrement. Pour un contrôle fin de l'exécution des
arbre de compilation, il est possible de fournir votre propre fonction runops.

Il est probablement préférable de copier l'une des fonctions runops existantes et de la modifier en fonction de vos besoins.
besoins. Ensuite, dans la section BOOT de votre fichier XS, ajoutez la ligne :

PL_runops = mon_runops ;

Cette fonction doit être aussi efficace que possible pour que vos programmes s'exécutent aussi rapidement que possible.
de qualité.

Temps de compilation portée crochets
Depuis Perl 5.14, il est possible de se connecter au mécanisme de portée lexicale au moment de la compilation en utilisant
"Perl_blockhook_register". Ceci est utilisé comme ceci :

STATIC void my_start_hook(pTHX_int full);
STATIQUE BHK mes_hooks ;

BATEAU:
BhkENTRY_set(&my_hooks, bhk_start, my_start_hook);
Perl_blockhook_register(aTHX_ &mes_hooks);

Cela fera en sorte que "my_start_hook" soit appelé au début de la compilation de chaque lexical.
portée. Les crochets disponibles sont :

"void bhk_start(pTHX_int complet)"
Ceci est appelé juste après le démarrage d'une nouvelle portée lexicale. Notez que le code Perl comme

si ($x) { ... }

crée deux scopes : le premier commence au "(" et a "full == 1", le second commence
au "{" et a "full == 0". Les deux se terminent par le "}", donc les appels à "start" et
"pre/post_end" correspondra. Tout ce qui est poussé sur la pile de sauvegarde par ce hook sera
est apparu juste avant la fin de la portée (entre les hooks "pre_" et "post_end", en fait).

"void bhk_pre_end(pTHX_ OP **o)"
Ceci est appelé à la fin d'une portée lexicale, juste avant de dérouler la pile. o is
la racine de l'optree représentant la portée ; c'est un double pointeur pour que vous puissiez
remplacez l'OP si vous en avez besoin.

"void bhk_post_end(pTHX_OP **o)"
Ceci est appelé à la fin d'une portée lexicale, juste après avoir déroulé la pile. o est tel que
au-dessus de. Notez qu'il est possible que les appels à "pre_" et "post_end" s'imbriquent, s'il y a
est quelque chose sur la pile de sauvegarde qui appelle string eval.

"void bhk_eval(pTHX_OP *const o)"
Ceci est appelé juste avant de commencer à compiler un "eval STRING", "do FILE", "require"
ou "utiliser", une fois l'évaluation configurée. o est le PO qui a demandé l'évaluation, et
sera normalement un "OP_ENTEREVAL", "OP_DOFILE" ou "OP_REQUIRE".

Une fois que vous avez vos fonctions de hook, vous avez besoin d'une structure "BHK" pour les insérer.
pour l'allouer de manière statique, car il n'y a aucun moyen de le libérer une fois enregistré. Le
les pointeurs de fonctions doivent être insérés dans cette structure à l'aide de la macro "BhkENTRY_set",
qui définira également des drapeaux indiquant quelles entrées sont valides. Si vous devez allouer
votre "BHK" dynamiquement pour une raison quelconque, assurez-vous de le remettre à zéro avant de commencer.

Une fois enregistré, il n'existe aucun mécanisme pour désactiver ces hooks, donc si cela est nécessaire
vous devrez le faire vous-même. Une entrée dans "%^H" est probablement la meilleure façon, donc le
l'effet est de portée lexicale ; cependant il est également possible d'utiliser le "BhkDISABLE" et
Macros "BhkENABLE" pour activer et désactiver temporairement les entrées. Vous devez également être conscient
que d'une manière générale, au moins un scope sera ouvert avant que votre extension ne soit
chargé, vous verrez donc des paires "pre/post_end" qui n'avaient pas de "start" correspondant.

Examiner interne données, structures avec le "décharge" fonctions


Pour faciliter le débogage, le fichier source décharge.c contient un certain nombre de fonctions qui produisent
sortie formatée des structures de données internes.

La plus couramment utilisée de ces fonctions est « Perl_sv_dump » ; il est utilisé pour vider les SV,
AV, HV et CV. Le module "Devel::Peek" appelle "sv_dump" pour produire une sortie de débogage
depuis Perl-space, les utilisateurs de ce module devraient donc déjà être familiers avec son format.

"Perl_op_dump" peut être utilisé pour vider une structure "OP" ou l'un de ses dérivés, et
produit une sortie similaire à "perl -Dx" ; en fait, "Perl_dump_eval" videra la racine principale
du code en cours d'évaluation, exactement comme "-Dx".

D'autres fonctions utiles sont "Perl_dump_sub", qui transforme un "GV" en arbre opérationnel,
"Perl_dump_packsubs" qui appelle "Perl_dump_sub" sur tous les sous-programmes d'un package comme
donc : (Heureusement, ce sont tous des xsubs, donc il n'y a pas d'arborescence opérationnelle)

(gdb) imprimer Perl_dump_packsubs(PL_defstash)

Attributs SUB ::bootstrap = (xsub 0x811fedc 0)

SOUS UNIVERSEL ::can = (xsub 0x811f50c 0)

SOUS UNIVERSEL ::isa = (xsub 0x811f304 0)

SOUS UNIVERSEL :: VERSION = (xsub 0x811f7ac 0)

SUB DynaLoader ::boot_DynaLoader = (xsub 0x805b188 0)

et "Perl_dump_all", qui vide tous les sous-programmes de la cachette et de l'arborescence des opérations du
racine principale.

Comment la plusieurs interprètes et concurrence sommes-nous soutenu


Information de Base: et PERL_IMPLICIT_CONTEXT
L'interpréteur Perl peut être considéré comme une boîte fermée : il dispose d'une API pour l'alimenter en code ou
sinon il lui fait faire des choses, mais il a aussi des fonctions pour son propre usage. Cela sent un
ressemble beaucoup à un objet, et il existe des moyens de construire Perl de manière à pouvoir avoir plusieurs
interprètes, avec un interprète représenté soit sous forme de structure C, soit à l'intérieur d'un
structure spécifique au thread. Ces structures contiennent tout le contexte, l'état de celui-ci
interprète.

Une macro contrôle la principale version de Perl : MULTIPLICITÉ. La version MULTIPLICITY a
une structure C qui regroupe tout l’état de l’interpréteur. Avec des Perls compatibles avec la multiplicité,
PERL_IMPLICIT_CONTEXT est également normalement défini et permet la prise en charge de la transmission d'un
Premier argument "caché" qui représente les trois structures de données. LA MULTIPLICITÉ fait
perls multi-thread possibles (avec le modèle de thread ithreads, lié à la macro
USE_ITHREADS.)

Deux autres macros "d'encapsulation" sont PERL_GLOBAL_STRUCT et PERL_GLOBAL_STRUCT_PRIVATE
(ce dernier active le premier, et le premier active la MULTIPLICITÉ.) Le
PERL_GLOBAL_STRUCT fait en sorte que toutes les variables internes de Perl soient encapsulées dans un seul
structure globale, struct perl_vars, accessible en tant que (globals) &PL_Vars ou PL_VarsPtr ou le
fonction Perl_GetVars(). Le PERL_GLOBAL_STRUCT_PRIVATE va encore plus loin, il y a
toujours une seule structure (allouée dans principale() soit depuis le tas, soit depuis la pile) mais il y a
aucun symbole de données globales ne le pointe. Dans les deux cas, la structure globale doit être
initialisé comme la toute première chose dans principale() grâce à Perl_init_global_struct() et
en conséquence, démontez-le après perl_free() grâce à Perl_free_global_struct(), s'il te plait regarde
miniperlmain.c pour les détails d'utilisation. Vous devrez peut-être également utiliser "dVAR" dans votre codage pour
"déclarez les variables globales" lorsque vous les utilisez. dTHX fait ça pour vous
automatiquement.

Pour voir si vous avez des données non constantes, vous pouvez utiliser un "nm" compatible BSD (ou GNU) :

nm libperl.a | grep -v '[TURtr]'

Si cela affiche des symboles "D" ou "d" (ou éventuellement "C" ou "c"), vous disposez de données non constantes.
Les symboles supprimés par "grep" sont les suivants : "Tt" sont texte, ou code, les "Rr" sont lis-
uniquement (const) données, et le "U" est , symboles externes mentionnés.

Le test t/portage/libperl.t effectue ce genre de vérification de l'intégrité des symboles sur "libperl.a".

Pour des raisons de compatibilité ascendante, définir uniquement PERL_GLOBAL_STRUCT ne se cache pas réellement
tous les symboles à l'intérieur d'une grande structure globale : certaines tables virtuelles PerlIO_xxx restent visibles. Le
PERL_GLOBAL_STRUCT_PRIVATE cache alors tout (voir comment le PERLIO_FUNCS_DECL est utilisé).

Tout cela nécessite évidemment un moyen pour que les fonctions internes de Perl soient soit des sous-programmes
prenant une sorte de structure comme premier argument, ou des sous-programmes ne prenant rien comme premier argument.
premier argument. Pour permettre ces deux manières très différentes de construire l'interprète, le
Les sources Perl (comme c'est le cas dans de nombreuses autres situations) font un usage intensif de macros et
conventions de dénomination des sous-programmes.

Premier problème : décider quelles fonctions seront des fonctions API publiques et lesquelles seront
privé. Toutes les fonctions dont le nom commence par "S_" sont privées (pensez "S" pour "secret" ou
"statique"). Toutes les autres fonctions commencent par "Perl_", mais simplement parce qu'une fonction commence
avec "Perl_" ne signifie pas qu'il fait partie de l'API. (Voir « Fonctions internes ».)
la façon la plus simple d'être sûr une fonction qui fait partie de l'API consiste à trouver son entrée dans perlapi. Si
ça existe dans perlapi, ça fait partie de l'API. Si ce n'est pas le cas, et vous pensez que cela devrait l'être
(c'est-à-dire que vous en avez besoin pour votre extension), envoyez un mail via Perlbug expliquant pourquoi vous le pensez
devrait être.

Deuxième problème : il doit y avoir une syntaxe pour que les mêmes déclarations et appels de sous-programmes
peut transmettre une structure comme premier argument, ou ne rien transmettre. Pour résoudre cela, le
les sous-programmes sont nommés et déclarés d'une manière particulière. Voici un début typique d'un
fonction statique utilisée dans les tripes de Perl :

Vide STATIQUE
S_incline(pTHX_ char *s)

STATIC devient "statique" en C, et peut être #défini à rien dans certaines configurations en
l'avenir.

Une fonction publique (c'est-à-dire faisant partie de l'API interne, mais pas nécessairement sanctionnée pour son utilisation
dans les extensions) commence ainsi :

annuler
Perl_sv_setiv(pTHX_ SV* dsv, IV num)

"pTHX_" est l'une des nombreuses macros (dans perl.h) qui masquent les détails du
contexte de l'interprète. THX signifie "thread", "this" ou "thingy", selon le cas.
(Et non, George Lucas n'est pas impliqué. :-) Le premier personnage pourrait être "p" pour un
prototype, 'a' pour aargument, ou 'd' pour ddéclaration, nous avons donc "pTHX", "aTHX" et "dTHX",
et leurs variantes.

Lorsque Perl est construit sans options définissant PERL_IMPLICIT_CONTEXT, il n'y a pas de premier
argument contenant le contexte de l’interprète. Le trait de soulignement final dans la macro pTHX_
indique que le développement de la macro nécessite une virgule après l'argument de contexte car d'autres
les arguments le suivent. Si PERL_IMPLICIT_CONTEXT n'est pas défini, pTHX_ sera ignoré, et
le sous-programme n'est pas prototype pour prendre l'argument supplémentaire. La forme de la macro
sans le trait de soulignement final est utilisé lorsqu'il n'y a pas d'arguments explicites supplémentaires.

Lorsqu'une fonction principale en appelle une autre, elle doit transmettre le contexte. Ceci est normalement caché via
macros. Considérez "sv_setiv". Cela se développe en quelque chose comme ceci :

#ifdef PERL_IMPLICIT_CONTEXT
#define sv_setiv(a,b) Perl_sv_setiv(aTHX_ a, b)
/* impossible de faire ça pour les fonctions vararg, voir ci-dessous */
#else
#define sv_setiv Perl_sv_setiv
#endif

Cela fonctionne bien et signifie que les auteurs XS peuvent écrire avec joie :

sv_setiv(foo, bar);

et le faire fonctionner dans tous les modes avec lesquels Perl aurait pu être compilé.

Cela ne fonctionne pas aussi proprement pour les fonctions varargs, car les macros impliquent que le
le nombre d’arguments est connu à l’avance. Au lieu de cela, nous devons soit les énoncer complètement,
en passant "aTHX_" comme premier argument (le noyau Perl a tendance à le faire avec des fonctions comme
Perl_warner), ou utilisez une version sans contexte.

La version sans contexte de Perl_warner s'appelle Perl_warner_nocontext et ne prend pas en charge
l'argument supplémentaire. Au lieu de cela, il fait du dTHX ; pour obtenir le contexte du stockage local du thread.
Nous "#définissons le warner Perl_warner_nocontext" afin que les extensions obtiennent la compatibilité source à
au détriment de la performance. (Passer un argument coûte moins cher que de le récupérer à partir du thread local
stockage.)

Vous pouvez ignorer [pad]THXx lorsque vous parcourez les en-têtes/sources Perl. Ce sont strictement pour
utiliser dans le noyau. Les extensions et les intégrateurs n'ont besoin que de connaître [pad]THX.

So est ce que nous faisons arrivé à dTHR ?
"dTHR" a été introduit dans Perl 5.005 pour prendre en charge l'ancien modèle de thread. Le fil plus ancien
Le modèle utilise désormais le mécanisme "THX" pour transmettre des pointeurs de contexte, donc "dTHR" n'est pas
plus utile. Perl 5.6.0 et versions ultérieures l'ont toujours pour une compatibilité ascendante avec les sources,
mais il est défini comme étant un non-opération.

Comment la do I utilisé tous ceci. in des rallonges ?
Lorsque Perl est construit avec PERL_IMPLICIT_CONTEXT, les extensions qui appellent des fonctions dans le
L'API Perl devra transmettre l'argument de contexte initial d'une manière ou d'une autre. Le plus intéressant, c'est que tu
devra l'écrire de telle manière que l'extension soit toujours compilée même si Perl ne l'a pas fait.
été construit avec PERL_IMPLICIT_CONTEXT activé.

Il existe trois façons de procéder. Premièrement, la méthode simple mais inefficace, qui est également la
par défaut, afin de maintenir la compatibilité des sources avec les extensions : à chaque fois XSUB.h is
#inclus, il redéfinit les macros aTHX et aTHX_ pour appeler une fonction qui renverra le
contexte. Ainsi, quelque chose comme :

sv_setiv(sv, num);

dans votre extension se traduira par ceci lorsque PERL_IMPLICIT_CONTEXT sera en vigueur :

Perl_sv_setiv(Perl_get_context(), sv, num);

ou à ceci autrement :

Perl_sv_setiv(sv, num);

Vous n'avez rien de nouveau à faire dans votre extension pour obtenir cela ; depuis la bibliothèque Perl
offre aux Perl_get_context(), tout fonctionnera.

La deuxième méthode, plus efficace, consiste à utiliser le modèle suivant pour votre Foo.xs :

#define PERL_NO_GET_CONTEXT /* nous voulons de l'efficacité */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

STATIC void my_private_function(int arg1, int arg2);

Vide STATIQUE
ma_fonction_privée (int arg1, int arg2)
{
dTHX; /* récupérer le contexte */
... appelle de nombreuses fonctions de l'API Perl ...
}

[... etc ...]

MODULE = Foo PAQUET = Foo

/* XSUB typique */

annuler
mon_xsub(arg)
argument entier
CODE:
ma_fonction_privée(arg, 10);

Notez que les deux seuls changements par rapport à la manière normale d'écrire une extension sont l'ajout
d'un "#define PERL_NO_GET_CONTEXT" avant d'inclure les en-têtes Perl, suivi d'un
"dTHX;" déclaration au début de chaque fonction qui appellera l'API Perl. (Vous allez
savoir quelles fonctions en ont besoin, car le compilateur C se plaindra qu'il y a un
identifiant non déclaré dans ces fonctions.) Aucune modification n'est nécessaire pour les XSUB
eux-mêmes, parce que le XS() la macro est correctement définie pour passer dans le contexte implicite si
nécessaire.

La troisième méthode, encore plus efficace, consiste à imiter la façon dont cela se fait dans les tripes de Perl :

#define PERL_NO_GET_CONTEXT /* nous voulons de l'efficacité */
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

/* pTHX_ nécessaire uniquement pour les fonctions qui appellent l'API Perl */
STATIC void my_private_function(pTHX_int arg1, int arg2);

Vide STATIQUE
ma_fonction_privée(pTHX_int arg1, int arg2)
{
/* dTHX; pas nécessaire ici, car THX est un argument */
... appeler les fonctions de l'API Perl ...
}

[... etc ...]

MODULE = Foo PAQUET = Foo

/* XSUB typique */

annuler
mon_xsub(arg)
argument entier
CODE:
ma_fonction_privée(aTHX_arg, 10);

Cette implémentation n'a jamais besoin de récupérer le contexte à l'aide d'un appel de fonction, car elle est
toujours passé comme argument supplémentaire. Selon vos besoins de simplicité ou d'efficacité,
vous pouvez mélanger librement les deux approches précédentes.

N'ajoutez jamais vous-même une virgule après "pTHX". Utilisez toujours la forme de la macro avec le
soulignement pour les fonctions qui prennent des arguments explicites, ou la forme sans l'argument
pour les fonctions sans arguments explicites.

Si l'on compile Perl avec "-DPERL_GLOBAL_STRUCT", la définition "dVAR" est nécessaire
si les variables globales Perl (voir perlvars.h or globvar.sym) sont accessibles dans la fonction
et "dTHX" n'est pas utilisé (le "dTHX" inclut le "dVAR" si nécessaire). On remarque le
besoin de "dVAR" uniquement avec ladite définition au moment de la compilation, car sinon le paramètre global Perl
les variables sont visibles telles quelles.

Si I do quoi que ce soit d'artificiel pour un spécial if I nous appeler perl à partir de plusieurs fils?
Si vous créez des interprètes dans un thread et que vous les appelez ensuite dans un autre, vous
devez vous assurer que le propre emplacement Thread Local Storage (TLS) de Perl est correctement initialisé dans
chacun de ces fils.

Les fonctions API "perl_alloc" et "perl_clone" définiront automatiquement le slot TLS sur le
interprète qu'ils ont créé, de sorte qu'il n'est pas nécessaire de faire quoi que ce soit de spécial si le
l'interpréteur est toujours accessible dans le même thread qui l'a créé, et ce thread ne l'a pas fait
créer ou appeler d'autres interprètes par la suite. Si ce n'est pas le cas, vous devez
définir l'emplacement TLS du thread avant d'appeler des fonctions dans l'API Perl sur celui-ci
interprète particulier. Cela se fait en appelant la macro "PERL_SET_CONTEXT" dans ce
fil comme première chose à faire :

/* fais ceci avant de faire autre chose avec some_perl */
PERL_SET_CONTEXT(un_perl);

... d'autres appels d'API Perl sur some_perl vont ici ...

A venir Tarifs et PERL_IMPLICIT_SYS
Tout comme PERL_IMPLICIT_CONTEXT fournit un moyen de regrouper tout ce que l'interprète
connaît lui-même et le fait circuler, et il est également prévu de permettre à l'interprète de
regroupe tout ce qu'il sait sur l'environnement sur lequel il s'exécute. Ceci est activé avec
la macro PERL_IMPLICIT_SYS. Actuellement, cela ne fonctionne qu'avec USE_ITHREADS sous Windows.

Cela permet de fournir un pointeur supplémentaire (appelé environnement « hôte ») pour
tous les appels système. Cela permet à tous les éléments du système de conserver leur
propre état, décomposé en sept structures C. Ce sont de fines enveloppes autour de l'habituel
appels système (voir win32/perllib.c) pour l'exécutable Perl par défaut, mais pour une version plus
hôte ambitieux (comme celui qui ferait fourchette() émulation) tout le travail supplémentaire nécessaire pour
prétendre que différents interprètes sont en réalité des "processus" différents, serait fait
ici.

Le moteur/interprète Perl et l'hôte sont des entités orthogonales. Il pourrait y en avoir un ou
plusieurs interprètes dans un processus, et un ou plusieurs "hôtes", avec association libre entre
Eux.

Interne Les fonctions


Toutes les fonctions internes de Perl qui seront exposées au monde extérieur sont préfixées
par "Perl_" afin qu'ils n'entrent pas en conflit avec les fonctions XS ou les fonctions utilisées dans un programme
dans lequel Perl est intégré. De même, toutes les variables globales commencent par « PL_ ». (Par
convention, les fonctions statiques commencent par "S_".)

À l'intérieur du noyau Perl ("PERL_CORE" défini), vous pouvez accéder aux fonctions soit avec ou
sans le préfixe "Perl_", grâce à un tas de définitions qui résident dans intégrer.h. Noter que
le code d'extension devrait pas définir "PERL_CORE" ; cela expose tous les composants internes de Perl, et est
susceptible de provoquer une rupture du XS à chaque nouvelle version de Perl.

Le fichier intégrer.h est généré automatiquement à partir de intégrer.pl et intégrer.fnc. intégrer.pl aussi
crée les fichiers d'en-tête de prototypage pour les fonctions internes, génère le
documentation et beaucoup d'autres éléments. Il est important que lorsque vous ajoutez un nouveau
fonction au cœur ou modifier une fonction existante, vous modifiez les données du tableau dans
intégrer.fnc aussi. Voici un exemple d'entrée de cette table :

Apd |SV** |av_fetch |AV* ar|Clé I32|I32 lval

La deuxième colonne est le type de retour, la troisième colonne le nom. Les colonnes suivantes sont
les arguments. La première colonne est un ensemble d'indicateurs :

R Cette fonction fait partie de l'API publique. Toutes ces fonctions devraient également avoir « d »,
très peu ne le font pas.

p Cette fonction a un préfixe « Perl_ » ; c'est-à-dire qu'il est défini comme "Perl_av_fetch".

d Cette fonction dispose d'une documentation utilisant la fonctionnalité "apidoc" que nous examinerons dans un
deuxième. Certaines fonctions ont « d » mais pas « A » ; les documents sont bons.

Les autres drapeaux disponibles sont :

s Il s'agit d'une fonction statique définie comme "STATIC S_whatever", et généralement appelée
dans les sources comme "peu importe (...)".

n Cela n'a pas besoin d'un contexte d'interprétation, donc la définition n'a pas de "pTHX", et elle
il s'ensuit que les appelants n'utilisent pas "aTHX". (Voir "Arrière-plan et PERL_IMPLICIT_CONTEXT".)

r Cette fonction ne renvoie jamais ; "croak", "sortie" et amis.

f Cette fonction prend un nombre variable d'arguments, style "printf". La liste des arguments
devrait se terminer par "...", comme ceci :

Afprd |void |croak |const char* pat|...

M Cette fonction fait partie de l'API de développement expérimental, et est susceptible de changer ou de disparaître
sans préavis.

o Cette fonction ne doit pas avoir de macro de compatibilité pour définir, par exemple, "Perl_parse" pour
"analyser". Il doit être appelé "Perl_parse".

x Cette fonction n'est pas exportée hors du noyau Perl.

m Ceci est implémenté sous forme de macro.

X Cette fonction est explicitement exportée.

E Cette fonction est visible pour les extensions incluses dans le noyau Perl.

b Compatibilité descendante binaire ; cette fonction est une macro mais possède aussi un "Perl_"
mise en œuvre (qui est exportée).

autres
Voir les commentaires en haut de "embed.fnc" pour les autres.

Si vous modifiez intégrer.pl or intégrer.fnc, vous devrez exécuter "make regen_headers" pour forcer un
reconstruction de intégrer.h et d'autres fichiers générés automatiquement.

formaté Impression of IV, les UV, et NV
Si vous imprimez des IV, UV ou NVS au lieu du stdio(3) les codes de formatage de style comme
%d, %ld, %f, vous devez utiliser les macros suivantes pour la portabilité

IVdf IV en décimal
UVuf UV en décimal
UVd'UV en octal
UVxf UV en hexadécimal
NVef NV %e-like
NVff NV %f-like
NVgf NV %g-like

Ceux-ci prendront en charge les entiers 64 bits et les doubles longs. Par exemple:

printf("IV est %"IVdf"\n", iv);

L'IVdf s'étendra au format correct pour les IV.

Notez qu'il existe différents "doubles longs" : Perl utilisera tout ce que le compilateur possède.

Si vous imprimez des adresses de pointeurs, utilisez UVxf combiné avec PTR2UV(), n'utilisez pas %lx
ou %p.

Pointeur vers un entier et Entier vers pointeur
Étant donné que la taille du pointeur n'est pas nécessairement égale à la taille d'un entier, utilisez les macros suivantes pour effectuer cette opération :
c'est juste.

PTR2UV (pointeur)
PTR2IV(pointeur)
PTR2NV (pointeur)
INT2PTR(pointertotype, entier)

Par exemple :

IViv = ... ;
SV *sv = INT2PTR(SV*,iv);

et

AV *av = ...;
UVuv = PTR2UV(moy);

Exception Maniabilité
Il existe quelques macros pour effectuer une gestion très basique des exceptions dans les modules XS. Tu as
définir "NO_XSLOCKS" avant d'inclure XSUB.h pour pouvoir utiliser ces macros :

#définir NO_XSLOCKS
#include "XSUB.h"

Vous pouvez utiliser ces macros si vous appelez du code susceptible de croasser, mais vous devez effectuer un nettoyage.
avant de redonner le contrôle à Perl. Par exemple:

dXCPT ; /* configure les variables nécessaires */

XCPT_TRY_START {
code_that_may_croak();
} XCPT_TRY_END

XCPT_CATCH
{
/* fais le nettoyage ici */
XCPT_RETHROW ;
}

Notez que vous devez toujours relancer une exception qui a été interceptée. En utilisant ces
macros, il n'est pas possible de simplement intercepter l'exception et de l'ignorer. Si tu dois
ignorez l'exception, vous devez utiliser la fonction "call_*".

L'avantage d'utiliser les macros ci-dessus est que vous n'avez pas besoin de configurer une fonction supplémentaire.
pour "call_*", et que l'utilisation de ces macros est plus rapide que l'utilisation de "call_*".

Source Documentation
Un effort est en cours pour documenter les fonctions internes et produire automatiquement
manuels de référence d'eux - perlapi est l'un de ces manuels qui détaille toutes les fonctions
qui sont disponibles pour les écrivains XS. perlintern est le manuel généré automatiquement pour le
des fonctions qui ne font pas partie de l'API et sont censées être destinées à un usage interne uniquement.

La documentation source est créée en insérant des commentaires POD dans la source C, comme ceci :

/*
=pour apidoc sv_setiv

Copie un entier dans le SV donné. Ne gère pas la magie « définie ». Voir
C .

=couper
*/

Veuillez essayer de fournir de la documentation si vous ajoutez des fonctions au noyau Perl.

En arrière compatibilité
L'API Perl évolue avec le temps. De nouvelles fonctions sont ajoutées ou les interfaces des existantes
les fonctions sont modifiées. Le module "Devel::PPPort" tente de fournir un code de compatibilité pour
certains de ces changements, afin que les rédacteurs XS n'aient pas à le coder eux-mêmes lors de la prise en charge
plusieurs versions de Perl.

"Devel::PPPort" génère un fichier d'en-tête C pport.h qui peut également être exécuté en tant que script Perl.
Générer pport.h, courir:

perl -MDevel :: PPPort -eDevel :: PPPort :: WriteFile

En plus de vérifier le code XS existant, le script peut également être utilisé pour récupérer la compatibilité
informations pour divers appels d'API à l'aide du commutateur de ligne de commande "--api-info". Pour
Exemple:

% perl ppport.h --api-info=sv_magicext

Pour plus de détails, voir « perldoc ppport.h ».

Unicode Assistance


Perl 5.6.0 a introduit la prise en charge d'Unicode. Il est important que les porteurs et les rédacteurs XS
comprendre ce support et assurez-vous que le code qu'ils écrivent ne corrompt pas Unicode
revendre.

Organisateur Ce que is unicode, de toute façon?
Dans les temps anciens, moins éclairés, nous utilisions tous l’ASCII. De toute façon, la plupart d’entre nous l’ont fait.
Le gros problème avec l'ASCII, c'est qu'il est américain. Eh bien non, ce n'est pas vraiment le
problème; le problème est que ce n'est pas particulièrement utile pour les personnes qui n'utilisent pas le
Alphabet romain. Ce qui se passait autrefois, c'était que certaines langues restaient les leurs
alphabet dans la plage supérieure de la séquence, entre 128 et 255. Bien entendu, nous
s'est retrouvé avec de nombreuses variantes qui n'étaient pas tout à fait ASCII, et tout l'intérêt de cela était
une norme a été perdue.

Pire encore, si vous avez une langue comme le chinois ou le japonais qui en compte des centaines ou
des milliers de caractères, alors vous ne pouvez vraiment pas les intégrer dans seulement 256, ils ont donc dû
oubliez complètement l'ASCII et construisez leurs propres systèmes en utilisant des paires de nombres pour faire référence
à un personnage.

Pour résoudre ce problème, certaines personnes ont créé Unicode, Inc. et ont produit un nouveau jeu de caractères contenant
tous les personnages auxquels vous pouvez penser et plus encore. Il existe plusieurs manières de
représentant ces caractères, et celui utilisé par Perl s'appelle UTF-8. UTF-8 utilise un
nombre variable d'octets pour représenter un caractère. Vous pouvez en savoir plus sur Unicode et
Le modèle Unicode de Perl en perlunicode.

(Sur les plateformes EBCDIC, Perl utilise à la place UTF-EBCDIC, qui est une forme d'UTF-8 adaptée pour
Plateformes EBCDIC. Ci-dessous, nous parlons simplement d'UTF-8. UTF-EBCDIC est comme UTF-8, mais le
les détails sont différents. Les macros vous cachent les différences, rappelez-vous simplement que le
les nombres particuliers et les modèles de bits présentés ci-dessous différeront en UTF-EBCDIC.)

Comment la Vous pouvez I reconnaître a UTF-8 chaîne?
Vous ne pouvez pas. En effet, les données UTF-8 sont stockées en octets, tout comme les données non UTF-8. Le
Le caractère Unicode 200, (0xC8 pour vos types hexadécimaux) E majuscule avec un accent grave, est
représenté par les deux octets "v196.172". Malheureusement, la chaîne non Unicode
"chr (196).chr(172)" a également cette séquence d'octets. Vous ne pouvez donc pas le savoir simplement en regardant --
c'est ce qui fait de la saisie Unicode un problème intéressant.

En général, soit vous devez savoir à quoi vous avez affaire, soit vous devez deviner. Le
La fonction API « is_utf8_string » peut vous aider ; il vous dira si une chaîne ne contient que des données valides
Caractères UTF-8, et les chances qu'une chaîne non UTF-8 ressemble à un UTF-8 valide deviennent
très petit très rapidement avec l'augmentation de la longueur des cordes. Personnage par personnage,
"isUTF8_CHAR" vous dira si le caractère actuel dans une chaîne est UTF-8 valide.

Comment la ne UTF-8 représentent Unicode personnages?
Comme mentionné ci-dessus, UTF-8 utilise un nombre variable d'octets pour stocker un caractère.
Les caractères avec les valeurs 0...127 sont stockés sur un octet, tout comme le bon vieux ASCII.
Le caractère 128 est stocké sous le nom « v194.128 » ; cela continue jusqu'au caractère 191, qui est
"v194.191". Maintenant, nous n'avons plus de bits (191 est le binaire 10111111), donc nous passons à autre chose ; personnage
192 est "v195.128". Et ainsi de suite, passant à trois octets au caractère 2048. "Unicode
Les encodages" dans perlunicode contiennent des images de la façon dont cela fonctionne.

En supposant que vous savez que vous avez affaire à une chaîne UTF-8, vous pouvez savoir combien de temps dure la première chaîne.
le caractère qu'il contient est avec la macro "UTF8SKIP":

char *utf = "\305\233\340\240\201";
lentille I32 ;

len = UTF8SKIP(utf); /* len vaut 2 ici */
utf += len;
len = UTF8SKIP(utf); /* len vaut 3 ici */

Une autre façon de sauter des caractères dans une chaîne UTF-8 consiste à utiliser "utf8_hop", qui prend un
chaîne et un certain nombre de caractères à ignorer. Vous êtes seul pour vérifier les limites,
cependant, alors ne l’utilisez pas à la légère.

Tous les octets d'un caractère UTF-8 multi-octets auront le bit haut défini, vous pouvez donc tester si
vous devez faire quelque chose de spécial avec ce caractère comme celui-ci (le "UTF8_IS_INVARIANT()"
est une macro qui teste si l'octet est codé comme un seul octet même en UTF-8) :

U8 *utf;
U8 *utf_end; /* 1 au-delà du tampon pointé par utf */
UVUV; /* Remarque : un UV, pas un U8, pas un char */
STRLEN len; /* longueur du caractère en octets */

si (!UTF8_IS_INVARIANT(*utf))
/* Doit traiter cela comme UTF-8 */
uv = utf8_to_uvchr_buf(utf, utf_end, &len);
d'autre
/* OK pour traiter ce caractère comme un octet */
uv = *utf;

Vous pouvez également voir dans cet exemple que nous utilisons "utf8_to_uvchr_buf" pour obtenir la valeur du
personnage; la fonction inverse "uvchr_to_utf8" est disponible pour mettre un UV en UTF-8 :

si (!UVCHR_IS_INVARIANT(uv))
/* Doit traiter ceci comme UTF8 */
utf8 = uvchr_to_utf8(utf8, uv);
d'autre
/* OK pour traiter ce caractère comme un octet */
*utf8++ = uv;

Vous doit convertissez les caractères en UV en utilisant les fonctions ci-dessus si jamais vous êtes dans une situation
où vous devez faire correspondre les caractères UTF-8 et non UTF-8. Vous ne pouvez pas ignorer UTF-8
caractères dans ce cas. Si vous faites cela, vous perdrez la capacité de faire correspondre le hi-bit
caractères non UTF-8 ; par exemple, si votre chaîne UTF-8 contient "v196.172" et que vous ignorez
ce personnage, vous ne pourrez jamais correspondre à un "chr(200)" dans une chaîne non UTF-8. Alors ne faites pas ça !

(Notez que nous n'avons pas besoin de tester les caractères invariants dans les exemples ci-dessus. Le
les fonctions fonctionnent sur n’importe quelle entrée UTF-8 bien formée. C'est juste que c'est plus rapide d'éviter le
surcharge de fonction lorsqu'elle n'est pas nécessaire.)

Comment la ne Perl Boutique UTF-8 des cordes ?
Actuellement, Perl traite les chaînes UTF-8 et les chaînes non UTF-8 de manière légèrement différente. UN
L'indicateur dans le SV, "SVf_UTF8", indique que la chaîne est codée en interne en UTF-8.
Sans cela, la valeur de l'octet est le numéro du point de code et vice versa. Ce drapeau est seulement
significatif si le SV est "SvPOK" ou immédiatement après la stringification via "SvPV" ou un
macro similaire. Vous pouvez vérifier et manipuler cet indicateur avec les macros suivantes :

SvUTF8(sv)
SvUTF8_on(sv)
SvUTF8_off(sv)

Cet indicateur a un effet important sur le traitement de la chaîne par Perl : si les données UTF-8 ne sont pas
correctement distingués, expressions régulières, "longueur", "substr" et autres manipulations de chaînes
les opérations auront des résultats indésirables (mauvais).

Le problème survient lorsque vous avez, par exemple, une chaîne qui n'est pas marquée comme UTF-8 et que
contient une séquence d'octets qui pourrait être UTF-8 -- en particulier lors de la combinaison de non-UTF-8 et
Chaînes UTF-8.

N'oubliez jamais que l'indicateur "SVf_UTF8" est distinct de la valeur PV ; tu dois être sûr
vous ne le faites pas tomber accidentellement pendant que vous manipulez des SV. Plus précisément, vous
Je ne peux pas m'attendre à faire ça :

SV *sv;
SV *nsv;
STRLEN len;
char *p;

p = SvPV(sv, len);
frobniquer(p);
nsv = nouveauSVpvn(p, len);

La chaîne "char*" ne vous raconte pas toute l'histoire et vous ne pouvez pas copier ou reconstruire un
SV simplement en copiant la valeur de la chaîne. Vérifiez si l'ancien SV a l'indicateur UTF8 défini (après le
Appel "SvPV") et agissez en conséquence :

p = SvPV(sv, len);
is_utf8 = SvUTF8(sv);
frobnicate(p, is_utf8);
nsv = nouveauSVpvn(p, len);
si (is_utf8)
SvUTF8_on(nsv);

Dans ce qui précède, votre fonction "frobnicate" a été modifiée pour savoir si ou
il ne s'agit pas non plus de données UTF-8, afin de pouvoir gérer la chaîne de manière appropriée.

Puisqu'il ne suffit pas de passer un SV à une fonction XS et de copier les données du SV pour
copiez les drapeaux UTF8, encore moins le droit consiste simplement à passer un "char *" à une fonction XS.

Pour une généralité complète, utilisez le "DO_UTF8" dans la macro Perlapi pour voir si la chaîne d'un SV est
être traités comme UTF-8. Ceci prend en compte si l'appel à la fonction XS est en cours
effectué dans le cadre de "utiliser les octets". Si tel est le cas, les octets sous-jacents qui composent le
Les chaînes UTF-8 doivent être exposées, plutôt que le caractère qu'elles représentent. Mais ce pragma
ne devrait vraiment être utilisé que pour le débogage et peut-être pour les tests de bas niveau au niveau des octets.
Par conséquent, la plupart du code XS n'a pas besoin de s'occuper de cela, mais de diverses zones du noyau Perl.
il faut le soutenir.

Et ce n'est pas toute l'histoire. À partir de Perl v5.12, les chaînes qui ne sont pas codées dans
UTF-8 peut également être traité comme Unicode dans diverses conditions (voir « Règles ASCII versus
Règles Unicode" en perlunicode). Ce n'est vraiment un problème que pour les caractères dont
les ordinaux sont compris entre 128 et 255, et leur comportement varie sous ASCII par rapport à Unicode
règles d'une manière qui intéresse votre code (voir "Le "Bogue Unicode"" dans perlunicode). Là
Il n'y a pas d'API publiée pour gérer cela, car elle est susceptible de changer, mais vous pouvez consulter
le code pour "pp_lc" dans pp.c pour un exemple de la façon dont cela se fait actuellement.

Comment la do I convertir a string à UTF-8 ?
Si vous mélangez des chaînes UTF-8 et non-UTF-8, il est nécessaire de mettre à niveau les chaînes non-UTF-8.
chaînes en UTF-8. Si vous possédez un SV, le moyen le plus simple de procéder est :

sv_utf8_upgrade(sv);

Cependant, vous ne devez pas faire cela, par exemple :

si (!SvUTF8(gauche))
sv_utf8_upgrade(gauche);

Si vous faites cela dans un opérateur binaire, vous modifierez en fait l'une des chaînes fournies
dans l'opérateur et, même si cela ne devrait pas être perceptible par l'utilisateur final, cela peut provoquer
problèmes de code déficient.

Au lieu de cela, "bytes_to_utf8" vous donnera un fichier codé en UTF-8 copier de son argument de chaîne. Ce
est utile pour disposer des données à des fins de comparaison, etc., sans nuire à la
SV d'origine. Il y a aussi "utf8_to_bytes" pour aller dans l'autre sens, mais naturellement, cela
échoue si la chaîne contient des caractères supérieurs à 255 qui ne peuvent pas être représentés dans un seul
octet.

Comment la do I comparer des cordes ?
"sv_cmp" en perlapi et "sv_cmp_flags" en perlapi font une comparaison lexigraphique de deux SV,
et gérer correctement l'UTF-8. Notez cependant qu'Unicode spécifie un format beaucoup plus sophistiqué.
mécanisme de classement, disponible via le module Unicode::Collate.

Pour comparer simplement deux chaînes d'égalité/non-égalité, vous pouvez simplement utiliser "memEQ()" et
"memNE()" comme d'habitude, sauf que les chaînes doivent être codées en UTF-8 ou non.

Pour comparer deux chaînes sans tenir compte de la casse, utilisez "foldEQ_utf8()" (les chaînes ne doivent pas nécessairement
ont le même caractère UTF-8).

Is quoi que ce soit d'artificiel d'autre I need à connaître?
Pas vraiment. N'oubliez pas ces choses :

· Il n'y a aucun moyen de savoir si une chaîne "char *" ou "U8 *" est UTF-8 ou non. Mais tu peux
indiquer si un SV doit être traité comme UTF-8 en appelant "DO_UTF8" dessus, après avoir chaîne
avec "SvPV" ou une macro similaire. Et vous pouvez savoir si SV est réellement UTF-8 (même si
il ne doit pas être traité comme tel) en regardant son drapeau "SvUTF8" (encore une fois après
en le stringant). N'oubliez pas de définir le drapeau si quelque chose doit être UTF-8. Traiter
le drapeau dans le cadre du PV, même si ce n'est pas le cas -- si vous transmettez le PV quelque part,
transmettez également le drapeau.

· Si une chaîne est UTF-8, toujours utilisez "utf8_to_uvchr_buf" pour obtenir la valeur, sauf si
"UTF8_IS_INVARIANT(*s)", auquel cas vous pouvez utiliser *s.

· Lors de l'écriture d'un caractère UV dans une chaîne UTF-8, toujours utilisez "uvchr_to_utf8", sauf si
"UVCHR_IS_INVARIANT(uv))" auquel cas vous pouvez utiliser "*s = uv".

· Le mélange de chaînes UTF-8 et non UTF-8 est délicat. Utilisez "bytes_to_utf8" pour obtenir une nouvelle chaîne
qui est codé en UTF-8, puis combinez-les.

Personnalisé Les opérateurs


La prise en charge des opérateurs personnalisés est une fonctionnalité expérimentale qui vous permet de définir vos propres opérations.
Il s'agit principalement de permettre la construction d'interprètes pour d'autres langages dans le langage Perl.
noyau, mais il permet également des optimisations via la création de "macro-ops" (des opérations qui
exécuter les fonctions de plusieurs opérations qui sont généralement exécutées ensemble, telles que "gvsv,
gvsv, ajouter".)

Cette fonctionnalité est implémentée en tant que nouveau type d'opération, "OP_CUSTOM". Le noyau Perl ne "sait" pas
quelque chose de spécial à propos de ce type d'opération, et il ne sera donc impliqué dans aucune optimisation.
Cela signifie également que vous pouvez définir vos opérations personnalisées comme n'importe quelle structure opérationnelle : unaire,
binaire, liste et ainsi de suite – vous aimez.

Il est important de savoir ce que les opérateurs personnalisés ne feront pas pour vous. Ils ne vous laisseront pas ajouter de nouveaux
syntaxe à Perl, directement. Ils ne vous permettront même pas d’ajouter directement de nouveaux mots-clés. En fait,
ils ne changeront pas du tout la façon dont Perl compile un programme. Vous devez faire ces changements
vous-même, une fois que Perl a compilé le programme. Vous faites cela soit en manipulant l'opération
arborescence en utilisant un bloc "CHECK" et le module "B::Generate", ou en ajoutant un judas personnalisé
optimiseur avec le module "optimiser".

Lorsque vous faites cela, vous remplacez les opérations Perl ordinaires par des opérations personnalisées en créant des opérations avec le
tapez "OP_CUSTOM" et le "op_ppaddr" de votre propre fonction PP. Cela devrait être défini dans
Code XS, et devrait ressembler aux opérations PP dans "pp_*.c". Vous êtes responsable d'assurer
que votre opération prend le nombre approprié de valeurs de la pile, et vous êtes
responsable d’ajouter des marques de pile si nécessaire.

Vous devez également "enregistrer" votre opération auprès de l'interpréteur Perl afin qu'elle puisse produire
messages d'erreur et d'avertissement sensés. Puisqu'il est possible d'avoir plusieurs opérations personnalisées
dans le type d'opération "logique" "OP_CUSTOM", Perl utilise la valeur de "o->op_ppaddr" pour
déterminer à quelle opération personnalisée il s'agit. Vous devez créer une structure "XOP" pour
chaque ppaddr que vous utilisez, définissez les propriétés de l'opération personnalisée avec "XopENTRY_set" et enregistrez-vous
la structure par rapport au ppaddr en utilisant "Perl_custom_op_register". Un exemple trivial pourrait
ressembler:

XOP statique mon_xop ;
OP statique *my_pp(pTHX);

BATEAU:
XopENTRY_set(&my_xop, xop_name, "myxop");
XopENTRY_set(&my_xop, xop_desc, "Opération personnalisée inutile");
Perl_custom_op_register(aTHX_ mon_pp, &mon_xop);

Les champs disponibles dans la structure sont :

nom_xop
Un nom court pour votre opération. Ceci sera inclus dans certains messages d'erreur et sera également
être renvoyé sous la forme "$op->name" par le module B, il apparaîtra donc dans la sortie du module
comme B :: Concis.

xop_desc
Une brève description de la fonction de l'op.

xop_class
Laquelle des différentes structures *OP cette opération utilise. Cela devrait être l'un des "OA_*"
constantes de op.h, à savoir

OA_BASEOP
OA_UNOP
OA_BINOP
OA_LOGOP
OA_LISTOP
OA_PMOP
OA_SVOP
OA_PADOP
OA_PVOP_OR_SVOP
Cela doit être interprété comme « PVOP » uniquement. Le "_OR_SVOP" est dû au fait que le seul
le noyau "PVOP", "OP_TRANS", peut parfois être un "SVOP" à la place.

OA_LOOP
OA_COP

Les autres constantes "OA_*" ne doivent pas être utilisées.

xop_peep
Ce membre est de type "Perl_cpeep_t", qui se développe en "void (*Perl_cpeep_t)(aTHX_ OP
*o, OP *oldop)". Si elle est définie, cette fonction sera appelée depuis "Perl_rpeep" lorsque
des opérations de ce type sont rencontrées par l’optimiseur de judas. o est le PO qui a besoin
optimisation ; vieux est l'OP précédent optimisé, dont "op_next" pointe vers o.

"B::Generate" prend directement en charge la création d'opérations personnalisées par nom.

AUTEURS


Jusqu'en mai 1997, ce document était conservé par Jeff Okamoto[email protected]>. Il est
maintenant maintenu dans le cadre de Perl lui-même par les Perl 5 Porters[email protected]>.

Avec beaucoup d'aide et de suggestions de Dean Roehrich, Malcolm Beattie, Andreas Koenig,
Paul Hudson, Ilya Zakharevitch, Paul Marquess, Neil Bowers, Matthew Green, Tim Bunce,
Spider Boardman, Ulrich Pfeifer, Stephen McCamant et Gurusamy Sarathy.

Utilisez Perlguts en ligne en utilisant les services onworks.net


Serveurs et postes de travail gratuits

Télécharger des applications Windows et Linux

Commandes Linux

Ad




×
Publicité
❤ ️Achetez, réservez ou achetez ici — gratuitement, contribue à maintenir la gratuité des services.