PERLAPI(1perl)

๐Ÿ“ฆ
version 5.44.0 ยท 2 versions
, in arch rolling

PERLAPI(1perl) ๐Ÿ’–

Perl Programmers Reference Guide

okay bestie, welcome to perlapi ๐Ÿ’… this is the autogenerated documentation for the perl public API, and yes we're doing the whole thing.

โœจ NAME โœจ

perlapi โ€” autogenerated documentation for the perl public API.

๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

Okay so this file contains most of the documentation of the perl public API, as generated by embed.pl. Specifically, it's a listing of functions, macros, flags, and variables that may be used by extension writers. Besides perlintern and config.h, some items are listed here as being actually documented in another pod.

At the end is a list of functions which have yet to be documented. Patches welcome! The interfaces of these are subject to change without notice.

To find out what release an element came into being, use:

perl dist/ppport.h --api-info=element

You may also use a pattern:

perl dist/ppport.h --api-info=/./

That displays all possible public api elements, but not items in perlintern. Some elements have been backported in Devel::PPPort so that they are usable in earlier versions than they otherwise would be available. The display also includes information as to what the earliest possible version such an element may be used in; as well as some hints and cautions.

Some of the functions documented here are consolidated so that a single entry serves for multiple functions which all do basically the same thing, but have some slight differences. For example, one form might process magic, while another doesn't. The name of each variation is listed at the top of the single entry.

The names of all API functions begin with the prefix Perl_ so as to prevent any name collisions with your code. But, unless -Accflags=-DPERL_NO_SHORT_NAMES has been specified in compiling your code (see Hiding Perl_ in perlembed), synonymous macros are also available to you that don't have this prefix, and also hide from you the need (or not) to have a thread context parameter passed to the function. Generally, code is easier to write and to read when the short form is used, so in practice that compilation flag is not used. Not all functions have the short form; both are listed here when available.

Anything not listed here or in the other mentioned pods is not part of the public API, and should not be used by extension writers at all. For these reasons, blindly using functions listed in proto.h is to be avoided when writing extensions.

In Perl, unlike C, a string of characters may generally contain embedded NUL characters. Sometimes in the documentation a Perl string is referred to as a "buffer" to distinguish it from a C string, but sometimes they are both just referred to as strings.

Note that all Perl API global variables must be referenced with the PL_ prefix. Again, those not listed here are not to be used by extension writers, and may be changed or removed without notice; same with macros. Some macros are provided for compatibility with the older, unadorned names, but this support may be disabled in a future release.

Perl was originally written to handle US-ASCII only (that is characters whose ordinal numbers are in the range 0 - 127). And documentation and comments may still use the term ASCII, when sometimes in fact the entire range from 0 - 255 is meant.

The non-ASCII characters below 256 can have various meanings, depending on various things. (See, most notably, perllocale.) But usually the whole range can be referred to as ISO-8859-1. Often, the term "Latin-1" (or "Latin1") is used as an equivalent for ISO-8859-1. But some people treat "Latin1" as referring just to the characters in the range 128 through 255, or sometimes from 160 through 255. This documentation uses "Latin1" and "Latin-1" to refer to all 256 characters.

Note that Perl can be compiled and run under either ASCII or EBCDIC (See perlebcdic). Most of the documentation (and even comments in the code) ignore the EBCDIC possibility. For almost all purposes the differences are transparent. As an example, under EBCDIC, instead of UTF-8, UTF-EBCDIC is used to encode Unicode strings, and so whenever this documentation refers to "utf8" (and variants of that name, including in function names), it also (essentially transparently) means "UTF-EBCDIC". But the ordinals of characters differ between ASCII, EBCDIC, and the UTF- encodings, and a string encoded in UTF-EBCDIC may occupy a different number of bytes than in UTF-8.

The organization of this document is tentative and subject to change. Suggestions and patches welcome perl5-porters@perl.org <mailto:perl5-porters@perl.org>.

The API elements are grouped by functionality into sections, as follows. Within sections the elements are ordered alphabetically, ignoring case, with non-leading underscores sorted first, and leading underscores and digits sorted last.

  • AV Handling
  • Callback Functions
  • Casting
  • Character case changing
  • Character classification
  • Compiler and Preprocessor information
  • Compiler directives
  • Compile-time scope hooks
  • Concurrency
  • COPs and Hint Hashes
  • Custom Operators
  • CV Handling
  • Debugging
  • Declaration and Initialization of Globals
  • Display functions
  • Embedding, Threads, and Interpreter Cloning
  • Errno
  • Exception Handling (simple) Macros
  • Filesystem configuration values
  • Floating point
  • General Configuration
  • Global Variables
  • GV Handling and Stashes
  • Hook manipulation
  • HV Handling
  • Input/Output
  • Integer
  • I/O Formats
  • Lexer interface
  • Locales
  • Magic
  • Memory Management
  • MRO
  • Multicall Functions
  • Numeric Functions
  • Optrees
  • Pack and Unpack
  • Pad Data Structures
  • Password and Group access
  • Paths to system commands
  • Prototype information
  • Reference-counted stack manipulation
  • REGEXP Functions
  • Reports and Formats
  • Signals
  • Site configuration
  • Sockets configuration values
  • Source Filters
  • Stack Manipulation Macros
  • String Handling
  • SV Flags
  • SV Handling
  • Tainting
  • Time
  • Typedef names
  • Unicode Support
  • Utility Functions
  • Versioning
  • Warning and Dieing
  • XS
  • Undocumented elements

The listing below is alphabetical, case insensitive.

๐Ÿฆ‹ AV Handling ๐Ÿฆ‹

AV

Described in perlguts.

av_clear

Frees all the elements of an array, leaving it empty. The XS equivalent of @array = (). See also av_undef.

Note that it is possible that the actions of a destructor called directly or indirectly by freeing an element of the array could cause the reference count of the array itself to be reduced (e.g. by deleting an entry in the symbol table). So it is a possibility that the AV could have been freed (or even reallocated) on return from the call unless you hold a reference to it.
            void       av_clear(      AV *av)
            void  Perl_av_clear(pTHX_ AV *av)

av_count

Returns the number of elements in the array av. This is the true length of the array, including any undefined elements. It is always the same as av_top_index(av) + 1.

            Size_t       av_count(      AV *av)
            Size_t  Perl_av_count(pTHX_ AV *av)

av_create_and_push

Push an SV onto the end of the array, creating the array if necessary. A small internal helper function to remove a commonly duplicated idiom.

            void  Perl_av_create_and_push(pTHX_ AV ** const avp,
                                                SV * const val)

av_create_and_unshift_one

Unshifts an SV onto the beginning of the array, creating the array if necessary. A small internal helper function to remove a commonly duplicated idiom.

            SV **  Perl_av_create_and_unshift_one(pTHX_ AV ** const avp,
                                                        SV * const val)

av_delete

Deletes the element indexed by key from the array, makes the element mortal, and returns it. If flags equals G_DISCARD, the element is freed and NULL is returned. NULL is also returned if key is out of range.

Perl equivalent: splice(@myarray, $key, 1, undef) (with the splice in void context if G_DISCARD is present).

            SV *       av_delete(      AV *av, SSize_t key, I32 flags)
            SV *  Perl_av_delete(pTHX_ AV *av, SSize_t key, I32 flags)

av_exists

Returns true if the element indexed by key has been initialized.

This relies on the fact that uninitialized array elements are set to NULL.

Perl equivalent: exists($myarray[$key]).

            bool       av_exists(      AV *av, SSize_t key)
            bool  Perl_av_exists(pTHX_ AV *av, SSize_t key)

av_extend

Pre-extend an array so that it is capable of storing values at indexes 0..key. Thus av_extend(av,99) guarantees that the array can store 100 elements, i.e. that av_store(av, 0, sv) through av_store(av, 99, sv) on a plain array will work without any further memory allocation.

If the av argument is a tied array then will call the EXTEND tied array method with an argument of (key+1).

            void       av_extend(      AV *av, SSize_t key)
            void  Perl_av_extend(pTHX_ AV *av, SSize_t key)

av_fetch

Returns the SV at the specified index in the array. The key is the index. If lval is true, you are guaranteed to get a real SV back (in case it wasn't real before), which you can then modify. Check that the return value is non-NULL before dereferencing it to a SV*.

See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more information on how to use this function on tied arrays.

The rough perl equivalent is $myarray[$key].

            SV **       av_fetch(      AV *av, SSize_t key, I32 lval)
            SV **  Perl_av_fetch(pTHX_ AV *av, SSize_t key, I32 lval)

av_fill

Set the highest index in the array to the given number, equivalent to Perl's $#array = $fill;.

The number of elements in the array will be fill + 1 after av_fill() returns. If the array was previously shorter, then the additional elements appended are set to NULL. If the array was longer, then the excess elements are freed. av_fill(av, -1) is the same as av_clear(av).

            void       av_fill(      AV *av, SSize_t fill)
            void  Perl_av_fill(pTHX_ AV *av, SSize_t fill)

av_len*

Described under av_top_index.

av_make

Creates a new AV and populates it with a list (**strp, length size) of SVs. A copy is made of each SV, so their refcounts are not changed. The new AV will have a reference count of 1.

Perl equivalent: my @new_array = ($scalar1, $scalar2, $scalar3...);

and here's the declaration block for that one, bestie:

AV *       av_make(      SSize_t size, SV **strp)
AV *  Perl_av_make(pTHX_ SSize_t size, SV **strp)

โœจ av_pop โœจ

Yoinks one SV off the end of the array ๐Ÿ“, shrinks the array by one, and hands that SV back to you โ€” plus control of one reference count, which is now yours. If the array is empty? You get &PL_sv_undef. no notes.

Perl equivalent vibe: pop(@myarray);

SV *       av_pop(      AV *av)
SV *  Perl_av_pop(pTHX_ AV *av)

๐Ÿ’– av_push / av_push_simple ๐Ÿ’–

Both of these push an SV onto the end of the array (transferring control of one reference count ๐Ÿ’…), and the array grows itself to accommodate the addition.

Perl equivalent: push @myarray, $val;.

av_push is the general-purpose main character โ€” suitable for all situations, no cap.

av_push_simple is the cut-down version that assumes the array is extremely straightforward: no magic, not readonly, and it's AvREAL (go peep "Real AVs - and those that are not" in perlguts), and that key is not less than -1. This function MUST NOT be used in situations where any of those assumptions may not hold. like, fr fr, don't.

void       av_push       (      AV *av, SV *val)
void  Perl_av_push       (pTHX_ AV *av, SV *val)
void       av_push_simple(      AV *av, SV *val)
void  Perl_av_push_simple(pTHX_ AV *av, SV *val)

๐ŸŒธ av_shift ๐ŸŒธ

Removes one SV from the start of the array, shrinks it by one, and returns that SV (control of one reference count goes to the caller ๐Ÿซถ). Empty array โ†’ &PL_sv_undef.

Perl equivalent: shift(@myarray);

SV *       av_shift(      AV *av)
SV *  Perl_av_shift(pTHX_ AV *av)

av_store

Stores an SV in an array. The index is specified as key. The return value will be NULL if the operation failed, or if the value didn't actually need to be stored inside the array (like, say, for tied arrays). Otherwise you can dereference it to get the SV* that got stored there (= val)).

BESTIE. The caller is responsible for suitably incrementing the reference count of val before the call, and decrementing it if the function returned NULL. That's on you. ๐Ÿ’€

Approximate Perl equivalent: splice(@myarray, $key, 1, $val).

Wanna use this on tied arrays? Go read "Understanding the Magic of Tied Hashes and Arrays" in perlguts for the full lore.

SV **       av_store(      AV *av, SSize_t key, SV *val)
SV **  Perl_av_store(pTHX_ AV *av, SSize_t key, SV *val)

๐Ÿฆ‹ av_top_index / av_tindex / AvFILL / av_len ๐Ÿฆ‹

These all behave identically. If the array av is empty, they return -1. Otherwise they return the maximum value of the indices of all the array elements currently defined in av.

They process 'get' magic. โœจ

The Perl equivalent for these is $#av.

ngl, this trips everyone up: despite what the name av_len is giving, it returns the maximum index in the array. This is unlike sv_len, which returns what you would expect. To get the actual number of elements in an array, use av_count.
SSize_t       av_top_index(      AV *av)
SSize_t       av_tindex   (      AV *av)
SSize_t       AvFILL      (      AV* av)
SSize_t       av_len      (      AV *av)
SSize_t  Perl_av_len      (pTHX_ AV *av)

av_undef

Undefines the array. It's the XS equivalent of undef(@array).

On top of freeing all the elements of the array (like av_clear() does), this ALSO frees the memory the av was using to store its list of scalars. double duty, iconic.

See av_clear for a note about the array possibly being invalid on return.

void       av_undef(      AV *av)
void  Perl_av_undef(pTHX_ AV *av)

av_unshift

Unshifts the given number of undef values onto the beginning of the array. The array grows automatically to accommodate the addition ๐ŸŒฑ.

Perl equivalent: unshift @myarray, ((undef) x $num);

void       av_unshift(      AV *av, SSize_t num)
void  Perl_av_unshift(pTHX_ AV *av, SSize_t num)

AvALLOC

Described in perlguts.

AvALLOC(AV* av)

โญ AvARRAY โญ

Returns a pointer to the AV's internal SV* array.

This is the move for doing pointer arithmetic on the array ๐Ÿ’…. But if all you need is to look up an array element, then prefer av_fetch.

SV**  AvARRAY(AV* av)

AvFILL*

Described under "av_top_index".

๐Ÿ’œ AvREFCNT_inc / AvREFCNT_inc_simple / AvREFCNT_inc_simple_NN ๐Ÿ’œ

These all increment the reference count of the given SV, which has to be an AV. They're lowkey perfect when you're assigning the result into a typed pointer, because they save you from casting the result to the appropriate type. slay.

AV *  AvREFCNT_inc          (AV *av)
AV *  AvREFCNT_inc_simple   (AV *av)
AV *  AvREFCNT_inc_simple_NN(AV *av)

get_av

Returns the AV of the specified Perl global or package array with the given name (so it will not work on lexical variables, just so you know). flags are passed to gv_fetchpv. If GV_ADD is set and the Perl variable doesn't exist yet, it gets created. If flags is zero (ignoring SVf_UTF8) and the variable doesn't exist, you get NULL back.

Perl equivalent: @{"$name"}.

NOTE: the perl_get_av() form is deprecated. ๐Ÿšซ
AV *       get_av(      const char *name, I32 flags)
AV *  Perl_get_av(pTHX_ const char *name, I32 flags)

๐ŸŽ€ newAV / newAV_mortal / newAV_alloc_x / newAV_alloc_xz ๐ŸŽ€

All of these create a new AV with the reference count set to 1. If you already know the initial elements of the array, go peep "av_make".

Background lore, because you deserve to know ๐Ÿงš: an array is made of three things:

  1. A data structure holding info about the array as a whole โ€” its size, reference count, that kind of thing.
  2. A C language array of pointers to the individual elements. These get treated as pointers to SVs, so all of them must be castable to SV*.
  3. The individual elements themselves. These could be, like, SVs and/or AVs and/or HVs, etc.

An empty array only needs the first data structure, and all of these functions create that. What they do beyond that is where they differ:

newAV form

Does nothing past creating the whole-array data structure. The Perl equivalent is approximately my @array;

This is the one when the minimum size of the array could be zero (maybe there are likely code paths that will entirely skip using it ๐Ÿซฃ).

If the array does get used, the pointers data structure has to be allocated at that time. That ends up being done by av_extend, either explicitly:

av_extend(av, len);

or implicitly when the first element is stored:

(void)av_store(av, 0, sv);

Unused array elements are typically initialized by av_extend.

newAV_mortal form

This also creates the whole-array data structure, but it mortalises it too. (That is to say, a reference to the AV is added to the temps stack.)

newAV_alloc_x form

This effectively does a newAV followed by also allocating (uninitialized) space for the pointers array. Use it when you already know ahead of time the likely minimum size of the array. It's more efficient than doing a plain newAV and then following it with an av_extend.

Of course the array can be extended later should it become necessary.

size must be at least 1.

newAV_alloc_xz form

This is newAV_alloc_x, except it initializes each pointer in it to NULL. That's extra safety ๐Ÿ›ก๏ธ to guard against them being read before being set.

size must be at least 1.

The following examples all result in an array that can fit four elements (indexes 0 .. 3):

AV *av = newAV();
av_extend(av, 3);

AV *av = newAV_alloc_x(4);

AV *av = newAV_alloc_xz(4);

In contrast, the following examples allocate an array that is only guaranteed to fit one element without extending:

AV *av = newAV_alloc_x(1);
AV *av = newAV_alloc_xz(1);
AV *       newAV         ()
AV *  Perl_newAV         (pTHX)
AV *       newAV_mortal  ()
AV *  Perl_newAV_mortal  (pTHX)
AV *       newAV_alloc_x (      SSize_t size)
AV *  Perl_newAV_alloc_x (pTHX_ SSize_t size)
AV *       newAV_alloc_xz(      SSize_t size)
AV *  Perl_newAV_alloc_xz(pTHX_ SSize_t size)

newAVav

Creates a new AV and populates it with values copied from an existing AV. The new AV has a reference count of 1, and it contains newly created SVs copied from the original SV. The original source stays untouched ๐Ÿซถ, no cap.

Perl equivalent: my @new_array = @existing_array;

AV *       newAVav(      AV *oav)
AV *  Perl_newAVav(pTHX_ AV *oav)

newAVhv

Creates a new AV and populates it with keys and values copied from an existing HV. The new AV has a reference count of 1, and it contains newly created SVs copied from the original HV. The original source stays untouched.

Perl equivalent: my @new_array = %existing_hash;

AV *       newAVhv(      HV *ohv)
AV *  Perl_newAVhv(pTHX_ HV *ohv)

Nullav

DEPRECATED! It is planned to remove Nullav from a future release of Perl. Do not use it for new code; remove it from existing code. ๐Ÿ’€

Null AV pointer.

(deprecated - use (AV *)NULL instead)


๐ŸŒˆ Callback Functions ๐ŸŒˆ

call_argv

Performs a callback to the specified named and package-scoped Perl subroutine with argv (a NULL-terminated array of strings) as arguments. Go see perlcall for the details.

Approximate Perl equivalent: &{"$sub_name"}(@$argv).

NOTE: the perl_call_argv() form is deprecated.
SSize_t       call_argv(      const char *sub_name, I32 flags,
                              char **argv)
SSize_t  Perl_call_argv(pTHX_ const char *sub_name, I32 flags,
                              char **argv)

call_method

Performs a callback to the specified Perl method. The blessed object must be on the stack. See perlcall.

NOTE: the perl_call_method() form is deprecated.
SSize_t       call_method(      const char *methname, I32 flags)
SSize_t  Perl_call_method(pTHX_ const char *methname, I32 flags)

call_pv ๐Ÿ’–

Does a callback to the Perl sub you name. Like, you point at it and it goes. See perlcall.

NOTE: the perl_call_pv() form is deprecated, bestie. It's giving legacy. ๐Ÿ’€
SSize_t       call_pv(      const char *sub_name, I32 flags)
SSize_t  Perl_call_pv(pTHX_ const char *sub_name, I32 flags)

call_sv โœจ

Runs a callback to the Perl sub that the SV is pointing at, okay?

If you don't hand it either the G_METHOD or G_METHOD_NAMED flag, the SV can be literally any of: a CV, a GV, a reference to a CV, a reference to a GV โ€” or else SvPV(sv) gets used as the name of the sub to call. Versatile queen. ๐Ÿ‘‘

If you do pass G_METHOD, then the SV can be a reference to a CV, or SvPV(sv) gets used as the name of the method to call.

If you pass G_METHOD_NAMED, then SvPV(sv) is used as the name of the method to call. Periodt.

Some other values get treated specially for internal use, and you should not depend on those. That's a hard no. ๐Ÿ™ˆ

See perlcall.

NOTE: the perl_call_sv() form is deprecated.
SSize_t       call_sv(      SV *sv, I32 flags)
SSize_t  Perl_call_sv(pTHX_ SV *sv, I32 flags)

defer_error ๐Ÿซถ

Called to report compilation errors, and it does exactly one of these:

  • adds err to $@ inside an eval EXPR,
  • appends err to PL_errors, so it gets reported when the next exception is thrown, or
  • warns โ€” but only if it's called early in interpreter construction or late in interpreter destruction, like, when PL_errors isn't available at all.

And it increments the parser error count if we're parsing. ๐Ÿ’…

This function may throw an exception if too many errors have been produced. So yeah, careful.

It's intended for use during compilation.

void       defer_error(      SV *err)
void  Perl_defer_error(pTHX_ SV *err)

DESTRUCTORFUNC_NOCONTEXT_t / DESTRUCTORFUNC_t ๐Ÿงš

Described in perlguts.


ENTER ๐ŸŒธ

The opening bracket on a callback, bestie. See LEAVE and perlcall.

ENTER;

ENTER_with_name ๐ŸŽ€

Same as ENTER, but when debugging is enabled it also associates the given literal string with the new scope. It's the same thing but it knows its name. Iconic.

ENTER_with_name("name");

eval_pv โญ

Tells Perl to eval the string you give it, in scalar context, and hand you back an SV* result.

NOTE: the perl_eval_pv() form is deprecated.
SV *       eval_pv(      const char *p, I32 croak_on_error)
SV *  Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)

eval_sv ๐ŸŒˆ

Tells Perl to eval the string sitting inside the SV. It supports the same flags as call_sv, with the obvious exception of G_EVAL. See perlcall.

The G_RETHROW flag is there if you only need eval_sv() to run code specified by a string, but you don't wanna catch any errors. Sometimes you just wanna let it happen, yk? ๐Ÿ’€

By default the code is compiled and executed with the default hints, like strict and features. Set G_USEHINTS in flags if you want it to use the current hints from PL_curcop.

NOTE: the perl_eval_sv() form is deprecated.
SSize_t       eval_sv(      SV *sv, I32 flags)
SSize_t  Perl_eval_sv(pTHX_ SV *sv, I32 flags)

FREETMPS ๐Ÿฆ‹

The closing bracket for temporaries on a callback. See SAVETMPS and perlcall.

FREETMPS;

G_DISCARD, G_EVAL, G_KEEPERR, G_LIST, G_NOARGS, G_SCALAR, G_VOID ๐Ÿ’œ

Described in perlcall.


GIMME ๐Ÿ’€

DEPRECATED! It is planned to remove GIMME from a future release of Perl. Do not use it for new code; remove it from existing code. Like, actually remove it, bestie.

A backward-compatible version of GIMME_V which can only return G_SCALAR or G_LIST; in a void context, it returns G_SCALAR. Deprecated. Use GIMME_V instead.

U32  GIMME

GIMME_V โœจ

The XSUB-writer's equivalent to Perl's wantarray โ€” yes, the same vibe check your Perl code does all the time. It returns G_VOID, G_SCALAR or G_LIST for void, scalar or list context, respectively. See perlcall for a usage example.

U32  GIMME_V

is_lvalue_sub ๐ŸŽ€

Returns non-zero if the sub calling this function is being called in an lvalue context. Returns 0 otherwise.

I32       is_lvalue_sub()
I32  Perl_is_lvalue_sub(pTHX)

LEAVE ๐ŸŒธ

The closing bracket on a callback. See ENTER and perlcall.

LEAVE;

LEAVE_with_name ๐Ÿซถ

Same as LEAVE, but when debugging is enabled it first checks that the scope has the given name. name must be a literal string.

LEAVE_with_name("name");

mortal_destructor_sv / MORTALDESTRUCTOR_SV ๐Ÿงš

These two are synonymous. Same thing, two names, no notes. ๐Ÿ’…

They each arrange for either a Perl code reference or a C function reference to get called at the end of the current statement.

The coderef argument is what decides which type of function gets called:

  • If it's SvROK() it is assumed to be a reference to a CV, and it will arrange for the coderef to be called.
  • If it is not SvROK(), then it is assumed to be an SvIV() which is SvIOK() whose value is a pointer to a C function of type DESTRUCTORFUNC_t created using PTR2IV.

Either way, the args parameter will be provided to the callback as a parameter โ€” though the rules for doing so differ between the Perl and C modes. Normally this function is only used directly for the Perl case, and the wrapper mortal_destructor_x() is used for the C function case.

When operating in Perl callback mode, the args parameter may be NULL, in which case the code reference is called with no arguments. Otherwise, if it's an AV (SvTYPE(args) == SVt_PVAV) then the contents of the AV will be used as the arguments to the code reference. And if it's any other type, then the args SV will be provided as a single argument to the code reference.

When operating in C callback mode, the args parameter gets passed directly to the C function as a void * pointer. No additional processing of the argument is performed, and it is the caller's responsibility to free the args parameter if necessary. That one's on you, bestie. ๐Ÿซถ

Be aware that there is a significant difference in timing between the end of the current statement and the end of the current pseudo block. If you're looking for a mechanism to trigger a function at the end of the current pseudo block, you should look at SAVEDESTRUCTOR_X in perlapi instead of this function.
void       mortal_destructor_sv(      SV *coderef, SV *args)
void  Perl_mortal_destructor_sv(pTHX_ SV *coderef, SV *args)
void       MORTALDESTRUCTOR_SV (      SV *coderef, SV *args)

PL_errgv ๐Ÿ˜ญ

Described in perlcall.


save_aelem / save_aelem_flags ๐Ÿ’–

These each arrange for the value of the array element av[idx] to be restored at the end of the enclosing pseudo-block. Time travel but for array slots, honestly.

In save_aelem, the SV at **sptr will be replaced by a new undef scalar. That scalar will inherit any magic from the original **sptr, and any 'set' magic will be processed.

In save_aelem_flags, with SAVEf_KEEPOLDELEM set in flags, the function forgoes all of that: the scalar at **sptr is untouched. If SAVEf_KEEPOLDELEM is not set, the SV at **sptr will be replaced by a new undef scalar. That scalar will inherit any magic from the original **sptr. Any 'set' magic will be processed if and only if SAVEf_SETMAGIC is set in flags.

void       save_aelem      (      AV *av, SSize_t idx, SV **sptr)
void  Perl_save_aelem      (pTHX_ AV *av, SSize_t idx, SV **sptr)
void       save_aelem_flags(      AV *av, SSize_t idx, SV **sptr,
                                  const U32 flags)
void  Perl_save_aelem_flags(pTHX_ AV *av, SSize_t idx, SV **sptr,
                                  const U32 flags)

save_aptr, save_ary, save_hash โญ

Described in perlguts.

void       save_aptr(      AV **aptr)
void  Perl_save_aptr(pTHX_ AV **aptr)
AV *       save_ary (      GV *gv)
AV *  Perl_save_ary (pTHX_ GV *gv)
HV *       save_hash(      GV *gv)
HV *  Perl_save_hash(pTHX_ GV *gv)

save_helem / save_helem_flags ๐ŸŒˆ

These each arrange for the value of the hash element (in Perlish terms) $hv{key} to be restored at the end of the enclosing pseudo-block. Same energy as the array ones, but make it hashy. ๐Ÿ’…

In save_helem, the SV at **sptr will be replaced by a new undef scalar. That scalar will inherit any magic from the original **sptr, and any 'set' magic will be processed.

In save_helem_flags, with SAVEf_KEEPOLDELEM set in flags, the function forgoes all of that: the scalar at **sptr is untouched. If SAVEf_KEEPOLDELEM is not set, the SV at **sptr will be replaced by a new undef scalar. That scalar will inherit any magic from the original **sptr. Any 'set' magic will be processed if and only if SAVEf_SETMAGIC is set in flags.

void       save_helem      (      HV *hv, SV *key, SV **sptr)
void  Perl_save_helem      (pTHX_ HV *hv, SV *key, SV **sptr)
void       save_helem_flags(      HV *hv, SV *key, SV **sptr,
                                  const U32 flags)
void  Perl_save_helem_flags(pTHX_ HV *hv, SV *key, SV **sptr,
                                  const U32 flags)

save_hptr, save_item, save_scalar, save_svref, SAVEBOOL, SAVEDELETE, SAVEDESTRUCTOR, SAVEDESTRUCTOR_X, SAVEFREEOP, SAVEFREEPV, SAVEFREERCPV, SAVEFREESV, SAVEGENERICSV, SAVEINT, SAVEIV, SAVEI8, SAVEI16, SAVEI32, SAVEMORTALIZESV, SAVEPPTR, SAVERCPV, SAVESPTR, SAVESTACK_POS, SAVESTRLEN ๐Ÿ‘‘

Described in perlguts. That's the whole vibe, bestie โ€” go read perlguts for the tea. ๐Ÿ“

โ€ฆand here's the rest of that lineup, bestie, every signature copied over character-for-character, not a single one of them touched ๐Ÿ’…

void       save_hptr       (      HV **hptr)
void  Perl_save_hptr       (pTHX_ HV **hptr)
void       save_item       (      SV *item)
void  Perl_save_item       (pTHX_ SV *item)
SV *       save_scalar     (      GV *gv)
SV *  Perl_save_scalar     (pTHX_ GV *gv)
SV *       save_svref      (      SV **sptr)
SV *  Perl_save_svref      (pTHX_ SV **sptr)
           SAVEBOOL        (      bool i)
           SAVEDELETE      (      HV * hv, char * key,
                                  I32 length)
           SAVEDESTRUCTOR  (      DESTRUCTORFUNC_NOCONTEXT_t f,
                                  void *p)
           SAVEDESTRUCTOR_X(      DESTRUCTORFUNC_t f, void *p)
           SAVEFREEOP      (      OP *op)
           SAVEFREEPV      (      char *pv)
           SAVEFREERCPV    (      char *pv)
           SAVEFREESV      (      SV* sv)
           SAVEGENERICSV   (      char **psv)
           SAVEINT         (      int i)
           SAVEIV          (      IV i)
           SAVEI8          (      I8 i)
           SAVEI16         (      I16 i)
           SAVEI32         (      I32 i)
           SAVEMORTALIZESV (      SV* sv)
           SAVEPPTR        (      char * p)
           SAVERCPV        (      char *pv)
           SAVESPTR        (      SV * s)
           SAVESTACK_POS   ()
           SAVESTRLEN      (      STRLEN i)

๐ŸŽ€ SAVETMPS ๐ŸŽ€

okay so this is literally the opening bracket for temporaries on a callback, bestie. The closing one is "FREETMPS", and there's more gossip in perlcall. ๐Ÿซถ

SAVETMPS;

๐Ÿฆ‹ Casting ๐Ÿฆ‹

โœจ cBOOL โœจ

Cast-to-bool, no cap. Back when Perl could be compiled on pre-C99 compilers, a (bool) cast didn't necessarily do the right thing ๐Ÿ˜ญ so this macro got created โ€” and made somewhat complicated to work around bugs in old compilers. Now, many years later, and C99 is used, this is no longer required, but it's kept for backwards compatibility. It's giving legacy icon energy fr fr.

bool  cBOOL(bool expr)

โœจ I_V โœจ

Cast an NV to IV while avoiding undefined C behavior. That's it, that's the whole job ๐Ÿ’œ

IV  I_V(NV what)

โœจ I_32 โœจ

Cast an NV to I32 while avoiding undefined C behavior. Same energy, different width.

I32  I_32(NV what)

โœจ INT2PTR, PTRV, PTR2IV, PTR2nat, PTR2NV, PTR2ul, PTR2UV โœจ

Described in perlguts โ€” go read that one for the full tea ๐Ÿ“

type           INT2PTR(type, int value)
IV             PTR2IV (void * ptr)
IV             PTR2nat(void *)
NV             PTR2NV (void * ptr)
unsigned long  PTR2ul (void *)
UV             PTR2UV (void * ptr)

โœจ U_V โœจ

Cast an NV to UV while avoiding undefined C behavior. The unsigned bestie of I_V.

UV  U_V(NV what)

โœจ U_32 โœจ

Cast an NV to U32 while avoiding undefined C behavior. And that's the whole fam. ๐Ÿงš

U32  U_32(NV what)

๐ŸŒธ Character case changing ๐ŸŒธ

okay so this is where it gets interesting, and by interesting I mean complicated ๐Ÿ™ˆ

Perl uses "full" Unicode case mappings. That means converting a single character to another case may result in a sequence of more than one character. The iconic example: the uppercase of "รŸ" (LATIN SMALL LETTER SHARP S) is the two character sequence "SS". Not one character. Two. ๐Ÿ’€ This presents some complications.

The lowercase of all characters in the range 0..255 is a single character, and thus toLOWER_L1 is furnished ๐Ÿ’– But toUPPER_L1 can't exist, because it couldn't return a valid result for all legal inputs. Instead toUPPER_uvchr has an API that does allow every possible legal result to be returned. Likewise, no other function that is crippled by not being able to give the correct results for the full range of possible inputs has been implemented here. Periodt.

โœจ toCTRL, fromCTRL โœจ

toCTRL converts the character cp into its equivalent control character, i.e., what the Perl construct "\ccp" would do given the same input.

For example, toCTRL('A') yields 1.

fromCTRL goes the other way.

The original motivation behind this is that most keyboards for languages based on the Latin script will have keys labelled with the ASCII alphabetic characters. G is one such key. (That key should really be labelled g, because that's what generally gets transmitted to the computer when that key is pressed. Getting G transmitted instead usually requires the Shift key to simultaneously be held down.) There is typically a Ctrl key on such keyboards, and toCTRL('G') returns what gets transmitted when the Ctrl key and the G key are simultaneously pressed, hence its name. That value in this case is 7, which is an ASCII ALERT (or BEL). Hence, typing CTRL-G at the command line will typically trigger the computer's bell sound. ๐Ÿ”” iconic tbh.

The values are (fairly) standardized only for the following keys:

@       0
A-Z  1-26
[      27
\      28
]      29
^      30
_      31

The Perl language includes the \c construct to be able to express this mapping, (See "Quote and Quote-like Operators" in perlop and "OPERATOR DIFFERENCES" in perlebcdic), and the toCTRL macro is the XS and C language equivalent of that.

It has been ported to work on EBCDIC as well, so that the conversion is numerical, not semantic; that is, on EBCDIC platforms, CTRL-@ is 0, CTRL-A is 1, etc, just like on ASCII, except that they don't necessarily mean the same character. For example, toCTRL('D') yields 4 on both platforms, which happens to mean "EOT" ("END OF TRANSMISSION") on ASCII platforms (which is why CTRL-D is often used to exit out of a shell), and "SEL" (Select) on EBCDIC. (See perlebcdic/Unicode code points versus EBCDIC code points.) But Perl itself does not ascribe any meaning beyond it being 4. (If your need is to get to "EOT" from "D", no matter which platform, wrap it thusly: LATIN1_TO_NATIVE(toCTRL('D')).)

A lowercase argument yields the same result as its upper case equivalent, hence toCTRL('b') returns 2.

To go the other direction, starting with a value in the range 0..31, and yielding a character like 'A', you can use fromCTRL(). For alphabetic results, this will always be the uppercase form.

The macros also map between the ? character and a defined value. But it is not possible to do this portably between ASCII and EBCDIC. On ASCII platforms, it is mapped to 127, which happens to be "DELETE". On EBCDIC, it is mapped to the "APC" control, whatever value this happens to be for the flavor of EBCDIC used on the platform. What these all have in common is that the value chosen is the only control that isn't in the same contiguous block of controls that the others are in. ๐Ÿ˜ตโ€๐Ÿ’ซ

โš ๏ธ Using any other values than those mentioned yields an undefined result. Not dramatic, just true. Don't do it bestie.

(It turns out that the conversion works both ways (except for lowercase inputs), so toCTRL('E') is 5, and toCTRL(5) is E. But you shouldn't have to know that, so just use fromCTRL to get from 5 to "E".)

U8  toCTRL  (U8 cp)
U8  fromCTRL(U8 cp)

โœจ toFOLD, toFOLD_A, toFOLD_utf8, toFOLD_utf8_safe, toFOLD_uvchr โœจ

These all return the foldcase of a character. "foldcase" is an internal case for /i pattern matching. If the foldcase of character A and the foldcase of character B are the same, they match caselessly; otherwise they don't. ๐Ÿค

The differences in the forms are what domain they operate on, and whether the input is specified as a code point (those forms with a cp parameter) or as a UTF-8 string (the others). In the latter case, the code point to use is the first one in the buffer of UTF-8 encoded code points, delineated by the arguments p .. e - 1.

toFOLD and toFOLD_A are synonyms of each other. They return the foldcase of any ASCII-range code point. In this range, the foldcase is identical to the lowercase. All other inputs are returned unchanged. Since these are macros, the input type may be any integral one, and the output will occupy the same number of bits as the input.

There is no toFOLD_L1 nor toFOLD_LATIN1 as the foldcase of some code points in the 0..255 range is above that range or consists of multiple characters. Instead use toFOLD_uvchr. ๐Ÿ‘‘

toFOLD_uvchr returns the foldcase of any Unicode code point. The return value is identical to that of toFOLD_A for input code points in the ASCII range. The foldcase of the vast majority of Unicode code points is the same as the code point itself. For these, and for code points above the legal Unicode maximum, this returns the input code point unchanged. It additionally stores the UTF-8 of the result into the buffer beginning at s, and its length in bytes into *lenp. The caller must have made s large enough to contain at least UTF8_MAXBYTES_CASE+1 bytes to avoid possible overflow. ๐Ÿซฃ

๐Ÿ“Œ NOTE: the foldcase of a code point may be more than one code point. The return value of this function is only the first of these. The entire foldcase is returned in s. To determine if the result is more than a single code point, you can do something like this:
uc = toFOLD_uvchr(cp, s, &len);
if (len > UTF8SKIP(s)) { is multiple code points }
else { is a single code point }

toFOLD_utf8 and toFOLD_utf8_safe are synonyms of each other. The only difference between these and toFOLD_uvchr is that the source for these is encoded in UTF-8, instead of being a code point. It is passed as a buffer starting at p, with e pointing to one byte beyond its end. The p buffer may certainly contain more than one code point; but only the first one (up through e - 1) is examined. If the UTF-8 for the input character is malformed in some way, the program may croak, or the function may return the REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to change in future releases. ๐Ÿ˜ญ

UV  toFOLD          (UV cp)
UV  toFOLD_A        (UV cp)
UV  toFOLD_utf8     (U8* p, U8* e, U8* s, STRLEN* lenp)
UV  toFOLD_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
UV  toFOLD_uvchr    (UV cp, U8* s, STRLEN* lenp)

toLOWER, toLOWER_A, toLOWER_LATIN1, toLOWER_LC, toLOWER_L1, toLOWER_utf8, toLOWER_utf8_safe, toLOWER_uvchr โ€” okay so these all hand you back the lowercase of a character. ๐Ÿ’š The tea is: they differ in what domain they vibe in, and whether you feed them a code point (the ones with a cp parameter, obviously) or a UTF-8 string (everybody else). For the string girlies, the code point it actually uses is the first one chilling in the buffer of UTF-8 encoded code points, fenced in by p .. e - 1. ๐ŸŽ€

  • toLOWER and toLOWER_A are synonyms, literally twins. They return the lowercase of any uppercase ASCII-range code point. Everything else gets returned untouched, no notes. And because they're macros, the input type can be any integral one and the output takes up the same number of bits as the input. slay.
  • toLOWER_L1 and toLOWER_LATIN1 are also synonyms of each other. For ASCII-range input they act exactly like toLOWER. But bestie, they also return the lowercase of any uppercase code point in the entire 0..255 range, assuming a Latin-1 encoding (or the EBCDIC equivalent on platforms like that). ๐ŸŒธ
  • toLOWER_LC returns the lowercase of the input code point following the rules of the current POSIX locale. Code points outside 0..255? Returned unchanged, periodt.
  • toLOWER_uvchr returns the lowercase of any Unicode code point. For input code points in the 0..255 range its return value is identical to toLOWER_L1. For the vast vast majority of Unicode code points the lowercase is just... the code point itself. So for those, and for anything above the legal Unicode maximum, it returns the input unchanged. ๐Ÿฆ‹ It also stashes the UTF-8 of the result into the buffer starting at s, and drops its length in bytes into *lenp. The caller must have made s big enough to hold at least UTF8_MAXBYTES_CASE+1 bytes, otherwise overflow is possible. ๐Ÿ˜ญ
NOTE: the lowercase of a code point can be more than one code point. The return value of this function is only the first of these. The whole entire lowercase is returned in s. To figure out if you got more than a single code point, you can do something like this:
 uc = toLOWER_uvchr(cp, s, &len);
 if (len > UTF8SKIP(s)) { is multiple code points }
 else { is a single code point }
  • toLOWER_utf8 and toLOWER_utf8_safe are synonyms. The only difference between these and toLOWER_uvchr is that the source here is encoded in UTF-8 instead of being a code point. It comes in as a buffer starting at p, with e pointing one byte past its end. The p buffer can absolutely hold more than one code point; but only the first one (up through e - 1) gets examined. If the UTF-8 for the input character is malformed somehow, the program may croak, or the function may return the REPLACEMENT CHARACTER โ€” that's at the discretion of the implementation and subject to change in future releases. ๐Ÿ’€
 UV  toLOWER          (UV cp)
 UV  toLOWER_A        (UV cp)
 UV  toLOWER_LATIN1   (UV cp)
 UV  toLOWER_LC       (UV cp)
 UV  toLOWER_L1       (UV cp)
 UV  toLOWER_utf8     (U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toLOWER_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toLOWER_uvchr    (UV cp, U8* s, STRLEN* lenp)

toTITLE, toTITLE_A, toTITLE_utf8, toTITLE_utf8_safe, toTITLE_uvchr โ€” same energy, but these return the titlecase of a character. ๐ŸŽ€ Differences again are the domain and whether the input is a code point (the cp ones) or a UTF-8 string (the rest). For the string ones, the code point used is the first one in the buffer of UTF-8 encoded code points, delineated by p .. e - 1.

  • toTITLE and toTITLE_A are synonyms. They return the titlecase of any lowercase ASCII-range code point. In this range, titlecase is identical to uppercase, iykyk. All other inputs come back unchanged. Macros, so input type can be any integral one and output occupies the same number of bits as the input.
  • There is no toTITLE_L1 and no toTITLE_LATIN1, because for some code points in the 0..255 range the titlecase is above that range or is made of multiple characters. So instead, use toTITLE_uvchr. ๐Ÿ™ˆ
  • toTITLE_uvchr returns the titlecase of any Unicode code point. For input code points in the ASCII range, the return value is identical to toTITLE_A. The titlecase of the vast majority of Unicode code points is the same as the code point itself, and for those (plus code points above the legal Unicode maximum) it returns the input code point unchanged. It also stores the UTF-8 of the result into the buffer beginning at s, with its length in bytes into *lenp. Caller must have made s large enough for at least UTF8_MAXBYTES_CASE+1 bytes to avoid possible overflow. โš ๏ธ
NOTE: the titlecase of a code point may be more than one code point. The return value is only the first of these. The entire titlecase is returned in s. To check if the result is more than a single code point, you can do something like this:
 uc = toTITLE_uvchr(cp, s, &len);
 if (len > UTF8SKIP(s)) { is multiple code points }
 else { is a single code point }
  • toTITLE_utf8 and toTITLE_utf8_safe are synonyms of each other. The only difference between these and toTITLE_uvchr is that the source here is encoded in UTF-8 instead of being a code point. It's passed as a buffer starting at p, with e pointing one byte beyond its end. The p buffer can for sure contain more than one code point; only the first (up through e - 1) is examined. If the UTF-8 for the input character is malformed in some way, the program may croak, or the function may return the REPLACEMENT CHARACTER, at the discretion of the implementation and subject to change in future releases. don't say I didn't warn you
 UV  toTITLE          (UV cp)
 UV  toTITLE_A        (UV cp)
 UV  toTITLE_utf8     (U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toTITLE_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toTITLE_uvchr    (UV cp, U8* s, STRLEN* lenp)

toUPPER, toUPPER_A, toUPPER_utf8, toUPPER_utf8_safe, toUPPER_uvchr โ€” and these ones give you the uppercase of a character. ๐Ÿ’… Differences? Domain, and whether the input is a code point (the cp forms) or a UTF-8 string (the others). In the latter case, the code point to use is the first one in the buffer of UTF-8 encoded code points, delineated by the arguments p .. e - 1.

  • toUPPER and toUPPER_A are synonyms of each other. They return the uppercase of any lowercase ASCII-range code point. All other inputs are returned unchanged. Since these are macros, the input type may be any integral one, and the output will occupy the same number of bits as the input. โœจ
  • There is no toUPPER_L1 nor toUPPER_LATIN1, because the uppercase of some code points in the 0..255 range is above that range or consists of multiple characters. Instead use toUPPER_uvchr. ๐Ÿงš
  • toUPPER_uvchr returns the uppercase of any Unicode code point. The return value is identical to that of toUPPER_A for input code points in the ASCII range. The uppercase of the vast majority of Unicode code points is the same as the code point itself; for those, and for code points above the legal Unicode maximum, this returns the input code point unchanged. It additionally stores the UTF-8 of the result into the buffer beginning at s, and its length in bytes into *lenp. The caller must have made s large enough to contain at least UTF8_MAXBYTES_CASE+1 bytes to avoid possible overflow. ๐ŸŒˆ
NOTE: the uppercase of a code point may be more than one code point. The return value of this function is only the first of these. The entire uppercase is returned in s. To determine if the result is more than a single code point, you can do something like this:
 uc = toUPPER_uvchr(cp, s, &len);
 if (len > UTF8SKIP(s)) { is multiple code points }
 else { is a single code point }
  • toUPPER_utf8 and toUPPER_utf8_safe are synonyms of each other. The only difference between these and toUPPER_uvchr is that the source for these is encoded in UTF-8, instead of being a code point. It is passed as a buffer starting at p, with e pointing to one byte beyond its end. The p buffer may certainly contain more than one code point; but only the first one (up through e - 1) is examined. If the UTF-8 for the input character is malformed in some way, the program may croak, or the function may return the REPLACEMENT CHARACTER, at the discretion of the implementation, and subject to change in future releases. ๐Ÿ˜ญ
 UV  toUPPER          (UV cp)
 UV  toUPPER_A        (UV cp)
 UV  toUPPER_utf8     (U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toUPPER_utf8_safe(U8* p, U8* e, U8* s, STRLEN* lenp)
 UV  toUPPER_uvchr    (UV cp, U8* s, STRLEN* lenp)

๐Ÿ” Character classification ๐Ÿ”

Okay bestie, this section is all about the functions (and honestly, they're really macros) that sort characters into types โ€” punctuation vs. alphabetic, that whole thing. ๐Ÿ’œ Most of them are analogous to regular expression character classes. (Peep "POSIX Character Classes" in perlrecharclass.) There are several variants for each class. (Not every macro has every variant; each item below lists the ones that are valid for it.) None of them are affected by use bytes, and only the ones with LC in the name are affected by the current locale. ๐Ÿ‘‘

The base function, e.g. isALPHA(), takes any signed or unsigned value, treats it as a code point, and returns a boolean saying whether the character it represents is (or, on non-ASCII platforms, corresponds to) an ASCII character in the named class, based on platform, Unicode, and Perl rules. If the input is a number that doesn't fit in an octet, FALSE is what you get. ๐Ÿšซ

Variant isFOO_A (e.g., isALPHA_A()) is identical to the base function with no _A suffix. This variant exists to emphasize by its name that only ASCII-range characters can return TRUE. โญ

Variant isFOO_L1 is giving "bestie, we're on Latin-1 now" energy. It imposes the Latin-1 (or the EBCDIC equivalent, iykyk) character set onto the platform. So the ASCII code points? Literally unaffected, because ASCII is a subset of Latin-1. But the non-ASCII code points are treated as if they're Latin-1 characters. For example, isWORDCHAR_L1() will return true when you call it with code point 0xDF, which is a word character in both ASCII and EBCDIC (though it represents different characters in each, not me saying that, the manpage says that ๐Ÿ’€). If the input is a number that doesn't fit in an octet, FALSE is returned. (Perl's documentation uses a colloquial definition of Latin-1, to include all code points below 256. Iconic.)

Variant isFOO_uvchr is exactly like the isFOO_L1 variant for inputs below 256, but if the code point is larger than 255, Unicode rules are used to determine if it's in the character class. Example: isWORDCHAR_uvchr(0x100) returns TRUE, since 0x100 is LATIN CAPITAL LETTER A WITH MACRON in Unicode, and is a word character. Slay. ๐Ÿ’…

Variants isFOO_utf8 and isFOO_utf8_safe are like isFOO_uvchr, but they're for UTF-8 encoded strings. The two forms are different names for the same thing. Each call to one of these classifies the first character of the string starting at p. The second parameter, e, points to anywhere in the string beyond the first character, up to one byte past the end of the entire string. Although both variants are identical, the suffix _safe in one name emphasizes that it will not attempt to read beyond e - 1, provided that the constraint s < e is true (this is asserted for in -DDEBUGGING builds). If the UTF-8 for the input character is malformed in some way, the program may croak, or the function may return FALSE, at the discretion of the implementation, and subject to change in future releases. So like, don't @ me if it changes. ๐Ÿ™ˆ

Variant isFOO_LC is like the isFOO_A and isFOO_L1 variants, but the result is based on the current locale, which is what LC in the name stands for. If Perl can determine that the current locale is a UTF-8 locale, it uses the published Unicode rules; otherwise, it uses the C library function that gives the named classification. For example, isDIGIT_LC() when not in a UTF-8 locale returns the result of calling isdigit(). FALSE is always returned if the input won't fit into an octet. On some platforms where the C library function is known to be defective, Perl changes its result to follow the POSIX standard's rules. Periodt.

Variant isFOO_LC_uvchr acts exactly like isFOO_LC for inputs less than 256, but for larger ones it returns the Unicode classification of the code point.

Variants isFOO_LC_utf8 and isFOO_LC_utf8_safe are like isFOO_LC_uvchr, but are used for UTF-8 encoded strings. The two forms are different names for the same thing. Each call to one of these classifies the first character of the string starting at p. The second parameter, e, points to anywhere in the string beyond the first character, up to one byte past the end of the entire string. Although both variants are identical, the suffix _safe in one name emphasizes that it will not attempt to read beyond e - 1, provided that the constraint s < e is true (this is asserted for in -DDEBUGGING builds). If the UTF-8 for the input character is malformed in some way, the program may croak, or the function may return FALSE, at the discretion of the implementation, and subject to change in future releases. Again, future releases can change it, so stay woke. โœจ


โœจ isALNUM, isALNUM_A, isALNUM_LC, isALNUM_LC_uvchr โœจ

These are each a synonym for their respectively named isWORDCHAR variant. That's the tea. They're provided for backward compatibility, even though a word character includes more than the standard C language meaning of alphanumeric. To get the C language definition, use the corresponding isALPHANUMERIC variant. Don't mix them up, bestie.

bool  isALNUM         (UV ch)
bool  isALNUM_A       (UV ch)
bool  isALNUM_LC      (UV ch)
bool  isALNUM_LC_uvchr(UV ch)

๐Ÿ’… isALNUMC, isALNUMC_A, isALNUMC_LC, isALNUMC_LC_uvchr, isALNUMC_L1 ๐Ÿ’…

These are discouraged, backward compatibility macros for isALPHANUMERIC. That is, each returns a boolean indicating whether the specified character is one of [A-Za-z0-9], analogous to m/[[:alnum:]]/. The C suffix in the names was meant to indicate that they correspond to the C language isalnum(3). So like, they're legacy, but still here. ๐Ÿซถ

bool  isALNUMC         (UV ch)
bool  isALNUMC_A       (UV ch)
bool  isALNUMC_LC      (UV ch)
bool  isALNUMC_LC_uvchr(UV ch)
bool  isALNUMC_L1      (UV ch)

โœจ isALPHA, isALPHA_A, isALPHA_LC, isALPHA_LC_utf8_safe, isALPHA_LC_uvchr, isALPHA_L1, isALPHA_utf8, isALPHA_utf8_safe, isALPHA_uvchr โœจ

Returns a boolean indicating whether the specified input is one of [A-Za-z], analogous to m/[[:alpha:]]/. See the top of this section for an explanation of the variants. It's giving alphabet energy. ๐ŸŒธ

bool  isALPHA             (UV ch)
bool  isALPHA_A           (UV ch)
bool  isALPHA_LC          (UV ch)
bool  isALPHA_LC_utf8_safe(U8 * s, U8 *end)
bool  isALPHA_LC_uvchr    (UV ch)
bool  isALPHA_L1          (UV ch)
bool  isALPHA_utf8        (U8 * s, U8 * end)
bool  isALPHA_utf8_safe   (U8 * s, U8 * end)
bool  isALPHA_uvchr       (UV ch)

๐Ÿฆ‹ isALPHANUMERIC, isALPHANUMERIC_A, isALPHANUMERIC_LC, isALPHANUMERIC_LC_utf8_safe, isALPHANUMERIC_LC_uvchr, isALPHANUMERIC_L1, isALPHANUMERIC_utf8, isALPHANUMERIC_utf8_safe, isALPHANUMERIC_uvchr ๐Ÿฆ‹

Returns a boolean indicating whether the specified character is one of [A-Za-z0-9], analogous to m/[[:alnum:]]/. See the top of this section for an explanation of the variants. Yes, it's the long name, but it's the C-language-correct one, periodt.

bool  isALPHANUMERIC             (UV ch)
bool  isALPHANUMERIC_A           (UV ch)
bool  isALPHANUMERIC_LC          (UV ch)
bool  isALPHANUMERIC_LC_utf8_safe(U8 * s, U8 *end)
bool  isALPHANUMERIC_LC_uvchr    (UV ch)
bool  isALPHANUMERIC_L1          (UV ch)
bool  isALPHANUMERIC_utf8        (U8 * s, U8 * end)
bool  isALPHANUMERIC_utf8_safe   (U8 * s, U8 * end)
bool  isALPHANUMERIC_uvchr       (UV ch)

๐Ÿ’– isASCII, isASCII_A, isASCII_LC, isASCII_LC_utf8_safe, isASCII_LC_uvchr, isASCII_L1, isASCII_utf8, isASCII_utf8_safe, isASCII_uvchr ๐Ÿ’–

Returns a boolean indicating whether the specified character is one of the 128 characters in the ASCII character set, analogous to m/[[:ascii:]]/. On non-ASCII platforms, it returns TRUE iff this character corresponds to an ASCII character. Variants isASCII_A() and isASCII_L1() are identical to isASCII(). See the top of this section for an explanation of the variants. Note, however, that some platforms do not have the C library routine isascii(). In these cases, the variants whose names contain LC are the same as the corresponding ones without. So if your platform is missing it, don't panic, it's fine. ๐ŸŽ€

Also note, that because all ASCII characters are UTF-8 invariant (meaning they have the exact same representation (always a single byte) whether encoded in UTF-8 or not), isASCII will give the correct results when called with any byte in any string encoded or not in UTF-8. And similarly isASCII_utf8 and isASCII_utf8_safe will work properly on any string encoded or not in UTF-8. That's highkey convenient.

bool  isASCII             (UV ch)
bool  isASCII_A           (UV ch)
bool  isASCII_LC          (UV ch)
bool  isASCII_LC_utf8_safe(U8 * s, U8 *end)
bool  isASCII_LC_uvchr    (UV ch)
bool  isASCII_L1          (UV ch)
bool  isASCII_utf8        (U8 * s, U8 * end)
bool  isASCII_utf8_safe   (U8 * s, U8 * end)
bool  isASCII_uvchr       (UV ch)

๐ŸŽ€ isBLANK, isBLANK_A, isBLANK_LC, isBLANK_LC_utf8_safe, isBLANK_LC_uvchr, isBLANK_L1, isBLANK_utf8, isBLANK_utf8_safe, isBLANK_uvchr ๐ŸŽ€

Returns a boolean indicating whether the specified character is a character considered to be a blank, analogous to m/[[:blank:]]/. See the top of this section for an explanation of the variants. Note, however, that some platforms do not have the C library routine isblank(). In these cases, the variants whose names contain LC are the same as the corresponding ones without. So like, blanks are blanks. ๐ŸŒธ

bool  isBLANK             (UV ch)
bool  isBLANK_A           (UV ch)
bool  isBLANK_LC          (UV ch)
bool  isBLANK_LC_utf8_safe(U8 * s, U8 *end)
bool  isBLANK_LC_uvchr    (UV ch)
bool  isBLANK_L1          (UV ch)
bool  isBLANK_utf8        (U8 * s, U8 * end)
bool  isBLANK_utf8_safe   (U8 * s, U8 * end)
bool  isBLANK_uvchr       (UV ch)

๐ŸŒˆ isCNTRL, isCNTRL_A, isCNTRL_LC, isCNTRL_LC_utf8_safe, isCNTRL_LC_uvchr, isCNTRL_L1, isCNTRL_utf8, isCNTRL_utf8_safe, isCNTRL_uvchr ๐ŸŒˆ

Returns a boolean indicating whether the specified character is a control character, analogous to m/[[:cntrl:]]/. See the top of this section for an explanation of the variants. On EBCDIC platforms, you almost always want to use the isCNTRL_L1 variant. That's the vibe check for EBCDIC, bestie. โœจ

bool  isCNTRL             (UV ch)
bool  isCNTRL_A           (UV ch)
bool  isCNTRL_LC          (UV ch)
bool  isCNTRL_LC_utf8_safe(U8 * s, U8 *end)
bool  isCNTRL_LC_uvchr    (UV ch)
bool  isCNTRL_L1          (UV ch)
bool  isCNTRL_utf8        (U8 * s, U8 * end)
bool  isCNTRL_utf8_safe   (U8 * s, U8 * end)
bool  isCNTRL_uvchr       (UV ch)

๐Ÿ“ isDIGIT, isDIGIT_A, isDIGIT_LC, isDIGIT_LC_utf8_safe, isDIGIT_LC_uvchr, isDIGIT_L1, isDIGIT_utf8, isDIGIT_utf8_safe, isDIGIT_uvchr ๐Ÿ“

Returns a boolean indicating whether the specified character is a digit, analogous to m/[[:digit:]]/. Variants isDIGIT_A and isDIGIT_L1 are identical to isDIGIT. See the top of this section for an explanation of the variants. Numbers are iconic, so yes. ๐Ÿ’…

bool  isDIGIT             (UV ch)
bool  isDIGIT_A           (UV ch)
bool  isDIGIT_LC          (UV ch)
bool  isDIGIT_LC_utf8_safe(U8 * s, U8 *end)
bool  isDIGIT_LC_uvchr    (UV ch)
bool  isDIGIT_L1          (UV ch)
bool  isDIGIT_utf8        (U8 * s, U8 * end)
bool  isDIGIT_utf8_safe   (U8 * s, U8 * end)
bool  isDIGIT_uvchr       (UV ch)

K more classification besties incoming, no breaks, no stopping ๐Ÿ’… remember the golden rule: any time it says see the top of this section for an explanation of the variants, that whole _A / _LC / _utf8_safe / _uvchr lore lives up there and I am not re-typing it. Periodt.


isGRAPH, isGRAPH_A, isGRAPH_LC, isGRAPH_LC_utf8_safe, isGRAPH_LC_uvchr, isGRAPH_L1, isGRAPH_utf8, isGRAPH_utf8_safe, isGRAPH_uvchr

Hands you back a boolean: is the char you passed in a graphic character or not? It's literally giving m/[[:graph:]]/ energy. Variants explained at the top of this section, you know the drill ๐Ÿฆ‹

 bool  isGRAPH             (UV ch)
 bool  isGRAPH_A           (UV ch)
 bool  isGRAPH_LC          (UV ch)
 bool  isGRAPH_LC_utf8_safe(U8 * s, U8 *end)
 bool  isGRAPH_LC_uvchr    (UV ch)
 bool  isGRAPH_L1          (UV ch)
 bool  isGRAPH_utf8        (U8 * s, U8 * end)
 bool  isGRAPH_utf8_safe   (U8 * s, U8 * end)
 bool  isGRAPH_uvchr       (UV ch)

isIDCONT, isIDCONT_A, isIDCONT_LC, isIDCONT_LC_utf8_safe, isIDCONT_LC_uvchr, isIDCONT_L1, isIDCONT_utf8, isIDCONT_utf8_safe, isIDCONT_uvchr

Boolean o'clock: can this character be the second or any succeeding character of an identifier? And no cap, this is very close to but not quite the same as the official Unicode property XID_Continue ๐Ÿ‘€ the difference? It only returns true if the input character also matches isWORDCHAR. Variants? top of the section, bestie โœจ

 bool  isIDCONT             (UV ch)
 bool  isIDCONT_A           (UV ch)
 bool  isIDCONT_LC          (UV ch)
 bool  isIDCONT_LC_utf8_safe(U8 * s, U8 *end)
 bool  isIDCONT_LC_uvchr    (UV ch)
 bool  isIDCONT_L1          (UV ch)
 bool  isIDCONT_utf8        (U8 * s, U8 * end)
 bool  isIDCONT_utf8_safe   (U8 * s, U8 * end)
 bool  isIDCONT_uvchr       (UV ch)

isIDFIRST, isIDFIRST_A, isIDFIRST_LC, isIDFIRST_LC_utf8_safe, isIDFIRST_LC_uvchr, isIDFIRST_L1, isIDFIRST_utf8, isIDFIRST_utf8_safe, isIDFIRST_uvchr

Same deal but for the first character of an identifier. Very close to, not quite the same as, the official Unicode property XID_Start โ€” again, the twist is it returns true only if the input character also matches isWORDCHAR. Variants: top of section, always ๐ŸŒธ

 bool  isIDFIRST             (UV ch)
 bool  isIDFIRST_A           (UV ch)
 bool  isIDFIRST_LC          (UV ch)
 bool  isIDFIRST_LC_utf8_safe(U8 * s, U8 *end)
 bool  isIDFIRST_LC_uvchr    (UV ch)
 bool  isIDFIRST_L1          (UV ch)
 bool  isIDFIRST_utf8        (U8 * s, U8 * end)
 bool  isIDFIRST_utf8_safe   (U8 * s, U8 * end)
 bool  isIDFIRST_uvchr       (UV ch)

isLOWER, isLOWER_A, isLOWER_LC, isLOWER_LC_utf8_safe, isLOWER_LC_uvchr, isLOWER_L1, isLOWER_utf8, isLOWER_utf8_safe, isLOWER_uvchr

Returns a boolean telling you if the char is a lowercase character, analogous to m/[[:lower:]]/. Variants โ€” top of the section ๐ŸŽ€

 bool  isLOWER             (UV ch)
 bool  isLOWER_A           (UV ch)
 bool  isLOWER_LC          (UV ch)
 bool  isLOWER_LC_utf8_safe(U8 * s, U8 *end)
 bool  isLOWER_LC_uvchr    (UV ch)
 bool  isLOWER_L1          (UV ch)
 bool  isLOWER_utf8        (U8 * s, U8 * end)
 bool  isLOWER_utf8_safe   (U8 * s, U8 * end)
 bool  isLOWER_uvchr       (UV ch)

isOCTAL, isOCTAL_A, isOCTAL_L1

Tiny crew, only three of them, iconic. Returns a boolean: is this char an octal digit, [0-7]? The only two variants are isOCTAL_A and isOCTAL_L1, and bestie, each one is identical to isOCTAL. That's it, that's the whole fam ๐Ÿ“

 bool  isOCTAL   (UV ch)
 bool  isOCTAL_A (UV ch)
 bool  isOCTAL_L1(UV ch)

isPRINT, isPRINT_A, isPRINT_LC, isPRINT_LC_utf8_safe, isPRINT_LC_uvchr, isPRINT_L1, isPRINT_utf8, isPRINT_utf8_safe, isPRINT_uvchr

Boolean, is the char a printable character? Analogous to m/[[:print:]]/. Variants = top of section ๐Ÿ’›

 bool  isPRINT             (UV ch)
 bool  isPRINT_A           (UV ch)
 bool  isPRINT_LC          (UV ch)
 bool  isPRINT_LC_utf8_safe(U8 * s, U8 *end)
 bool  isPRINT_LC_uvchr    (UV ch)
 bool  isPRINT_L1          (UV ch)
 bool  isPRINT_utf8        (U8 * s, U8 * end)
 bool  isPRINT_utf8_safe   (U8 * s, U8 * end)
 bool  isPRINT_uvchr       (UV ch)

isPSXSPC, isPSXSPC_A, isPSXSPC_LC, isPSXSPC_LC_utf8_safe, isPSXSPC_LC_uvchr, isPSXSPC_L1, isPSXSPC_utf8, isPSXSPC_utf8_safe, isPSXSPC_uvchr

(short for Posix Space, yes the name is a whole vibe.) Starting in 5.18, this is identical in all its forms to the corresponding isSPACE() macros. The locale forms of this macro are identical to their corresponding isSPACE() forms in all Perl releases. But in releases prior to 5.18, the non-locale forms differ from their isSPACE() forms in exactly one way: the isSPACE() forms don't match a Vertical Tab, and the isPSXSPC() forms do. Otherwise? Identical, twins fr fr.

So this macro is analogous to what m/[[:space:]]/ matches in a regular expression. Variants: top of the section ๐Ÿซถ

 bool  isPSXSPC             (UV ch)
 bool  isPSXSPC_A           (UV ch)
 bool  isPSXSPC_LC          (UV ch)
 bool  isPSXSPC_LC_utf8_safe(U8 * s, U8 *end)
 bool  isPSXSPC_LC_uvchr    (UV ch)
 bool  isPSXSPC_L1          (UV ch)
 bool  isPSXSPC_utf8        (U8 * s, U8 * end)
 bool  isPSXSPC_utf8_safe   (U8 * s, U8 * end)
 bool  isPSXSPC_uvchr       (UV ch)

isPUNCT, isPUNCT_A, isPUNCT_LC, isPUNCT_LC_utf8_safe, isPUNCT_LC_uvchr, isPUNCT_L1, isPUNCT_utf8, isPUNCT_utf8_safe, isPUNCT_uvchr

Boolean: is the char a punctuation character, analogous to m/[[:punct:]]/. Fair warning though โ€” the definition of what counts as punctuation isn't as straightforward as one might desire ๐Ÿ˜ญ see "POSIX Character Classes" in perlrecharclass for the details. Variants: top of the section, obviously ๐Ÿ’…

 bool  isPUNCT             (UV ch)
 bool  isPUNCT_A           (UV ch)
 bool  isPUNCT_LC          (UV ch)
 bool  isPUNCT_LC_utf8_safe(U8 * s, U8 *end)
 bool  isPUNCT_LC_uvchr    (UV ch)
 bool  isPUNCT_L1          (UV ch)
 bool  isPUNCT_utf8        (U8 * s, U8 * end)
 bool  isPUNCT_utf8_safe   (U8 * s, U8 * end)
 bool  isPUNCT_uvchr       (UV ch)

isSPACE, isSPACE_A, isSPACE_LC, isSPACE_LC_utf8_safe, isSPACE_LC_uvchr, isSPACE_L1, isSPACE_utf8, isSPACE_utf8_safe, isSPACE_uvchr

Boolean: is the char a whitespace character? Analogous to what m/\s/ matches in a regex. Starting in Perl 5.18 this also matches what m/[[:space:]]/ does.

Prior to 5.18, only the locale forms of this macro โ€” the ones with LC in their names โ€” matched precisely what m/[[:space:]]/ does. In those releases, the only difference in the non-locale variants was that isSPACE() did not match a vertical tab. (See isPSXSPC for a macro that matches a vertical tab in all releases.) ๐Ÿ‘‘

And yes, variants are explained at the top of this section ๐ŸŒˆ

 bool  isSPACE             (UV ch)
 bool  isSPACE_A           (UV ch)
 bool  isSPACE_LC          (UV ch)
 bool  isSPACE_LC_utf8_safe(U8 * s, U8 *end)
 bool  isSPACE_LC_uvchr    (UV ch)
 bool  isSPACE_L1          (UV ch)
 bool  isSPACE_utf8        (U8 * s, U8 * end)
 bool  isSPACE_utf8_safe   (U8 * s, U8 * end)
 bool  isSPACE_uvchr       (UV ch)

isUPPER, isUPPER_A, isUPPER_LC, isUPPER_LC_utf8_safe, isUPPER_LC_uvchr, isUPPER_L1, isUPPER_utf8, isUPPER_utf8_safe, isUPPER_uvchr

Boolean: uppercase character? Analogous to m/[[:upper:]]/. Variants at the top of the section, bestie โœจ

 bool  isUPPER             (UV ch)
 bool  isUPPER_A           (UV ch)
 bool  isUPPER_LC          (UV ch)
 bool  isUPPER_LC_utf8_safe(U8 * s, U8 *end)
 bool  isUPPER_LC_uvchr    (UV ch)
 bool  isUPPER_L1          (UV ch)
 bool  isUPPER_utf8        (U8 * s, U8 * end)
 bool  isUPPER_utf8_safe   (U8 * s, U8 * end)
 bool  isUPPER_uvchr       (UV ch)

isWORDCHAR, isWORDCHAR_A, isWORDCHAR_LC, isWORDCHAR_LC_utf8_safe, isWORDCHAR_LC_uvchr, isWORDCHAR_L1, isWORDCHAR_utf8, isWORDCHAR_utf8_safe, isWORDCHAR_uvchr

Boolean: is this a word character? It's the m/\w/ and m/[[:word:]]/ match energy. So what even is a word character, you ask? It's:

  • an alphabetic character
  • a decimal digit
  • a connecting punctuation character (such as an underscore)
  • or a "mark" character that attaches to one of those (like some sort of accent)

Variants explained at the top of this section, same as always ๐Ÿ’–

Oh and special shoutout: isWORDCHAR_A, isWORDCHAR_L1, isWORDCHAR_uvchr, isWORDCHAR_LC, isWORDCHAR_LC_uvchr, isWORDCHAR_LC_utf8, and isWORDCHAR_LC_utf8_safe are also as described up there โ€” but they additionally include the platform's native underscore. Noted, not messing that up ๐Ÿซก

 bool  isWORDCHAR             (UV ch)
 bool  isWORDCHAR_A           (UV ch)
 bool  isWORDCHAR_LC          (UV ch)
 bool  isWORDCHAR_LC_utf8_safe(U8 * s, U8 *end)
 bool  isWORDCHAR_LC_uvchr    (UV ch)
 bool  isWORDCHAR_L1          (UV ch)
 bool  isWORDCHAR_utf8        (U8 * s, U8 * end)
 bool  isWORDCHAR_utf8_safe   (U8 * s, U8 * end)
 bool  isWORDCHAR_uvchr       (UV ch)

isXDIGIT, isXDIGIT_A, isXDIGIT_LC, isXDIGIT_LC_utf8_safe, isXDIGIT_LC_uvchr, isXDIGIT_L1, isXDIGIT_utf8, isXDIGIT_utf8_safe, isXDIGIT_uvchr

Boolean: is the char a hexadecimal digit? In the ASCII range those bad boys are [0-9A-Fa-f] ๐Ÿ”ฅ and the variants isXDIGIT_A() and isXDIGIT_L1() are identical to isXDIGIT(). Variants explanation: top of this section, you already know ๐ŸŽ€

bool  isXDIGIT             (UV ch)
bool  isXDIGIT_A           (UV ch)
bool  isXDIGIT_LC          (UV ch)
bool  isXDIGIT_LC_utf8_safe(U8 * s, U8 *end)
bool  isXDIGIT_LC_uvchr    (UV ch)
bool  isXDIGIT_L1          (UV ch)
bool  isXDIGIT_utf8        (U8 * s, U8 * end)
bool  isXDIGIT_utf8_safe   (U8 * s, U8 * end)
bool  isXDIGIT_uvchr       (UV ch)

okay and that's the last of the isXDIGIT girlies, so the whole classification crew is officially accounted for ๐Ÿ’… every single one, no stragglers, we love to see it.


๐Ÿ› ๏ธ Compiler and Preprocessor information ๐Ÿงฐโœจ

this whole section is about the little breadcrumbs Perl sprinkles around so that other C code can find out what the compiler and preprocessor can actually do. it's giving "extended family of config symbols" and honestly? iconic. let's get into it ๐Ÿซถ

  • CPPLAST โ€” this one is meant to be used right alongside CPPRUN, in exactly the same way that CPPMINUS is used with CPPSTDIN. it holds either - or " " (an empty string, bestie).
  • CPPMINUS โ€” the second part of the string that'll invoke the C preprocessor on standard input and produce stuff on standard output. it's - if CPPSTDIN needs a minus to say "hey, take standard input," and otherwise it's just "" (empty). ๐Ÿ˜Œ
  • CPPRUN โ€” the string that invokes a C preprocessor on standard input and writes to standard output. it has to end with CPPLAST, after every other preprocessor flag has been specified. the big glow-up difference from CPPSTDIN is that this program will never be a pointer to a shell wrapper โ€” like, it'll be empty if there's no preprocessor available directly to the user. and heads up: it can absolutely be different from the preprocessor that was used to compile the C program. ๐Ÿ‘€
  • CPPSTDIN โ€” the first part of the string that invokes the C preprocessor on standard input โ†’ standard output. typical value is something like cc -E or /lib/cpp, but it can also call a wrapper. go check CPPRUN for the rest of the lore.
  • HAS_BUILTIN_ADD_OVERFLOW โ€” if defined, it means the compiler supports __builtin_add_overflow for adding integers with overflow checks. safety girlie behavior ๐Ÿ’–
  • HAS_BUILTIN_CHOOSE_EXPR โ€” can we handle the GCC builtin for compile-time ternary-like expressions? that's the whole question.
  • HAS_BUILTIN_EXPECT โ€” can we handle the GCC builtin for hinting that certain values are more likely? yes ma'am, branch prediction vibes.
  • HAS_BUILTIN_MUL_OVERFLOW โ€” if defined, the compiler supports __builtin_mul_overflow for multiplying integers with overflow checks.
  • HAS_BUILTIN_SUB_OVERFLOW โ€” if defined, the compiler supports __builtin_sub_overflow for subtracting integers with overflow checks.
  • HAS_C99_VARIADIC_MACROS โ€” if defined, the compiler supports C99 variadic macros. fancy.
  • HAS_STATIC_INLINE โ€” if defined, the C compiler supports C99-style static inline. meaning: the function can't be called from another translation unit. no sneaking across files, periodt.
  • HASATTRIBUTE_ALWAYS_INLINE โ€” can we handle the GCC attribute for functions that should always be inlined?
  • HASATTRIBUTE_DEPRECATED โ€” can we handle the GCC attribute for marking deprecated APIs? ๐Ÿ’€ the "don't use this anymore" stamp.
  • HASATTRIBUTE_FORMAT โ€” can we handle the GCC attribute for checking printf-style formats?
  • HASATTRIBUTE_NONNULL โ€” can we handle the GCC attribute for nonnull function parms.
  • HASATTRIBUTE_NORETURN โ€” can we handle the GCC attribute for functions that do not return.
  • HASATTRIBUTE_PURE โ€” can we handle the GCC attribute for pure functions.
  • HASATTRIBUTE_UNUSED โ€” can we handle the GCC attribute for unused variables and arguments.
  • HASATTRIBUTE_VISIBILITY โ€” can we handle the GCC attribute for functions that should have a different visibility.
  • HASATTRIBUTE_WARN_UNUSED_RESULT โ€” can we handle the GCC attribute for warning on unused results. she WILL call you out ๐ŸŒธ
  • MEM_ALIGNBYTES โ€” this symbol holds the number of bytes required to align a double, or a long double when applicable. usual values are 2, 4, and 8. the default is eight, for safety. and for cross-compiling or multiarch support, Configure will set a minimum of 8.
  • PERL_STATIC_INLINE โ€” the best-guess incantation for static inline functions. if HAS_STATIC_INLINE is defined, you get C99-style inline. if HAS_STATIC_INLINE is not defined, you get a plain 'static'. it's always defined to something that gives static linkage. possibilities include:
static inline       (c99)
static __inline__   (gcc -ansi)
static __inline     (MSVC)
static _inline      (older MSVC)
static              (c89 compilers)
  • PERL_THREAD_LOCAL โ€” if defined, this gives a linkage specification for thread-local storage. for example, for a C11 compiler this will be _Thread_local.
โš ๏ธ beware, bestie: some compilers are sensitive about which C language standard they've been told to parse. for example, suncc defaults to C11, so our probe will report that _Thread_local can be used. but if -std=c99 is later added to the compiler flags, then _Thread_local becomes a syntax error. so it's super important for these flags to stay consistent between probing and use. consistency is the whole vibe check here, no cap. ๐Ÿ”ฅ
  • U32_ALIGNMENT_REQUIRED โ€” if defined, it means you must access character data through U32-aligned pointers. non-negotiable. ๐Ÿ™ˆ

๐Ÿ’ซ Compiler directives ๐Ÿ’ซ

okay so these are the little preprocessor besties that do all the meta stuff โ€” assertions, warnings, linkage magic. don't scroll past, some of these have real opinions attached ๐Ÿ’…


  • assert_, __ASSERT_ โ€” these two are literally synonyms, and their whole job is to wrap the libc assert() call inside comma expressions when you're doing macro expansions. but bestie, past a certain point you semi don't want to use them or plain assert โ€” keep reading, we'll get there ๐Ÿ™ˆ

In DEBUGGING builds, each one expands to an assert of its argument, followed by a comma. (yeah that trailing underscore? that's what it's signifying. iconic.)

In non-DEBUGGING builds, each one expands to nothing. ๐Ÿ’€

so the point is you can string a whole bunch of asserts together in a comma expression and it stays syntactically valid in either type of build. slay.

NOTE, however, that using these (or plain assert()) inside a macro is discouraged. why? because people usually use them to validate some of the arguments to that macro โ€” which very likely means those arguments get evaluated more than once during the macro expansion. and if one of those arguments is an expression with side effects, your macro's behavior will differ between DEBUGGING and non-DEBUGGING builds. no cap, that's a bug factory. ๐Ÿšจ

Also, they'd only be necessary on platforms where the libc assert() expands to nothing when you're not in a DEBUGGING build. There should be no such platforms in existence now, because the C89 standard forbids that, and Perl requires at least C99. So you can just use plain assert, write assert(...), assert(...),, and everything will compile (and it'll work, provided none of the arguments to the asserts is an expression with side effects).

These macros are retained for backward compatibility.

Do NOT use __ASSERT_. A name with two leading underscores followed by a capital letter is reserved for the use of the compiler and libc in some contexts in C, and in all contexts in C++. so likeโ€ฆ don't. ๐Ÿ™…โ€โ™€๏ธ
 void       assert_  (bool expr)
 void  Perl_assert_  (bool expr)
 void       __ASSERT_(bool expr)
  • ASSUME โ€” it's like assert(), but it has one specific benefit in a release build: it's a hint to the compiler about a statement of fact in a function-call-free expression, which lets the compiler generate better machine code. โœจ In a debug build, ASSUME(x) is a synonym for assert(x). ASSUME(0) means the control path is unreachable. In a for loop, ASSUME can hint that a loop will run at least X times. It's based off MSVC's __assume intrinsic function โ€” go read its docs for more detail, bestie.
   ASSUME(bool expr)
  • dNOOP โ€” declares nothing. it's typically a placeholder standing in for something that used to declare something. works on compilers that require declarations before any code. so basically the "I'm just here so I don't get fined" macro ๐Ÿซถ
   dNOOP;
  • END_EXTERN_C โ€” when you're not compiling with C++, it expands to nothing. otherwise, it ends a section of code that a START_EXTERN_C already began. closing the group chat, respectfully. ๐Ÿ’–
  • EXTERN_C โ€” when you're not compiling with C++, it expands to nothing. otherwise it's used in a declaration of a function to say that the function should have external C linkage. This is required for things to work for just about all functions with external linkage compiled into perl. A lot of the time you can just wrap all the code that needs this linkage in START_EXTERN_C ... END_EXTERN_C blocks and call it a day.

Example usage:

  EXTERN_C int flock(int fd, int op);
  • LIKELY โ€” returns the input unchanged, but at the same time it gives the compiler a branch prediction hint that this condition is likely to be true. it's giving "trust me on this one" ๐ŸŒธ
   LIKELY(bool expr)
  • NOOP โ€” does nothing. typically used as a placeholder to replace something that used to do something. the ghost of code past ๐Ÿ‘ป
   NOOP;
  • PERL_UNUSED_ARG โ€” used to suppress compiler warnings that a parameter to a function isn't used. this situation can happen, for example, when a parameter is needed under some configuration conditions but not others, so that C preprocessor conditional compilation causes it to only be used sometimes. shhh, it's fine, it's used, I promise ๐Ÿฅฒ
   PERL_UNUSED_ARG(void x);
  • PERL_UNUSED_CONTEXT โ€” used to suppress compiler warnings that the thread context parameter to a function isn't used. this one can happen, e.g., when a C preprocessor conditional compilation causes it to be used just some of the time.
   PERL_UNUSED_CONTEXT;
  • PERL_UNUSED_DECL โ€” tells the compiler that the parameter in the function prototype right before it is not necessarily expected to be used in the function. Not that many compilers actually understand this, so only use it in cases where PERL_UNUSED_ARG can't conveniently be used. it's the backup queen ๐Ÿ‘‘

Example usage:

  Signal_t
  Perl_perly_sighandler(int sig, Siginfo_t *sip PERL_UNUSED_DECL,
                        void *uap PERL_UNUSED_DECL, bool safe)
  • PERL_UNUSED_RESULT โ€” this macro says "yeah, discard the return value of the function call inside me," like:
  PERL_UNUSED_RESULT(foo(a, b))

The main reason this exists is that the combination of gcc -Wunused-result (which is part of -Wall) and the __attribute__((warn_unused_result)) cannot be silenced by casting to void. That causes trouble when system header files use the attribute. ๐Ÿ˜ญ

Use PERL_UNUSED_RESULT sparingly, though โ€” because usually that warning is there for a good reason: you might lose success/failure information, or leak resources, or change resources. big yikes energy.

But sometimes you genuinely just want to ignore the return value โ€” e.g. on codepaths that are soon going to end up in abort, or in "best effort" attempts, or in situations where there is no good way to handle failures. valid.

Sometimes PERL_UNUSED_RESULT might not be the most natural way: another possibility is that you can capture the return value and use PERL_UNUSED_VAR on it instead. ๐ŸŽ€

   PERL_UNUSED_RESULT(void x)
  • PERL_UNUSED_VAR โ€” used to suppress compiler warnings that the variable x isn't used. this situation can arise, for example, when a C preprocessor conditional compilation causes it to be used only some of the time.
   PERL_UNUSED_VAR(void x);
  • START_EXTERN_C โ€” when you're not compiling with C++, it expands to nothing. Otherwise it begins a section of code in which every function will effectively have EXTERN_C applied to it โ€” that is, it'll have external C linkage. The section is ended by an END_EXTERN_C. it's giving group project, but everyone's on the same page this time ๐Ÿซถ
  • STATIC_ASSERT_DECL, STATIC_ASSERT_EXPR, STATIC_ASSERT_STMT โ€” these are like assert(), but for compile time invariants. Which means their argument must be a constant expression that the compiler can verify. That expression can contain anything the compiler knows about, e.g. #define constants, enums, or sizeof (...).

If the expression evaluates to 0, compilation fails. periodt. โŒ

Because they generate no runtime code (i.e. their use is "free"), they're always active, even under non-DEBUGGING builds. obsessed.

STATIC_ASSERT_STMT expands to a statement and is suitable for use inside a function.

STATIC_ASSERT_DECL expands to a declaration and is suitable for use inside a function or at file scope (outside of any function).

STATIC_ASSERT_EXPR expands to an expression and is suitable anywhere an expression is usable. It has some limitations compared to the other two when used on a platform without PERL_USE_GCC_BRACE_GROUPS. On those platforms it expands to an ASSUME(). When called with a compile-time expression, the compiler should optimize out the expression, so that the use of this is "free" โ€” but constness is not enforced. On non-DEBUGGING builds, this will expand to a no-op, so again it's "free", but no checking is done. ๐Ÿ’€

So code that uses this macro can be ported to all platforms without needing to change, and it'll work as well as is possible on that platform. Presumably it'll get compiled at some point before release on a platform where it has parity with the other two forms. ๐Ÿฆ‹

   STATIC_ASSERT_DECL(const_expr)
   STATIC_ASSERT_EXPR(const_expr)
   STATIC_ASSERT_STMT(const_expr)
  • STMT_START, STMT_END โ€” these let you take a series of statements in a macro and use the whole thing as a single statement, like this:
  if (x) STMT_START { ... } STMT_END else ...

Note that you can't return a value out of this construct, and you can't use it as an operand to the comma operator. Those two things really limit how useful it is. ๐Ÿ™ˆ

But! A value could be returned by constructing the API so that a pointer is passed and the macro dereferences this to set the return. If the value can be any of various types, depending on context, you can handle that situation in some cases by adding the type of the return as an extra accompanying parameter:

  #define foo(param, type)  STMT_START {
                               type * param; *param = do_calc; ...
                            } STMT_END

This could be awkward, so consider instead using a C language static inline function. lowkey the better move honestly.

If you do use this construct, it's easy to forget that it's a macro and not a function, and hence fall into traps that might not show up until someone someday writes code which contains names that clash with the ones you chose here, or calls it with a parameter which is an expression with side effects โ€” the consequences of which you didn't think about. ๐Ÿ˜ญ See "Writing safer macros" in perlhacktips for how to avoid these.

  • UNLIKELY โ€” returns the input unchanged, but at the same time it gives a branch prediction hint to the compiler that this condition is likely to be false. the flip side of LIKELY, and equally iconic ๐Ÿ’…
   UNLIKELY(bool expr)

โœจ Compile-time scope hooks โœจ

Hey bestie, these are the BHK (block hook) goodies โ€” the stuff that lets you sneak in hooks when a lexical scope changes at compile time ๐Ÿ’…

  • BhkDISABLE โ€” turns off an entry in this BHK structure by clearing the right flag. which is a preprocessor token that says which entry you're disabling. ๐Ÿšซ
NOTE: BhkDISABLE is experimental and may change or be removed without notice. iykyk, don't build your whole personality on it ๐Ÿ˜ญ
void  BhkDISABLE(BHK *hk, token which)
  • BhkENABLE โ€” re-enables an entry in this BHK structure by setting the right flag. which is a preprocessor token that says which entry to enable. Heads up: this will assert (under -DDEBUGGING) if the entry doesn't contain a valid pointer, so likeโ€ฆ know what you're doing ๐Ÿ™ˆ
NOTE: BhkENABLE is experimental and may change or be removed without notice. โœจ
void  BhkENABLE(BHK *hk, token which)
  • BhkENTRY_set โ€” sets an entry in the BHK structure and sets the flags saying it's valid, so it's giving two-for-one energy ๐Ÿซถ which is a preprocessing token indicating which entry to set. The type of ptr depends on the entry โ€” literally depends on which one you picked, no cap.
NOTE: BhkENTRY_set is experimental and may change or be removed without notice. ๐ŸŒธ
void  BhkENTRY_set(BHK *hk, token which, void *ptr)
  • blockhook_register โ€” registers a set of hooks to be called whenever the Perl lexical scope changes at compile time. Main character behaviour, honestly ๐Ÿ‘‘ See "Compile-time scope hooks" in perlguts.
NOTE: blockhook_register is experimental and may change or be removed without notice. ๐Ÿ’€
void  Perl_blockhook_register(pTHX_ BHK *hk)

๐ŸŒˆ Concurrency ๐ŸŒˆ

Multithreading time, bestie โ€” stay calm, stay hydrated ๐Ÿ’–

  • aTHX
  • aTHX_ โ€” described in perlguts.
  • CPERLscope โ€” DEPRECATED! It is planned to remove CPERLscope from a future release of Perl. Do not use it for new code; remove it from existing code. It's now a no-op, so it literally does nothing. Iconic of it ๐ŸŽ€
void  CPERLscope(void x)
  • dTHR
  • dTHX โ€” described in perlguts.
  • dTHXa โ€” on threaded perls, set pTHX to a; on unthreaded perls, do nothing. Pick your fighter ๐Ÿ˜Œ
  • dTHXoa โ€” now a synonym for dTHXa. Nothing new, just a rebrand slay โœจ
  • dVAR โ€” this is now a synonym for dNOOP: declare nothing. Manifesting emptiness, fr fr ๐Ÿฆ‹
  • GETENV_PRESERVES_OTHER_THREAD โ€” if this symbol is defined, it indicates that the getenv system call doesn't zap the static buffer of getenv() in a different thread. The typical getenv() implementation will return a pointer to the proper position in **environ. But some may instead copy them to a static buffer in getenv(). If there is a per-thread instance of that buffer, or the return points to **environ, then a many-reader/1-writer mutex will work; otherwise an exclusive locking mutex is required to prevent races. โš ๏ธ protection mode: ON.
  • HAS_PTHREAD_ATFORK โ€” if this symbol is defined, it indicates that the pthread_atfork routine is available to setup fork handlers. ๐Ÿด
  • HAS_PTHREAD_ATTR_SETSCOPE โ€” if this symbol is defined, it indicates that the pthread_attr_setscope system call is available to set the contention scope attribute of a thread attribute object. ๐Ÿ”ฅ
  • HAS_PTHREAD_YIELD โ€” if this symbol is defined, it indicates that the pthread_yield routine is available to yield the execution of the current thread. But bestie, sched_yield is preferable to pthread_yield. ๐Ÿ’…
  • HAS_SCHED_YIELD โ€” if this symbol is defined, it indicates that the sched_yield routine is available to yield the execution of the current thread. And again: sched_yield is preferable to pthread_yield. Say it with me ๐Ÿ‘‘
  • I_MACH_CTHREADS โ€” if this symbol is defined, it indicates to the C program that it should include mach/cthreads.h.
#ifdef I_MACH_CTHREADS
    #include <mach_cthreads.h>
#endif
  • I_PTHREAD โ€” if this symbol is defined, it indicates to the C program that it should include pthread.h.
#ifdef I_PTHREAD
    #include <pthread.h>
#endif
  • MULTIPLICITY โ€” if this symbol is defined, it indicates that Perl should be built to use multiplicity. โœจ
  • OLD_PTHREAD_CREATE_JOINABLE โ€” if this symbol is defined, it indicates how to create pthread in joinable (aka undetached) state. NOTE: not defined if pthread.h already has defined PTHREAD_CREATE_JOINABLE (the new version of the constant). If defined, known values are PTHREAD_CREATE_UNDETACHED and __UNDETACHED.
  • OLD_PTHREADS_API โ€” if this symbol is defined, it indicates that Perl should be built to use the old draft POSIX threads API. Vintage era energy ๐Ÿ•ฐ๏ธ
  • PERL_IMPLICIT_CONTEXT
  • PERL_NO_GET_CONTEXT
  • pTHX
  • pTHX_ โ€” described in perlguts.
  • SCHED_YIELD โ€” this symbol defines the way to yield the execution of the current thread. Known ways are sched_yield, pthread_yield, and pthread_yield with NULL. Three options, one vibe ๐ŸŒˆ

๐Ÿ’– COPs and Hint Hashes ๐Ÿ’–

Okay so COP stands for "Current Operation". It is the type used for nextstate and dbstate ops, storing the filename and line number, warning bits, hints bits, feature flags, etc, and a sort of incremental representation of the hints hash for the code that follows. Literally the receipts of your code, bestie ๐Ÿงพ

  • cop_fetch_label โ€” returns the label attached to a cop, and stores its length in bytes into *len. Upon return, *flags will be set to either SVf_UTF8 or 0.

Alternatively, use the macro CopLABEL_len_flags; or if you don't need to know if the label is UTF-8 or not, the macro CopLABEL_len; or if you additionally don't need to know the length, CopLABEL. So many options, all valid, all slay โœจ

NOTE: cop_fetch_label is experimental and may change or be removed without notice. ๐Ÿ™ˆ
const char *       cop_fetch_label(      COP * const cop,
                                         STRLEN *len, U32 *flags)
const char *  Perl_cop_fetch_label(pTHX_ COP * const cop,
                                         STRLEN *len, U32 *flags)
  • cop_hints_exists_pv
  • cop_hints_exists_pvn
  • cop_hints_exists_pvs
  • cop_hints_exists_sv โ€” these look up the hint entry in the cop cop with the key specified by key (and keylen in the pvn form), returning true if a value exists, and false otherwise. vibe check on your hints โœ…

The forms differ in how the key is specified. In all forms, the key is pointed to by key. In the plain pv form, the key is a C language NUL-terminated string. In the pvs form, the key is a C language string literal. In the pvn form, an additional parameter, keylen, specifies the length of the string, which hence, may contain embedded-NUL characters. In the sv form, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. This parameter is omitted from the pvs form, as it is computed automatically at compile time. โšก

The only flag currently used from the flags parameter is COPHH_KEY_UTF8. It is illegal to set this in the sv form. In the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). The sv form uses the underlying SV to determine the UTF-8ness of the octets.

bool  cop_hints_exists_pv (const COP *cop, const char *key,
                           U32 hash, U32 flags)
bool  cop_hints_exists_pvn(const COP *cop, const char *key,
                           STRLEN keylen, U32 hash, U32 flags)
bool  cop_hints_exists_pvs(const COP *cop, "key", U32 flags)
bool  cop_hints_exists_sv (const COP *cop, SV *key, U32 hash,
                           U32 flags)
  • cop_hints_fetch_pv
  • cop_hints_fetch_pvn
  • cop_hints_fetch_pvs
  • cop_hints_fetch_sv โ€” these look up the hint entry in the cop cop with the key specified by key (and keylen in the pvn form), returning that value as a mortal scalar copy, or &PL_sv_placeholder if there is no value associated with the key. No value? You get the placeholder. That's the deal ๐Ÿซถ

The forms differ in how the key is specified. In the plain pv form, the key is a C language NUL-terminated string. In the pvs form, the key is a C language string literal. In the pvn form, an additional parameter, keylen, specifies the length of the string, which hence, may contain embedded-NUL characters. In the sv form, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. This parameter is omitted from the pvs form, as it is computed automatically at compile time.

The only flag currently used from the flags parameter is COPHH_KEY_UTF8. It is illegal to set this in the sv form. In the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). The sv form uses the underlying SV to determine the UTF-8ness of the octets.

SV *  cop_hints_fetch_pv (const COP *cop, const char *key,
                          U32 hash, U32 flags)
SV *  cop_hints_fetch_pvn(const COP *cop, const char *key,
                          STRLEN keylen, U32 hash, U32 flags)
SV *  cop_hints_fetch_pvs(const COP *cop, "key", U32 flags)
SV *  cop_hints_fetch_sv (const COP *cop, SV *key, U32 hash,
                          U32 flags)
  • cop_hints_2hv โ€” generates and returns a standard Perl hash representing the full set of hint entries in the cop cop. flags is currently unused and must be zero. Periodt ๐Ÿ’…
HV *  cop_hints_2hv(const COP *cop, U32 flags)
  • cop_store_label โ€” saves a label into a cop_hints_hash. You need to set flags to SVf_UTF8 for a UTF-8 label. Any other flag is ignored. Bye ๐Ÿ‘‹
NOTE: cop_store_label is experimental and may change or be removed without notice. ๐Ÿ˜ญ
void       cop_store_label(      COP * const cop,
                                 const char *label, STRLEN len,
                                 U32 flags)
void  Perl_cop_store_label(pTHX_ COP * const cop,
                                 const char *label, STRLEN len,
                                 U32 flags)
  • CopFILE โ€” returns the name of the file associated with the COP c ๐Ÿ“
const char *  CopFILE(const COP * c)
  • CopFILE_copy โ€” efficiently copies the cop file name from one COP to another. Wraps the required logic to do a refcounted copy under threads or not. Copy-paste but make it responsible ๐Ÿซถ
void  CopFILE_copy(COP * dst, COP * src)
  • CopFILE_free โ€” frees the file data in a cop. Under the hood this is a refcounting operation. Let it gooo ๐Ÿฆ‹
void  CopFILE_free(COP * c)
  • CopFILE_LEN โ€” returns the length of the file associated with the COP c ๐Ÿ“
const char *  CopFILE_LEN(const COP * c)

CopFILE_set, CopFILE_setn <butterfly emoji โ€” no, must use the allowed emoji> ๐Ÿฆ‹

okay so these two are little besties that both do the same job: they set pv as the name of the file that's chillin' with the COP c. that's it, that's the gig ๐Ÿ’…

the difference? in plain old CopFILE_set, pv is a C language NUL-terminated string โ€” normal vibes. but in CopFILE_setn, len tells you how long pv is, which means pv is allowed to contain embedded NUL characters. yes bestie, NULs inside the string, it's giving chaotic but valid ๐Ÿ˜Œ

void  CopFILE_set (COP * c, const char * pv)
void  CopFILE_setn(COP * c, const char * pv, STRLEN len)

CopFILEAV ๐ŸŒธ

returns the AV that's associated with the COP c, and โ€” and this is the iconic part โ€” it creates it if it's not already there. very "making it happen" energy fr fr โœจ

AV *  CopFILEAV(const COP * c)

CopFILEAVn ๐Ÿงš

same vibe as above BUT it will not manifest an AV out of thin air. if it doesn't already exist, you get NULL. no cap, no auto-creating, just honesty ๐Ÿ’€

AV *  CopFILEAVn(const COP * c)

CopFILEGV ๐ŸŽ€

hands you the GV associated with the COP c. simple. clean. slay.

GV *  CopFILEGV(const COP * c)

CopFILEGV_set ๐Ÿ‘‘

heads up bestie: this one is Available only on unthreaded perls. so if you're on a threaded perl, this is not your moment ๐Ÿ˜ญ

it makes pv the name of the file associated with the COP c โ€” same destiny as the CopFILE_set crew.

void       CopFILEGV_set(      COP *c, GV *gv)
void  Perl_CopFILEGV_set(pTHX_ COP *c, GV *gv)

CopFILESV ๐Ÿ’–

returns the SV associated with the COP c. that's the whole thing, we love a short option description.

SV *  CopFILESV(const COP * c)

cophh_copy ๐Ÿซถ

NOTE: cophh_copy is experimental and may change or be removed without notice. lowkey living on the edge, highkey still using it ๐ŸŒˆ

makes you a complete copy of the cop hints hash cophh, and returns it. fresh copy, new you, iconic behavior.

COPHH *  cophh_copy(COPHH *cophh)

cophh_delete_pv, cophh_delete_pvn, cophh_delete_pvs, cophh_delete_sv ๐Ÿ’…

NOTE: all these forms are experimental and may change or be removed without notice. periodt, proceed with awareness ๐Ÿฆ‹

each one deletes a key plus its associated value from the cop hints hash cophh, and returns a pointer to the modified structure. and here's the tea: the returned pointer is in general not the same as the pointer that was passed in. ๐Ÿ˜ญ

the input cophh is consumed by the function, and the pointer to it must not be subsequently used. gone. used up. do not touch it after, bestie, that pointer is in its rearview era ๐Ÿ’€

if you need both the old structure and the new one? use cophh_copy first. that's the whole point of it.

the forms differ only in how the key is specified:

  • in cophh_delete_pv, key is a C language NUL-terminated string.
  • in cophh_delete_pvs, key is a C language string literal, enclosed in double quotes.
  • in cophh_delete_pvn, key points to the first byte of the string specifying the key, and an additional parameter, keylen, specifies its length in bytes. hence, key may contain embedded-NUL characters. (the NUL girls are back ๐Ÿซถ)
  • in cophh_delete_sv, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. this parameter is omitted from cophh_delete_pvs, which behaves as if zero had been specified.

the only flag currently used from the flags parameter is COPHH_KEY_UTF8. it is illegal to set this in the sv form. (illegal!! ๐Ÿšจ). in the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). the sv form uses the underlying SV to determine the UTF-8ness of the octets โ€” it just knows.

COPHH *  cophh_delete_pv (COPHH *cophh, const char *key,
                          U32 hash, U32 flags)
COPHH *  cophh_delete_pvn(COPHH *cophh, const char *key,
                          STRLEN keylen, U32 hash, U32 flags)
COPHH *  cophh_delete_pvs(COPHH *cophh, "key", U32 flags)
COPHH *  cophh_delete_sv (COPHH *cophh, SV *key, U32 hash,
                          U32 flags)

cophh_exists_pv, cophh_exists_pvn, cophh_exists_pvs, cophh_exists_sv ๐Ÿ”

NOTE: all these forms are experimental and may change or be removed without notice. we stay cautious, we stay cute ๐ŸŒธ

each one looks up the entry in the cop hints hash cophh with the specified key, and returns true if a value exists, and false otherwise. a simple yes/no situation, we love clarity.

you should probably be instead using the wrappers for these functions that take a COP* โ€” see cop_hints_exists_pv. like, that's the move, that's the recommendation ๐Ÿ’–

the forms here differ only in how the key is specified:

  • in cophh_exists_pv, key is a C language NUL-terminated string.
  • in cophh_exists_pvs, key is a C language string literal, enclosed in double quotes.
  • in cophh_exists_pvn, key points to the first byte of the string specifying the key, and an additional parameter, keylen, specifies its length in bytes. hence, key may contain embedded-NUL characters.
  • in cophh_exists_sv, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. this parameter is omitted from cophh_exists_pvs, which behaves as if zero had been specified.

the only flag currently used from the flags parameter is COPHH_KEY_UTF8. it is illegal to set this in cophh_exists_sv. in the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). the sv form uses the underlying SV to determine the UTF-8ness of the octets.

bool  cophh_exists_pv (const COPHH *cophh, const char *key,
                       U32 hash, U32 flags)
bool  cophh_exists_pvn(const COPHH *cophh, const char *key,
                       STRLEN keylen, U32 hash, U32 flags)
bool  cophh_exists_pvs(const COPHH *cophh, "key", U32 flags)
bool  cophh_exists_sv (const COPHH *cophh, SV *key, U32 hash,
                       U32 flags)

cophh_fetch_pv, cophh_fetch_pvn, cophh_fetch_pvs, cophh_fetch_sv โœจ

NOTE: all these forms are experimental and may change or be removed without notice. ๐Ÿ’…

each one looks up the entry in the cop hints hash cophh with the specified key, and returns that value as a mortal scalar copy โ€” or, if there is no value associated with the key, you get &PL_sv_placeholder. so you're never left empty-handed, just sometimes handed a placeholder. it's giving "here's something so you don't cry" ๐Ÿ˜ญ

you should probably be instead using the wrappers for these functions that take a COP* โ€” see cop_hints_fetch_pv. bestie, take the shortcut.

the forms here differ only in how the key is specified:

  • in cophh_fetch_pv, key is a C language NUL-terminated string.
  • in cophh_fetch_pvs, key is a C language string literal, enclosed in double quotes.
  • in cophh_fetch_pvn, key points to the first byte of the string specifying the key, and an additional parameter, keylen, specifies its length in bytes. hence, key may contain embedded-NUL characters.
  • in cophh_fetch_sv, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. this parameter is omitted from cophh_fetch_pvs, which behaves as if zero had been specified.

the only flag currently used from the flags parameter is COPHH_KEY_UTF8. it is illegal to set this in cophh_fetch_sv. in the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). the sv form uses the underlying SV to determine the UTF-8ness of the octets.

SV *  cophh_fetch_pv (const COPHH *cophh, const char *key,
                      U32 hash, U32 flags)
SV *  cophh_fetch_pvn(const COPHH *cophh, const char *key,
                      STRLEN keylen, U32 hash, U32 flags)
SV *  cophh_fetch_pvs(const COPHH *cophh, "key", U32 flags)
SV *  cophh_fetch_sv (const COPHH *cophh, SV *key, U32 hash,
                      U32 flags)

cophh_free ๐Ÿฆ‹

NOTE: cophh_free is experimental and may change or be removed without notice. ๐ŸŒˆ

discards the cop hints hash cophh, freeing all resources associated with it. it's a goodbye, it's a cleanup, it's a slay. do not use it after. please. for me. ๐Ÿซถ

void  cophh_free(COPHH *cophh)

cophh_new_empty ๐ŸŽ€

NOTE: cophh_new_empty is experimental and may change or be removed without notice. โœจ

generates and returns a fresh cop hints hash containing no entries. brand new, empty, blank-slate main character energy. no notes, no history, just vibes. ๐Ÿ’–

COPHH *  cophh_new_empty()

cophh_store_pv, cophh_store_pvn, cophh_store_pvs, cophh_store_sv ๐Ÿ“

NOTE: all these forms are experimental and may change or be removed without notice. ๐Ÿ’…

each one stores a value associated with the specified key. the value gets stored into the cop hints hash cophh, and you get back a pointer to the modified structure returned. and once again, bestie, the tea: the returned pointer is in general not the same as the pointer that was passed in. ๐Ÿ˜ญ

the input cophh is consumed by the function, and the pointer to it must not be subsequently used. use cophh_copy first if you need both structures โ€” yes this is the third time we've said it, it matters, write it down ๐Ÿ“

value is the scalar value to store for this key. value is copied by these functions, which thus do not take ownership of any reference to it โ€” so later changes to the scalar will not be reflected in the value visible in cophh. complex types of scalar will not be stored with referential integrity, but will be coerced to strings. (they get stringified, it is what it is ๐Ÿ™ˆ)

the forms differ only in how the key is specified:

  • in cophh_store_pv, key is a C language NUL-terminated string.
  • in cophh_store_pvs, key is a C language string literal, enclosed in double quotes.
  • in cophh_store_pvn, key points to the first byte of the string specifying the key, and an additional parameter, keylen, specifies its length in bytes. hence, key may contain embedded-NUL characters.
  • in cophh_store_sv, *key is an SV, and the key is the PV extracted from that, using SvPV_const.

hash is a precomputed hash of the key string, or zero if it has not been precomputed. this parameter is omitted from cophh_store_pvs, which behaves as if zero had been specified.

the only flag currently used from the flags parameter is COPHH_KEY_UTF8. it is illegal to set this in the sv form. in the pv* forms, it specifies whether the key octets are interpreted as UTF-8 (if set) or as Latin-1 (if cleared). the sv form uses the underlying SV to determine the UTF-8ness of the octets.

COPHH *  cophh_store_pv (COPHH *cophh, const char *key, U32 hash,
                         SV *value, U32 flags)
COPHH *  cophh_store_pvn(COPHH *cophh, const char *key,
                         STRLEN keylen, U32 hash, SV *value,
                         U32 flags)
COPHH *  cophh_store_pvs(COPHH *cophh, "key", SV *value,
                         U32 flags)
COPHH *  cophh_store_sv (COPHH *cophh, SV *key, U32 hash,
                         SV *value, U32 flags)

cophh_2hv ๐Ÿ”ฅ

NOTE: cophh_2hv is experimental and may change or be removed without notice.

Generates and returns a standard Perl hash that holds the full set of key/value pairs from the cop hints hash cophh. And flags? bestie, flags is currently unused and must be zero. no notes.

HV *  cophh_2hv(const COPHH *cophh, U32 flags)

CopLABEL, CopLABEL_len, CopLABEL_len_flags

These three hand you the label that's attached to a cop ๐Ÿ’–

CopLABEL_len and CopLABEL_len_flags also stash the number of bytes that make up the returned label into *len.

And CopLABEL_len_flags goes one step further โ€” it tells you about the UTF-8ness of the returned label by setting *flags to either 0 or SVf_UTF8.

const char *  CopLABEL          (COP *const cop)
const char *  CopLABEL_len      (COP *const cop, STRLEN *len)
const char *  CopLABEL_len_flags(COP *const cop, STRLEN *len,
                                 U32 *flags)

CopLINE

Returns the line number, in the source code, that goes with the COP c โญ

line_t  CopLINE(const COP * c)

CopSTASH

Returns the stash chillin' with c.

HV *  CopSTASH(const COP * c)

CopSTASH_eq

Returns a boolean answering the question: is hv the stash that belongs to c, or not? ๐Ÿ’…

bool  CopSTASH_eq(const COP * c, const HV * hv)

CopSTASH_set

Sets the stash associated with c to hv.

bool  CopSTASH_set(COP * c, HV * hv)

CopSTASHPV

Returns the package name of the stash hanging out with c โ€” or NULL if there's no associated stash ๐Ÿ™ˆ

char *  CopSTASHPV(const COP * c)

CopSTASHPV_set

Sets the package name of the stash associated with c to the NUL-terminated C string p, creating the package if necessary.

void  CopSTASHPV_set(COP * c, const char * pv)

PERL_SI

Use this typedef when you need to declare variables that are gonna hold a struct stackinfo. that's it, that's the job ๐ŸŽ€

PL_curcop

The currently active COP (control op) โ€” roughly speaking, it represents the current statement in the source ๐Ÿ”ฅ

On threaded perls, every thread has its own independent copy of this variable, and each one gets initialized at creation time with the current value of the creating thread's copy.

COP*  PL_curcop

RCPV_LEN

Returns the length of a pv that was created with rcpv_new() โœจ Heads up though: this reflects the length of the string from the caller's point of view โ€” it does not include the mandatory null that rcpv_new() always injects at the end of the string.

And listen: no checks are performed to make sure pv was actually allocated with rcpv_new(). It is the caller's responsibility to make sure that's the case, fr fr.
RCPV *  RCPV_LEN(char *pv)

RCPV_REFCNT_dec

Decrements the refcount for a char * pointer that was created with a call to rcpv_new(). Same thing as calling rcpv_free() ๐Ÿ’€

Same warning as above: no checks confirm pv came from rcpv_new(). Caller's responsibility, always.
RCPV *  RCPV_REFCNT_dec(char *pv)

RCPV_REFCNT_inc

Increments the refcount for a char * pointer created with a call to rcpv_new(). Same as calling rcpv_copy() ๐Ÿซถ

And yeah โ€” no checks that pv was actually allocated with rcpv_new(). That's on you, bestie.
RCPV *  RCPV_REFCNT_inc(char *pv)

RCPV_REFCOUNT

Returns the refcount for a pv created with rcpv_new() ๐ŸŒธ

No checks are performed to ensure pv was actually allocated with rcpv_new(). It is the caller's responsibility to ensure that this is the case.
RCPV *  RCPV_REFCOUNT(char *pv)

RCPVx

Returns the RCPV structure (struct rcpv) for a refcounted string pv that was created with rcpv_new().

You already know: no checks that pv came from rcpv_new(). Caller's responsibility, periodt.
RCPV *  RCPVx(char *pv)

๐ŸŒˆ Custom Operators ๐ŸŒˆ

custom_op_register

Register a custom op ๐Ÿ’… See "Custom Operators" in perlguts.

void  Perl_custom_op_register(pTHX_ Perl_ppaddr_t ppaddr,
                                    const XOP *xop)

Perl_custom_op_xop

Return the XOP structure for a given custom op. This macro is meant to be considered internal to OP_NAME and the other access macros โ€” so use those instead, okay? ๐Ÿ‘‘

Also, this macro does call a function. And fun fact: prior to 5.19.6, it was implemented as a function.

const XOP *  Perl_custom_op_xop(const OP *o)

XopDISABLE

Temporarily disables a member of the XOP by clearing the appropriate flag.

void  XopDISABLE(XOP *xop, token which)

XopENABLE

Reenables a member of the XOP that's been disabled โœจ

void  XopENABLE(XOP *xop, token which)

XopENTRY

Return a member of the XOP structure. which is a cpp token saying which entry to return. If the member isn't set, this returns a default value. The return type depends on which ๐Ÿ˜ญ

Careful: this macro evaluates its arguments more than once. And if you're using Perl_custom_op_xop to grab an XOP * from an OP *, use the more efficient XopENTRYCUSTOM instead ๐Ÿ’–
XopENTRY(XOP *xop, token which)

XopENTRY_set

Sets a member of the XOP structure to value. which is a cpp token indicating which entry to set. See "Custom Operators" in perlguts for all the details about the available members and how they're used.

This macro evaluates its argument more than once, ngl.
void  XopENTRY_set(XOP *xop, token which, value)

XopENTRYCUSTOM

Exactly like XopENTRY(XopENTRY(Perl_custom_op_xop(aTHX_ o), which) but more efficient ๐Ÿ”ฅ The which parameter is identical to XopENTRY.

XopENTRYCUSTOM(const OP *o, token which)

XopFLAGS

Return the XOP's flags.

U32  XopFLAGS(XOP *xop)

๐Ÿ‘‘ CV Handling ๐Ÿ‘‘

This section documents functions for manipulating CVs, which are code-values โ€” meaning, subroutines ๐ŸŽ€ For more info, see perlguts.

caller_cx

The XSUB-writer's equivalent of caller(). You can interrogate the returned PERL_CONTEXT structure to find all the info that caller hands back to Perl ๐Ÿ’œ

Note that XSUBs don't get a stack frame, so caller_cx(0, NULL) will return info for the immediately-surrounding Perl code.

This function skips over the automatic calls to &DB::sub that get made on behalf of the debugger. If the stack frame you requested was a sub called by DB::sub, the return value will be the frame for the call to DB::sub, since that's the one with the correct line number / etc. for the call site. If dbcxp is non-NULL, it gets set to a pointer to the frame for the sub call itself โœจ

const PERL_CONTEXT *       caller_cx(I32 level,
                                           const PERL_CONTEXT **dbcxp)
const PERL_CONTEXT *  Perl_caller_cx(pTHX_ I32 level,
                                           const PERL_CONTEXT **dbcxp)

CvDEPTH

Returns the recursion level of the CV sv. So >= 2 means we are in a recursive call ๐Ÿ”

I32 *       CvDEPTH(const CV * const sv)
I32 *  Perl_CvDEPTH(const CV * const sv)

CvGV

Returns the GV associated with the CV sv, reifying it if necessary.

GV *       CvGV(      CV *sv)
GV *  Perl_CvGV(pTHX_ CV *sv)

CvREFCNT_inc, CvREFCNT_inc_simple, CvREFCNT_inc_simple_NN

All three of these increment the reference count of the given SV, which must be a CV ๐Ÿ’… They're useful when you're assigning the result into a typed pointer, since they save you from having to cast the result to the appropriate type ๐Ÿซถ

CV *  CvREFCNT_inc          (CV *cv)
CV *  CvREFCNT_inc_simple   (CV *cv)
CV *  CvREFCNT_inc_simple_NN(CV *cv)

CvSTASH

Returns the stash of the CV. A stash is the symbol table hash, and it holds the package-scoped variables in the package where the subroutine was defined. For more info, see perlguts ๐Ÿ’–

This also has a special use with XS AUTOLOAD subs โ€” see "Autoloading with XSUBs" in perlguts.

HV*  CvSTASH(CV* cv)

find_runcv

Locate the CV that corresponds to the currently executing sub or eval ๐Ÿฆ‹

If db_seqp is non_null, skip CVs that live in the DB package and populate *db_seqp with the cop sequence number from the point that the DB:: code was entered. (This is what lets debuggers eval in the scope of the breakpoint instead of in the scope of the debugger itself โ€” iconic tbh.)

CV *       find_runcv(      U32 *db_seqp)
CV *  Perl_find_runcv(pTHX_ U32 *db_seqp)

get_cv, get_cvn_flags, get_cvs

These return the CV of the specified Perl subroutine โญ flags get passed to gv_fetchpvn_flags. If GV_ADD is set and the Perl subroutine doesn't exist, then it will be declared (which does the same thing as saying sub name;). If GV_ADD is not set and the subroutine doesn't exist, then NULL is returned.

The forms differ only in how the subroutine is specified.. With get_cvs, the name is a literal C string, wrapped in double quotes. With get_cv, the name comes from the name parameter, which must be a NUL-terminated C string. With get_cvn_flags, the name also comes from the name parameter, but it's a Perl string (so it may contain embedded NUL bytes), and its length in bytes lives in the len parameter.

NOTE: the perl_get_cv() form is deprecated. don't be that girl ๐Ÿ™ˆ
CV *       get_cv       (      const char *name, I32 flags)
CV *  Perl_get_cv       (pTHX_ const char *name, I32 flags)
CV *       get_cvn_flags(      const char *name, STRLEN len,
                               I32 flags)
CV *  Perl_get_cvn_flags(pTHX_ const char *name, STRLEN len,
                               I32 flags)
CV *       get_cvs      (      "name", I32 flags)

Nullcv

DEPRECATED! It is planned to remove Nullcv from a future release of Perl. Do not use it for new code; remove it from existing code. fr fr, this one's on the way out ๐Ÿ’€

Null CV pointer.

(deprecated - use (CV *)NULL instead)

av_dump

Dumps everything inside an AV straight to the STDERR filehandle ๐Ÿ’– It's giving Devel::Peek on an arrayref, except it does not expect an RV wrapper, so no extra layer of vibes. Dumps contents to a depth of 3 levels deep.

void       av_dump(      AV *av)
void  Perl_av_dump(pTHX_ AV *av)

deb, deb_nocontext, vdeb

When perl is compiled with -DDEBUGGING, each of these prints to STDERR the info you handed it in the arguments, prefaced by the name of the file holding the Perl script that caused the call, plus the line number inside that file. โœจ

If the v (verbose) debugging option is in effect, the process id gets printed too.

deb and deb_nocontext behave identically when called from outside the perl core, unless PERL_WANT_VARARGS has been explicitly #defined. Once it has been โ€” or when you're calling from inside the core โ€” they differ only in that deb requires the thread context (aTHX) to be available. ๐Ÿซถ

vdeb is the same as deb except args is a pointer to a va_list.

void       deb          (      const char *pat, ...)
void  Perl_deb          (pTHX_ const char *pat, ...)
void       deb_nocontext(      const char *pat, ...)
void  Perl_deb_nocontext(      const char *pat, ...)
void       vdeb         (      const char *pat, va_list *args)
void  Perl_vdeb         (pTHX_ const char *pat, va_list *args)

debstack

Dump the current stack ๐Ÿ’… Like, show me the whole stack bestie.

I32       debstack()
I32  Perl_debstack(pTHX)

DEBUG_U, DEBUG_Uv, DEBUG_U_TEST, DEBUG_Uv_TEST

Described in perlguts. ๐Ÿ“–

      DEBUG_U      (const char * format, ...)
      DEBUG_Uv     (const char * format, ...)
bool  DEBUG_U_TEST
bool  DEBUG_Uv_TEST

dump_all

Dumps the entire optree of the current program, starting at PL_main_root, to STDERR. ๐ŸŒˆ It also dumps the optrees for all visible subroutines in PL_defstash. So much tree, so much dumping, iconic.

void       dump_all()
void  Perl_dump_all(pTHX)

dump_c_backtrace

Dumps the C backtrace to the given fp ๐Ÿ˜Œ

Returns true if a backtrace could actually be retrieved, false if not.

bool       dump_c_backtrace(      PerlIO *fp, int max_depth,
                                  int skip)
bool  Perl_dump_c_backtrace(pTHX_ PerlIO *fp, int max_depth,
                                  int skip)

dump_eval

Described in perlguts. ๐Ÿ“–

void       dump_eval()
void  Perl_dump_eval(pTHX)

dump_form

Dumps the contents of the format contained in the GV gv to STDERR, or a message that one doesn't exist. ๐Ÿ’€ (helpful queen behavior honestly)

void       dump_form(      const GV *gv)
void  Perl_dump_form(pTHX_ const GV *gv)

dump_packsubs

Dumps the optrees for all visible subroutines in stash. ๐ŸŒธ

void       dump_packsubs(      const HV *stash)
void  Perl_dump_packsubs(pTHX_ const HV *stash)

dump_sub

Described in perlguts. ๐Ÿ“–

void       dump_sub(      const GV *gv)
void  Perl_dump_sub(pTHX_ const GV *gv)

get_c_backtrace_dump

Returns a SV containing a dump of depth frames of the call stack, skipping the skip innermost ones. A depth of 20 is usually enough, fr fr. ๐Ÿซถ

The appended output looks like this:

...
1   10e004812:0082   Perl_croak   util.c:1716    /usr/bin/perl
2   10df8d6d2:1d72   perl_parse   perl.c:3975    /usr/bin/perl
...

The fields are tab-separated. The first column is the depth (zero being the innermost non-skipped frame). In the hex:offset, the hex is where the program counter was in S_parse_body, and the :offset (might be missing) tells how much inside the S_parse_body the program counter was. ๐Ÿ‘‘

The util.c:1716 is the source code file and line number.

The /usr/bin/perl is obvious (hopefully). ๐Ÿ™ˆ

Unknowns are -. And bestie, unknowns can happen unfortunately quite easily: if the platform doesn't support retrieving the information; if the binary is missing the debug information; if the optimizer has transformed the code by for example inlining. ๐Ÿ˜ญ

SV *       get_c_backtrace_dump(      int max_depth, int skip)
SV *  Perl_get_c_backtrace_dump(pTHX_ int max_depth, int skip)

gv_dump

Dump the name โ€” and, if they differ, the effective name โ€” of the GV gv to STDERR. โœจ

void       gv_dump(      GV *gv)
void  Perl_gv_dump(pTHX_ GV *gv)

HAS_BACKTRACE

This symbol, if defined, indicates that the backtrace() routine is available to get a stack trace. ๐Ÿ”ฅ The execinfo.h header must be included to use this routine.


hv_dump

Dumps the contents of an HV to the STDERR filehandle ๐Ÿ’œ Just like using Devel::Peek on a hashref, except it does not expect an RV wrapper. Dumps contents to a depth of 3 levels deep.

void       hv_dump(      HV *hv)
void  Perl_hv_dump(pTHX_ HV *hv)

magic_dump

Dumps the contents of the MAGIC mg to STDERR. ๐ŸŽ€

void       magic_dump(      const MAGIC *mg)
void  Perl_magic_dump(pTHX_ const MAGIC *mg)

op_class

Given an op, figure out what type of struct it's been allocated as. Returns one of the OPclass enums, such as OPclass_LISTOP. ๐Ÿงš

OPclass       op_class(      const OP *o)
OPclass  Perl_op_class(pTHX_ const OP *o)

op_dump

Dumps the optree starting at OP o to STDERR. ๐Ÿ’…

void       op_dump(      const OP *o)
void  Perl_op_dump(pTHX_ const OP *o)

opdump_printf

Prints formatted output to STDERR according to the pattern and subsequent arguments, in the style of printf() et.al. โœจ This should only be called by a function invoked by the xop_dump field of a custom operator, where the ctx opaque structure pointer should be passed in from the argument given to the xop_dump callback.

This function handles indentation after linefeeds, so the message strings you pass in should not account for it themselves. Multiple lines may be passed to this function at once, or a single line may be split across multiple calls. ๐ŸŒธ

void       opdump_printf(      struct Perl_OpDumpContext *ctx,
                               const char *pat, ...)
void  Perl_opdump_printf(pTHX_ struct Perl_OpDumpContext *ctx,
                               const char *pat, ...)

PERL_POISON

Described in perlhacktips. ๐Ÿ“–


PL_DBsub

When Perl is run in debugging mode, with the -d switch, this GV contains the SV which holds the name of the sub being debugged. ๐Ÿ‘€ This is the C variable which corresponds to Perl's $DB::sub variable. See "PL_DBsingle" in perlintern>.

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy. ๐Ÿงต

GV *  PL_DBsub

PL_op

Described in perlhacktips. ๐Ÿ“–


PL_runops

Described in perlguts. ๐Ÿ“–

runops_proc_t  PL_runops

PL_sv_serial

Described in perlhacktips. ๐Ÿ“–


pmop_dump

Dump an OP that is related to Pattern Matching, such as s/foo/bar/ โ€” these require special handling. ๐Ÿ”ฅ

void       pmop_dump(      PMOP *pm)
void  Perl_pmop_dump(pTHX_ PMOP *pm)

PoisonFree, Poison

These each call PoisonWith(0xEF) for catching access to freed memory. ๐Ÿ’€ the freed memory said no access

void  PoisonFree(void* dest, int nitems, type)
void  Poison    (void* dest, int nitems, type)

PoisonNew

PoisonWith(0xAB) for catching access to allocated but uninitialized memory. ๐Ÿ™ˆ

void  PoisonNew(void* dest, int nitems, type)

PoisonWith

Fill up memory with a byte pattern (a byte repeated over and over again) that hopefully catches attempts to access uninitialized memory. โœจ hopefully bestie, hopefully

void  PoisonWith(void* dest, int nitems, type, U8 byte)

sv_dump, sv_dump_depth

These each dump the contents of an SV to the STDERR filehandle. ๐Ÿ’–

sv_dump_depth is a more flexible variant of sv_dump, taking an extra parameter giving the maximum depth to dump.

sv_dump is limited to dumping items to a depth of 4 if the item is an SvROK, and dumping only the top level item otherwise. ๐Ÿ‘‘ Which means it will not dump the contents of an AV * or HV *. For that, use av_dump or hv_dump.

For an example of its output, see Devel::Peek.

In contrast, sv_dump_depth can be used on any SV derived type (GV, HV, AV) with an appropriate cast:

HV *hv = ...;
sv_dump_depth((SV*)hv, 2);

would dump the hv, its keys and its values, but would not recurse into any RV values. ๐Ÿฆ‹

void       sv_dump      (      SV *sv)
void  Perl_sv_dump      (pTHX_ SV *sv)
void       sv_dump_depth(      SV *sv, I32 depth)
void  Perl_sv_dump_depth(pTHX_ SV *sv, I32 depth)

vdeb*

Described under deb ๐Ÿ‘† go look bestie


๐ŸŒˆ DECLARATION AND INITIALIZATION OF GLOBALS ๐ŸŒˆ

There are currently no public API items in Declaration and Initialization of Globals ๐Ÿ’€ not a single one bestie, we stay empty

โœจ Display functions โœจ

๐ŸŽ€ form, form_nocontext, vform

Okay bestie, these three each take a sprintf-style format pattern plus regular old conventional (non-SV) arguments, and hand you back the formatted string. ๐Ÿ’–

(char *) form(const char* pat, ...)

You can drop them anywhere a string (char *) is required:

char * s = form_nocontext("%d.%d", major, minor);

The way that they each return a temporary that's gonna get freed soon, automatically, by the system โ€” at the exact same moment the SVs that sv_2mortal is operating on get freed. ๐Ÿซถ

So use the result immediately, or copy it somewhere stable if you need it hanging around longer. And lowkey this is in direct opposition to the old (wrong!) docs that claimed the return value was a single per-thread buffer. That was (and still is) only actually true when these get called during global destruction. ๐Ÿ™ˆ

form and form_nocontext behave identically when called from outside the perl core โ€” unless PERL_WANT_VARARGS has been explicitly #defined. When it has been, or when you're calling from inside the core, the only diff between them is that form requires the thread context (aTHX) to be available.

vform is the same as form except the arguments are a va_list. It genuinely does need a thread context parameter, but that gets supplied automatically when you call it without the Perl_ prefix. โœจ

 char *       form          (      const char *pat, ...)
 char *  Perl_form          (pTHX_ const char *pat, ...)
 char *       form_nocontext(      const char *pat, ...)
 char *  Perl_form_nocontext(      const char *pat, ...)
 char *       vform         (      const char *pat, va_list *args)
 char *  Perl_vform         (pTHX_ const char *pat, va_list *args)

๐Ÿ“ mess, mess_nocontext, vmess

Each of these takes a sprintf-style format pattern and an argument list, and uses them to generate a string message. If the message doesn't end with a newline, then it gets extended with some indication of the current location in the code โ€” exactly as described for mess_sv. ๐Ÿ’…

mess and mess_nocontext behave identically when called from outside the perl core unless PERL_WANT_VARARGS has been explicitly #defined. When it has, or when you're inside the core, they differ only in that mess requires the thread context (aTHX) to be available. No cap.

vmess is the same as mess except the arguments are a <va_list>. It needs a thread context parameter only when called with the Perl_ prefix.

Normally the resulting message comes back in a brand new mortal SV. But during global destruction a single SV may be shared between uses of this function. ๐Ÿ’€

 SV *       mess          (      const char *pat, ...)
 SV *  Perl_mess          (pTHX_ const char *pat, ...)
 SV *       mess_nocontext(      const char *pat, ...)
 SV *  Perl_mess_nocontext(      const char *pat, ...)
 SV *       vmess         (      const char *pat, va_list *args)
 SV *  Perl_vmess         (pTHX_ const char *pat, va_list *args)

๐Ÿฆ‹ mess_sv

Expands a message meant for the user so it includes an indication of the current location in the code โ€” but only if the message doesn't already look complete. ๐Ÿ‘‘

basemsg is the initial message or object. If it's a reference, it gets used as-is and that becomes the result of this function. Otherwise it's used as a string, and if it already ends with a newline it's taken to be complete, and the result of this function is literally that same string. But if the message does not end with a newline, then a segment like at foo.pl line 37 gets appended, plus possibly other clauses indicating the current state of execution. And the resulting message ends with a dot and a newline. Periodt. โœจ

Normally the resulting message is returned in a new mortal SV. During global destruction, a single SV may be shared between uses of this function. And if consume is true, then the function is permitted (but not required, bestie, no pressure) to modify and return basemsg instead of allocating a new SV.

 SV *       mess_sv(      SV *basemsg, bool consume)
 SV *  Perl_mess_sv(pTHX_ SV *basemsg, bool consume)

๐ŸŒธ pv_display

Similar to

pv_escape(dsv,pv,cur,pvlim,PERL_PV_ESCAPE_QUOTE);

except that an extra "\0" gets appended to the string when len > cur and pv[cur] is "\0". ๐ŸŽ€

Heads up: the final string may be up to 7 chars longer than pvlim. Iconic of it honestly.
 char *       pv_display(      SV *dsv, const char *pv,
                               STRLEN cur, STRLEN len,
                               STRLEN pvlim)
 char *  Perl_pv_display(pTHX_ SV *dsv, const char *pv,
                               STRLEN cur, STRLEN len,
                               STRLEN pvlim)

๐Ÿ’œ pv_escape

Escapes at most the first count chars of pv and drops the results into dsv, in such a way that the size of the escaped string won't exceed max chars and won't contain any incomplete escape sequences. The number of bytes escaped gets returned in the STRLEN *escaped parameter โ€” if it's not null, that is. And when the dsv parameter is null, no escaping actually happens, but it still calculates the number of bytes that would have been escaped if it weren't null. Main character behavior fr fr. ๐Ÿ‘‘

If flags contains PERL_PV_ESCAPE_QUOTE then any double quotes in the string get escaped too.

Normally the SV gets cleared before the escaped string is prepared, but when PERL_PV_ESCAPE_NOCLEAR is set, that will not happen.

If PERL_PV_ESCAPE_UNI is set then the input string is treated as UTF-8. If PERL_PV_ESCAPE_UNI_DETECT is set then the input string is scanned using is_utf8_string() to figure out if it's UTF-8. ๐Ÿฆ‹

If PERL_PV_ESCAPE_ALL is set then all input chars get output using "\x01F1" style escapes. Otherwise, if PERL_PV_ESCAPE_NONASCII is set, only non-ASCII chars get escaped using this style. Otherwise, only chars above 255 get escaped that way; other non-printable chars use octal or common escaped patterns like "\n". Otherwise, if PERL_PV_ESCAPE_NOBACKSLASH then all chars below 255 are treated as printable and get output as literals. And PERL_PV_ESCAPE_NON_WC modifies the previous rules to cause word chars โ€” unicode or otherwise โ€” to be output as literals. Note that this uses the unicode rules for deciding on word characters. ๐Ÿ’…

If PERL_PV_ESCAPE_FIRSTCHAR is set then only the first char of the string gets escaped, no matter what max says. If the output is going to be in hex, then it gets returned as a plain hex sequence. So the output will be either a single char, an octal escape sequence, a special escape like "\n", or a hex value.

If PERL_PV_ESCAPE_RE is set then the escape char used will be a "%" and not a "\\". This is because regexes very often contain backslashed sequences, whereas "%" isn't a particularly common character in patterns. iykyk. ๐Ÿงš

Returns a pointer to the escaped text as held by dsv.

 char *       pv_escape(      SV *dsv, char const * const str,
                              const STRLEN count, STRLEN max,
                              STRLEN * const escaped, U32 flags)
 char *  Perl_pv_escape(pTHX_ SV *dsv, char const * const str,
                              const STRLEN count, STRLEN max,
                              STRLEN * const escaped, U32 flags)

โญ pv_pretty

Converts a string into something presentable, handling escaping via pv_escape() and supporting quoting and ellipses. It's giving glow-up. โœจ

If the PERL_PV_PRETTY_QUOTE flag is set then the result will be double quoted, with any double quotes in the string escaped. Otherwise, if the PERL_PV_PRETTY_LTGT flag is set, then the result gets wrapped in angle brackets.

If the PERL_PV_PRETTY_ELLIPSES flag is set and not all characters in the string were output, then an ellipsis ... gets appended to the string. Note that this happens AFTER it has been quoted. ๐ŸŽ€

If start_color is non-null then it gets inserted after the opening quote (if there is one) but before the escaped text. If end_color is non-null then it gets inserted after the escaped text but before any quotes or ellipses.

Returns a pointer to the prettified text as held by dsv.

 char *       pv_pretty(      SV *dsv, char const * const str,
                              const STRLEN count,
                              const STRLEN max,
                              char const * const start_color,
                              char const * const end_color,
                              const U32 flags)
 char *  Perl_pv_pretty(pTHX_ SV *dsv, char const * const str,
                              const STRLEN count,
                              const STRLEN max,
                              char const * const start_color,
                              char const * const end_color,
                              const U32 flags)

๐ŸŒˆ vform*

Described under form (scroll up bestie, it's all there ๐Ÿ’–)

๐ŸŒˆ vmess*

Described under mess (yeah, same deal, go look ๐Ÿ‘€)


๐ŸŒธ Embedding, Threads, and Interpreter Cloning ๐ŸŒธ

๐Ÿซถ call_atexit

Adds a function fn to the list of functions to be called at global destruction. ptr gets passed as an argument to fn; it can point to a struct so you can pass literally anything you want. Obsessed with the flexibility ngl. ๐Ÿ’…

Note that under threads, fn may run multiple times. This is because the list gets executed each time the current thread, or any thread descending from it, terminates.
 void       call_atexit(      ATEXIT_t fn, void *ptr)
 void  Perl_call_atexit(pTHX_ ATEXIT_t fn, void *ptr)

๐Ÿงš cv_clone

Clones a CV, making a lexical closure. proto supplies the prototype of the function: its code, pad structure, and other attributes. That prototype gets combined with a capture of the outer lexicals that the code refers to โ€” and those get taken from the currently-executing instance of the immediately surrounding code. It's basically copy-paste but make it โœจsemantically correctโœจ.

 CV *       cv_clone(      CV *proto)
 CV *  Perl_cv_clone(pTHX_ CV *proto)

๐Ÿ‘‘ cv_name

Returns an SV containing the name of the CV, mainly for use in error reporting. The CV may actually be a GV instead, in which case the returned SV holds the GV's name. Anything that's neither a GV nor a CV gets treated as a string already holding the sub name โ€” but ngl, this could change in the future. โš ๏ธ

You can pass an SV as a second argument. If you do, the name gets assigned to it and it gets returned. Otherwise, the returned SV will be a new mortal.

 CV *       cv_name(      CV *cv, SV *sv, U32 flags)
 CV *  Perl_cv_name(pTHX_ CV *cv, SV *sv, U32 flags)
wait, hold on โ€” the signature block just above isn't in this part of the page, so don't quote me on it bestie ๐Ÿ™ˆ stick to what the manpage actually lists below ๐Ÿ‘‡

okay so continuing on cv_name for one more sec โ€” if flags has the CV_NAME_NOTQUAL bit set, then the package name does not get included in the result. And if the first argument is neither a CV nor a GV? This flag just gets ignored entirely (subject to change, so likeโ€ฆ don't marry it ๐Ÿ’€).

 SV *       cv_name(      NOCHECK CV *cv, SV *sv, U32 flags)
 SV *  Perl_cv_name(pTHX_ NOCHECK CV *cv, SV *sv, U32 flags)

๐Ÿงน cv_undef

Clears out all the active components of a CV. The way this happens is either someone explicitly going undef &foo, or the reference count just dropping to zero (rip ๐Ÿ’€). In the first case, we hang onto the CvOUTSIDE pointer so that any anonymous children can still follow the full lexical scope chain. Keeping the family tree intact, periodt โœจ

 void       cv_undef(      CV *cv)
 void  Perl_cv_undef(pTHX_ CV *cv)

๐ŸŽ€ find_rundefsv

Returns the global variable $_. That's it. That's the whole function. It's giving "main character who needs no introduction" ๐ŸŒŸ

 SV *       find_rundefsv()
 SV *  Perl_find_rundefsv(pTHX)

โš ๏ธ get_op_descs

DEPRECATED! It is planned to remove get_op_descs from a future release of Perl. Do not use it for new code; remove it from existing code. Like, actually remove it. This is your sign ๐Ÿซถ

Returns a pointer to the array of all the descriptions of the various OPs. Given an opcode from the enum in opcodes.h, PL_op_desc[opcode] returns a pointer to a C language string giving its description.

 char **       get_op_descs()
 char **  Perl_get_op_descs(pTHX)

โš ๏ธ get_op_names

DEPRECATED! It is planned to remove get_op_names from a future release of Perl. Do not use it for new code; remove it from existing code. Same vibe as its sibling above ๐Ÿ‘†

Returns a pointer to the array of all the names of the various OPs. Given an opcode from the enum in opcodes.h, PL_op_name[opcode] returns a pointer to a C language string giving its name.

 char **       get_op_names()
 char **  Perl_get_op_names(pTHX)

๐Ÿ“– HAS_SKIP_LOCALE_INIT

Described in perlembed. Go look there, bestie, it's got the whole story ๐Ÿฆ‹


โœจ intro_my

"Introduce" my variables to visible status. This gets called during parsing at the end of each statement so that lexical variables become visible to the subsequent statements. It's literally the function that makes my mean something as you keep reading your code, iconic behavior ๐Ÿ’…

 U32       intro_my()
 U32  Perl_intro_my(pTHX)

๐Ÿ“ฆ load_module, load_module_nocontext, vload_module

These load the module whose name is pointed to by the string part of name. Big note here: you give the actual module name, not its filename. So like, Foo::Bar, not Foo/Bar.pm. Do not come in here with filesystem paths, I'm begging ๐Ÿ™ˆ

ver, if specified and not NULL, provides version semantics similar to use Foo::Bar VERSION.

The optional trailing arguments can be used to specify arguments to the module's import() method, similar to use Foo::Bar VERSION LIST; their precise handling depends on the flags.

The flags argument is a bitwise-ORed collection of any of PERL_LOADMOD_DENY, PERL_LOADMOD_NOIMPORT, or PERL_LOADMOD_IMPORT_OPS (or 0 for no flags).

  • If PERL_LOADMOD_NOIMPORT is set, the module is loaded as if with an empty import list, like use Foo::Bar (). This is the only circumstance in which the trailing optional arguments may be omitted entirely.
  • Otherwise, if PERL_LOADMOD_IMPORT_OPS is set, the trailing arguments must consist of exactly one OP*, containing the op tree that produces the relevant import arguments.
  • Otherwise, the trailing arguments must all be SV* values that will be used as import arguments; and the list must be terminated with (SV*) NULL.

If neither PERL_LOADMOD_NOIMPORT nor PERL_LOADMOD_IMPORT_OPS is set, that trailing NULL pointer is needed even if no import arguments are desired. And heads up: the reference count for each specified SV* argument is decremented. Also, the name argument gets modified. Not "maybe" โ€” it does. ๐Ÿซ 

If PERL_LOADMOD_DENY is set, the module is loaded as if with no rather than use.

load_module and load_module_nocontext behave identically when called from outside the perl core, unless PERL_WANT_VARARGS has been explicitly #defined. When it has been, or when called from inside the core, they differ only in that load_module requires the thread context (aTHX) to be available.

vload_module differs from the other two only in that its trailing arguments are a va_list.

 void       load_module          (      U32 flags, SV *name,
                                        SV *ver, ...)
 void  Perl_load_module          (pTHX_ U32 flags, SV *name,
                                        SV *ver, ...)
 void       load_module_nocontext(      U32 flags, SV *name,
                                        SV *ver, ...)
 void  Perl_load_module_nocontext(      U32 flags, SV *name,
                                        SV *ver, ...)
 void       vload_module         (      U32 flags, SV *name,
                                        SV *ver, va_list *args)
 void  Perl_vload_module         (pTHX_ U32 flags, SV *name,
                                        SV *ver, va_list *args)

๐Ÿšช my_exit

A wrapper for the C library exit(3), but it honors whatever PL_exit_flags in perlapi says to do. So it's exit, but with etiquette โœจ

 void       my_exit(      U32 status)
 void  Perl_my_exit(pTHX_ U32 status)

๐Ÿ’ฅ my_failure_exit

Exits the running Perl process with an error.

On non-VMS platforms, this is essentially equivalent to "my_exit", using errno, except it forces an error code of 255 if errno is 0. So you always leave with a bad vibe, no cap ๐Ÿ˜ญ

On VMS, it takes care to set the appropriate severity bits in the exit status.

 void       my_failure_exit()
 void  Perl_my_failure_exit(pTHX)

๐Ÿ—‚๏ธ newPADNAMELIST

NOTE: newPADNAMELIST is experimental and may change or be removed without notice. Do not get attached.

Creates a new pad name list. max is the highest index for which space is allocated.

 PADNAMELIST *       newPADNAMELIST(size_t max)
 PADNAMELIST *  Perl_newPADNAMELIST(size_t max)

๐ŸŒ€ newPADNAMEouter

NOTE: newPADNAMEouter is experimental and may change or be removed without notice.

Constructs and returns a new pad name. Only use this function for names that refer to outer lexicals. (See also newPADNAMEpvn.) outer is the outer pad name that this one mirrors. The returned pad name has the PADNAMEf_OUTER flag already set, so it comes pre-labeled, slay ๐Ÿท๏ธ

 PADNAME *       newPADNAMEouter(PADNAME *outer)
 PADNAME *  Perl_newPADNAMEouter(PADNAME *outer)

๐ŸŒ€ newPADNAMEpvn

NOTE: newPADNAMEpvn is experimental and may change or be removed without notice.

Constructs and returns a new pad name. s must be a UTF-8 string. Do not use this for pad names that point to outer lexicals โ€” that's newPADNAMEouter's whole job. Stay in your lane ๐Ÿฆ‹

 PADNAME *       newPADNAMEpvn(const char *s, STRLEN len)
 PADNAME *  Perl_newPADNAMEpvn(const char *s, STRLEN len)

๐Ÿงต nothreadhook

A stub that provides the thread hook for perl_destruct when there are no threads. It's the "we don't have threads, but the code still needs a function here" friend. Doing the bare minimum and doing it well ๐ŸŽ€

 int       nothreadhook()
 int  Perl_nothreadhook(pTHX)

๐Ÿ‘ป pad_add_anon

Allocates a place in the currently-compiling pad (via pad_alloc) for an anonymous function that is lexically scoped inside the currently-compiling function. The function func is linked into the pad, and its CvOUTSIDE link to the outer scope is weakened to avoid a reference loop. Gotta break that cycle, bestie ๐Ÿ’…

One reference count is stolen, so you may need to do SvREFCNT_inc(func).

optype should be an opcode indicating the type of operation that the pad entry is to support. This doesn't affect operational semantics, but it is used for debugging.

 PADOFFSET       pad_add_anon(      CV *func, I32 optype)
 PADOFFSET  Perl_pad_add_anon(pTHX_ CV *func, I32 optype)

๐Ÿท๏ธ pad_add_name_pv, pad_add_name_pvn, pad_add_name_pvs, pad_add_name_sv

These each allocate a place in the currently compiling pad for a named lexical variable. They store the name and other metadata in the name part of the pad, and make preparations to manage the variable's lexical scoping, returning the offset of the allocated pad slot.

They differ only in how the input variable's name is specified. But in all forms, the variable name must include the leading sigil. Yes, the sigil is mandatory. That's the whole point of the name ๐ŸŒธ

  • In pad_add_name_pvs, the name is a C language string literal, which must be encoded in UTF-8.
  • In pad_add_name_pv, the input name is a NUL-terminated string, which must be encoded in UTF-8.
  • In pad_add_name_pvn, namepv points to the first byte of the name (which better be the sigil), and an additional parameter, namelen, specifies its length in bytes. Again, it must be encoded in UTF-8.
  • In pad_add_name_sv, name is an SV, and the actual name is its PV, extracted using "SvPVutf8".

If typestash is non-null, the name is for a typed lexical, and this identifies the type. If ourstash is non-null, it's a lexical reference to a package variable, and this identifies the package.

The following flags can be OR'ed together:

 padadd_OUR          redundantly specifies if it's a package var
 padadd_STATE        variable will retain value persistently
 padadd_NO_DUP_CHECK skip check for lexical shadowing
 padadd_FIELD        specifies that the lexical is a field for a class

โ€ฆand yeah, here's exactly how you actually call them, all named variants laid out:

PADOFFSET       pad_add_name_pv (      const char *name,
                                       const U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET  Perl_pad_add_name_pv (pTHX_ const char *name,
                                       const U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET       pad_add_name_pvn(      const char *namepv,
                                       STRLEN namelen, U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET  Perl_pad_add_name_pvn(pTHX_ const char *namepv,
                                       STRLEN namelen, U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET       pad_add_name_pvs(      const char *name,
                                       const U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET       pad_add_name_sv (      SV *name, U32 flags,
                                       HV *typestash,
                                       HV *ourstash)
PADOFFSET  Perl_pad_add_name_sv (pTHX_ SV *name, U32 flags,
                                       HV *typestash,
                                       HV *ourstash)

โœจ pad_alloc โœจ

โš ๏ธ bestie, heads up: pad_alloc is experimental and may change or get yeeted entirely without notice.

It hands you a spot in the pad that's currently compiling, and gives back the offset of that freshly-allocated pad slot ๐ŸŽ€. Nothing's named yet at this point โ€” the slot is just sitting there, unnamed, waiting for its moment.

tmptype is a bundle of flags saying what kind of pad entry you need, and those get set in the value SV of the allocated pad entry:

  • SVs_PADMY โ€” a named lexical variable (my, our, state)
  • SVs_PADTMP โ€” an unnamed temporary store
  • SVf_READONLY โ€” a constant shared between recursion levels

Tiny history moment ๐Ÿ’–: SVf_READONLY has only been supported here since perl 5.20. Want to play nice with earlier versions too? Use SVf_READONLY|SVs_PADTMP. And real talk โ€” SVf_READONLY does not go mark the SV in the pad slot as read-only. It just tells pad_alloc that it will be made read-only (by whoever's calling), or at the very least should be treated like it is.

SVs_PADMY can be combined with padalloc_NO_SV to ask that no actual SV gets allocated and stuffed into the pad โ€” in that case the pad slot just stays as NULL ๐Ÿซถ.

And optype? That should be an opcode signalling the type of operation the pad entry is supporting. It doesn't change operational semantics at all, it's purely for debugging vibes ๐Ÿ”.

PADOFFSET       pad_alloc(      I32 optype, U32 tmptype)
PADOFFSET  Perl_pad_alloc(pTHX_ I32 optype, U32 tmptype)

๐ŸŒธ pad_findmy_pv ๐ŸŒธ

๐ŸŒธ pad_findmy_pvn ๐ŸŒธ

๐ŸŒธ pad_findmy_pvs ๐ŸŒธ

๐ŸŒธ pad_findmy_sv ๐ŸŒธ

You give these the name of a lexical variable โ€” sigil included, don't forget it ๐Ÿ’… โ€” and they find where it lives in the pad currently being compiled. They return that offset, or NOT_IN_PAD if there's no such lexical in scope. Simple as that.

Here's the cute part: if it's not in the current pad but it does show up in the pad of any lexically enclosing scope, then a pseudo-entry for it gets added into the current pad. So it's still findable, iconic behaviour โœจ.

All of them return the offset in the current pad, or NOT_IN_PAD when no such lexical is in scope.

The four forms differ only in how you spell out the variable's name:

  • In pad_findmy_pvs, the variable name is a C language string literal, wrapped in double quotes.
  • In plain pad_findmy_pv, the variable name is a C language NUL-terminated string.
  • In pad_findmy_pvn, namepv points at the first byte of the name (which better be its sigil, no cap), and an extra parameter namelen says how long it is in bytes. So yes, namepv can contain embedded NUL characters ๐Ÿ˜ญ. The caller has to make sure namepv holds at least namelen bytes.
  • In pad_findmy_sv, the variable name comes from the SV parameter using "SvPVutf8"().

Oh and flags is reserved โ€” it must be zero. Don't get creative ๐Ÿšซ.

PADOFFSET       pad_findmy_pv (      const char *name, U32 flags)
PADOFFSET  Perl_pad_findmy_pv (pTHX_ const char *name, U32 flags)
PADOFFSET       pad_findmy_pvn(      const char *namepv,
                                     STRLEN namelen, U32 flags)
PADOFFSET  Perl_pad_findmy_pvn(pTHX_ const char *namepv,
                                     STRLEN namelen, U32 flags)
PADOFFSET       pad_findmy_pvs(      "name", U32 flags)
PADOFFSET       pad_findmy_sv (      SV *name, U32 flags)
PADOFFSET  Perl_pad_findmy_sv (pTHX_ SV *name, U32 flags)

๐Ÿงš pad_tidy ๐Ÿงš

โš ๏ธ another experimental queen: pad_tidy may change or be removed without notice.

This one tidies up a pad at the end of compiling the code it belongs to. The glow-up jobs it does: remove most stuff from the pads of anonsub prototypes; give it a @_; and mark temporaries as such ๐Ÿงนโœจ.

type tells it what kind of subroutine we're dealing with:

  • padtidy_SUB โ€” ordinary subroutine
  • padtidy_SUBCLONE โ€” prototype for lexical closure
  • padtidy_FORMAT โ€” format
void       pad_tidy(      padtidy_type type)
void  Perl_pad_tidy(pTHX_ padtidy_type type)

โญ padnamelist_fetch โญ

โš ๏ธ experimental, bestie โ€” may change or vanish without notice.

Fetches the pad name from the given index. That's it, that's the whole job ๐ŸŽ€.

PADNAME *       padnamelist_fetch(PADNAMELIST *pnl, SSize_t key)
PADNAME *  Perl_padnamelist_fetch(PADNAMELIST *pnl, SSize_t key)

๐Ÿ’œ padnamelist_store ๐Ÿ’œ

โš ๏ธ also experimental, also might change or get removed without notice.

Stores the pad name (which may be null, no judgement ๐Ÿ™ˆ) at the given index, and frees any pad name that was already chilling in that slot.

PADNAME **       padnamelist_store(      PADNAMELIST *pnl,
                                         SSize_t key,
                                         PADNAME *val)
PADNAME **  Perl_padnamelist_store(pTHX_ PADNAMELIST *pnl,
                                         SSize_t key,
                                         PADNAME *val)

๐Ÿ‘‘ perl_alloc ๐Ÿ‘‘

Allocates a brand-new Perl interpreter ๐Ÿผโœจ. Go read perlembed for the full story.

PerlInterpreter *  perl_alloc()

๐Ÿ’€ PERL_ASYNC_CHECK ๐Ÿ’€

Fully described over in perlinterp โ€” go peek there.

void  PERL_ASYNC_CHECK()

๐Ÿฆ‹ perl_clone ๐Ÿฆ‹

Makes you a new interpreter by cloning the one you've got, and returns it. Copy-paste but make it โœจmain characterโœจ.

perl_clone takes these flags as parameters:

  • CLONEf_COPY_STACKS โ€” used to, well, copy the stacks too ๐Ÿ˜Œ. Without it, you only clone the data and zero the stacks. With it, the stacks get copied and the new perl interpreter is ready to run at the exact same point as the previous one. The pseudo-fork code uses COPY_STACKS, while threads->create doesn't.
  • CLONEf_KEEP_PTR_TABLE โ€” perl_clone keeps a ptr_table with the pointer of the old variable as a key and the new variable as a value. This lets it check whether something's already been cloned so it doesn't clone it again, and instead just uses the value and bumps the refcount. If KEEP_PTR_TABLE isn't set, then perl_clone will kill the ptr_table using the function ptr_table_free(PL_ptr_table); PL_ptr_table = NULL;. A reason you might want to keep it around: if you want to dup some of your own variables that live outside the graph perl scans ๐Ÿ‘€.
  • CLONEf_CLONE_HOST โ€” this is a win32 thing, and it's ignored on unix. It tells perl's win32host code (which is c++) to clone itself. This is needed on win32 if you want to run two threads at the same time. If you just want to do some stuff in a separate perl interpreter, throw it away, and come back to the original one, you don't need to do anything ๐Ÿ’….
PerlInterpreter *  perl_clone(PerlInterpreter *proto_perl,
                              UV flags)

๐ŸŒˆ perl_construct ๐ŸŒˆ

Initializes a new Perl interpreter. See perlembed for the tea.

void  perl_construct(PerlInterpreter *my_perl)

๐Ÿ“ perl_destruct ๐Ÿ“

Shuts down a Perl interpreter. perlembed has a whole tutorial if you want it.

my_perl points at the Perl interpreter. It must have been created beforehand via perl_alloc and perl_construct. It may have been initialised through perl_parse, and may have been used via perl_run and other means. You should call this function for any Perl interpreter constructed with perl_construct โ€” even if the stuff you did afterwards failed, like if perl_parse returned a non-zero value. Don't leave it hanging ๐Ÿ˜ญ.

If the interpreter's PL_exit_flags word has the PERL_EXIT_DESTRUCT_END flag set, then this function will execute code in END blocks before doing the rest of the destruction โœจ. If you want to make any use of the interpreter between perl_parse and perl_destruct other than just calling perl_run, then this flag should be set early on. This matters if perl_run won't be called, or if you're going to do anything else beyond calling perl_run.

It returns a value suitable for passing to the C library function exit (or for returning from main), to serve as an exit code telling the world how the interpreter terminated. It takes into account any failure of perl_parse and any early exit from perl_run. The exit code is of the type required by the host operating system, so because exit code conventions differ, it is not portable to read specific numeric values as having specific meanings ๐Ÿ™…โ™€๏ธ.

int  perl_destruct(PerlInterpreter *my_perl)

๐Ÿซถ perl_free ๐Ÿซถ

Releases a Perl interpreter. See perlembed.

void  perl_free(PerlInterpreter *my_perl)

โญ PERL_GET_CONTEXT โญ

Described in perlguts, bestie.

PerlInterpreter*  PERL_GET_CONTEXT

๐ŸŽ€ perl_parse ๐ŸŽ€

Tells a Perl interpreter to parse a Perl script ๐Ÿ“œ. This does most of the initialisation of a Perl interpreter. See perlembed for the tutorial version.

my_perl points at the Perl interpreter that's going to parse the script. It must have been created beforehand through perl_alloc and perl_construct. And xsinit points at a callback function that'll be called to set up this Perl interpreter's ability to load XS extensions โ€” or it may be null, in which case no such setup happens at all ๐Ÿคทโ™€๏ธ.

argc and argv hand the Perl interpreter a set of command-line arguments, exactly like the ones you'd normally pass to a C program's main function. argv[argc] must be null โ€” non-negotiable bestie ๐Ÿ’…. These arguments are where the script to parse gets specified, either by naming a script file or by providing a script in a -e option. And listen: if $0 is going to be written to inside the Perl interpreter, then those argument strings must be in writable memory, so they can't just be string constants. ๐Ÿซ 

env specifies a set of environment variables that this Perl interpreter will use. If it's non-null, it must point to a null-terminated array of environment strings. If it's null, the Perl interpreter uses the environment supplied by the environ global variable. easy peasy โœจ

This function initialises the interpreter, and parses and compiles the script specified by the command-line arguments. That includes executing code in BEGIN, UNITCHECK, and CHECK blocks. It does not execute INIT blocks or the main program. important distinction, queen ๐Ÿ‘‘

Returns an integer of slightly tricky interpretation. The correct use of the return value is as a truth value indicating whether there was a failure in initialisation. If zero comes back โ€” slay โ€” initialisation was successful, and it's safe to proceed to call perl_run and make other use of it. If a non-zero value comes back, that's some problem that means the interpreter wants to terminate. And do not just abandon the interpreter on such a failure, that's giving neglect ๐Ÿ˜ญ. The caller should proceed to shut the interpreter down cleanly with perl_destruct and free it with perl_free.

For historical reasons, the non-zero return value also attempts to be a suitable value to pass to the C library function exit (or to return from main), to serve as an exit code indicating the nature of the way initialisation terminated. However โ€” plot twist โ€” this isn't portable, due to differing exit code conventions. An attempt is made to return an exit code of the type required by the host operating system, but because it is constrained to be non-zero, it is not necessarily possible to indicate every type of exit. It is only reliable on Unix, where a zero exit code can be augmented with a set bit that will be ignored. In any case, this function is not the correct place to acquire an exit code: one should get that from perl_destruct. periodt ๐Ÿ’–

 int  perl_parse(PerlInterpreter *my_perl, XSINIT_t xsinit,
                 int argc, char **argv, char **env)

๐Ÿƒโ™€๏ธ perl_run ๐Ÿƒโ™€๏ธ

Tells a Perl interpreter to run its main program. See perlembed for a tutorial. ๐Ÿ“–

my_perl points to the Perl interpreter. It must have been previously created through the use of perl_alloc and perl_construct, and initialised through perl_parse. This function should not be called if perl_parse returned a non-zero value, indicating a failure in initialisation or compilation. no cap, don't do it ๐Ÿšซ

This function executes code in INIT blocks, and then executes the main program. The code to be executed is that established by the prior call to perl_parse. If the interpreter's PL_exit_flags word does not have the PERL_EXIT_DESTRUCT_END flag set, then this function will also execute code in END blocks. If it is desired to make any further use of the interpreter after calling this function, then END blocks should be postponed to perl_destruct time by setting that flag. big-brain move ๐Ÿง 

Returns an integer of slightly tricky interpretation. The correct use of the return value is as a truth value indicating whether the program terminated non-locally. If zero is returned, this indicates that the program ran to completion, and it is safe to make other use of the interpreter (provided that the PERL_EXIT_DESTRUCT_END flag was set as described above). If a non-zero value is returned, this indicates that the interpreter wants to terminate early. The interpreter should not be just abandoned because of this desire to terminate; the caller should proceed to shut the interpreter down cleanly with perl_destruct and free it with perl_free. ๐Ÿ’–

For historical reasons, the non-zero return value also attempts to be a suitable value to pass to the C library function exit (or to return from main), to serve as an exit code indicating the nature of the way the program terminated. However, this isn't portable, due to differing exit code conventions. An attempt is made to return an exit code of the type required by the host operating system, but because it is constrained to be non-zero, it is not necessarily possible to indicate every type of exit. It is only reliable on Unix, where a zero exit code can be augmented with a set bit that will be ignored. In any case, this function is not the correct place to acquire an exit code: one should get that from perl_destruct.

 int  perl_run(PerlInterpreter *my_perl)

๐ŸŒ€ PERL_SET_CONTEXT ๐ŸŒ€

Described in perlguts.

 void  PERL_SET_CONTEXT(PerlInterpreter* i)

๐Ÿ”ง PERL_SYS_INIT / PERL_SYS_INIT3 ๐Ÿ”ง

These provide system-specific tune up of the C runtime environment necessary to run Perl interpreters. Only one should be used, and it should be called only once, before creating any Perl interpreters. one and done, bestie โญ

They differ in that PERL_SYS_INIT3 also initializes env.

 void  PERL_SYS_INIT (int *argc, char*** argv)
 void  PERL_SYS_INIT3(int *argc, char*** argv, char*** env)

๐Ÿงน PERL_SYS_TERM ๐Ÿงน

Provides system-specific clean up of the C runtime environment after running Perl interpreters. This should be called only once, after freeing any remaining Perl interpreters. the final tidy-up, we love to see it ๐ŸŒธ

 void  PERL_SYS_TERM()

๐Ÿซถ PerlInterpreter ๐Ÿซถ

Described in perlembed.


๐Ÿšช PL_exit_flags ๐Ÿšช

Contains flags controlling perl's behaviour on exit():

  • PERL_EXIT_DESTRUCT_END โ€” If set, END blocks are executed when the interpreter is destroyed. This is normally set by perl itself after the interpreter is constructed.
  • PERL_EXIT_ABORT โ€” Call abort() on exit. This is used internally by perl itself to abort if exit is called while processing exit.
  • PERL_EXIT_WARN โ€” Warn on exit.
  • PERL_EXIT_EXPECTED โ€” Set by the exit in perlfunc operator.

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy. ๐Ÿงต

 U8  PL_exit_flags

๐Ÿ“ PL_origalen ๐Ÿ“

Described in perlembed.


๐Ÿงผ PL_perl_destruct_level ๐Ÿงผ

This value may be set when embedding for full cleanup.

Possible values:

  • 0 - none
  • 1 - full
  • 2 or greater - full with checks.

If $ENV{PERL_DESTRUCT_LEVEL} is set to an integer greater than the value of PL_perl_destruct_level its value is used instead.

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy. ๐Ÿชก

 signed char  PL_perl_destruct_level

๐Ÿ”Ž ptr_table_fetch ๐Ÿ”Ž

Look for sv in the pointer-mapping table tbl, returning its value, or NULL if not found. like a little lookup gremlin ๐Ÿ•ต๏ธ

 void *       ptr_table_fetch(      PTR_TBL_t * const tbl,
                                    const void * const sv)
 void *  Perl_ptr_table_fetch(pTHX_ PTR_TBL_t * const tbl,
                                    const void * const sv)

๐Ÿ—‘๏ธ ptr_table_free ๐Ÿ—‘๏ธ

Clear and free a ptr table.

 void       ptr_table_free(      PTR_TBL_t * const tbl)
 void  Perl_ptr_table_free(pTHX_ PTR_TBL_t * const tbl)

โœจ ptr_table_new โœจ

Create a new pointer-mapping table.

 PTR_TBL_t *       ptr_table_new()
 PTR_TBL_t *  Perl_ptr_table_new(pTHX)

๐Ÿ“ˆ ptr_table_split ๐Ÿ“ˆ

Double the hash bucket size of an existing ptr table. growth mindset fr fr ๐ŸŒฑ

 void       ptr_table_split(      PTR_TBL_t * const tbl)
 void  Perl_ptr_table_split(pTHX_ PTR_TBL_t * const tbl)

๐Ÿ“ฅ ptr_table_store ๐Ÿ“ฅ

Add a new entry to a pointer-mapping table tbl. In hash terms, oldsv is the key; newsv is the value.

The names old and new are specific to the core's typical use of ptr_tables in thread cloning.

 void       ptr_table_store(      PTR_TBL_t * const tbl,
                                  const void * const oldsv,
                                  void * const newsv)
 void  Perl_ptr_table_store(pTHX_ PTR_TBL_t * const tbl,
                                  const void * const oldsv,
                                  void * const newsv)

๐Ÿ“œ require_pv ๐Ÿ“œ

Tells Perl to require the file named by the string argument. It is analogous to the Perl code eval "require '$file'". It's even implemented that way; consider using load_module instead.

NOTE: the perl_require_pv() form is deprecated. โš ๏ธ
 void       require_pv(      const char *pv)
 void  Perl_require_pv(pTHX_ const char *pv)

๐Ÿ‘ฏ sv_dup / sv_dup_inc ๐Ÿ‘ฏ

In spite of their generic names, these are very specialized functions mainly for use when cloning an interpreter instance. You are probably looking for newSVsv in perlapi. Generally speaking you will only want to use these in either a svt_dup magic handler, or a CLONE method. ๐Ÿช„

They duplicate an SV of any type (not just a plain SV, but including AV, HV etc.), returning a pointer to the cloned object. The cloning process uses a lookup table, so that if a particular source SV address has already been duped, that duped SV is returned rather than creating a second duplicate. no double-dipping ๐Ÿ’…

The difference is that the new SV under sv_dup will not have its reference count incremented (potentially causing it to be zero), unlike under sv_dup_inc. This is only desirable when cloning a non-owning pointer. Thus, you almost always want to use the sv_dup_inc form.

param has type CLONE_PARAMS *. This is mostly for internal core use when duplicating something more complicated than an SV (code in common is used). Your code may inherit this parameter, which you merely pass on, but you can initialize it by using clone_params_new. Don't forget to free it when done, via clone_params_del. Its only member that is public is flags, all which are documented in perl_clone in perlapi. ๐ŸŒˆ

            SV *       sv_dup    (      const SV * const ssv,
                                        CLONE_PARAMS * const param)
            SV *  Perl_sv_dup    (pTHX_ const SV * const ssv,
                                        CLONE_PARAMS * const param)
            SV *       sv_dup_inc(      const SV * const ssv,
                                        CLONE_PARAMS * const param)
            SV *  Perl_sv_dup_inc(pTHX_ const SV * const ssv,
                                        CLONE_PARAMS * const param)

๐ŸŒฑ vload_module* ๐ŸŒฑ

ok bestie this one's got no lore of its own, it's fully Described under "load_module". go read that one. ๐Ÿ’–


๐Ÿ’€ Errno ๐Ÿ’€

๐Ÿ“ sv_string_from_errnum ๐Ÿ“

ngl this one is iconic โ€” it builds you the message string that describes an OS error and hands it back as an SV. the errnum you pass must be a value that errno could take, because that's what tells it which kind of error we're talking about. no cap.

so if tgtsv is non-null, the string gets written into that SV (sorry to whatever was in there before, it gets overwritten) and then returned. if tgtsv is a null pointer, the string goes into a brand new mortal SV and that's what comes back. โœจ

where does the message come from? from whatever locale $! would use, and it gets encoded in the SV exactly however $! would encode it. and listen, the details of this are subject to future change โ€” that's straight from the source, don't shoot the messenger.

as it stands rn: the message comes from the C locale by default (which usually gives you an English message), and from the currently selected locale whenever you're inside the scope of the use locale pragma. they do a little heuristic attempt at decoding the message from the locale's character encoding, but it will only ever decode as either UTF-8 or ISO-8859-1. so:

  • always correctly decoded in a UTF-8 locale โœ…
  • usually in an ISO-8859-1 locale (usually!!) ๐Ÿซ 
  • never in any other locale ๐Ÿ˜ญ

and the SV always comes back containing an actual string, with no other OK bits set. unlike $!, you even get a message for errnum zero (which means success, bestie), and if there's genuinely no useful message available then you get a useless string back (currently it's empty). at least it's honest about it ๐Ÿ’…

 SV *       sv_string_from_errnum(      int errnum, SV *tgtsv)
 SV *  Perl_sv_string_from_errnum(pTHX_ int errnum, SV *tgtsv)

๐Ÿšจ Exception Handling (simple) Macros ๐Ÿšจ

๐Ÿงš dXCPT ๐Ÿงš

sets up all the local variables you're gonna need for exception handling. see "Exception Handling" in perlguts. ๐Ÿ’–

   dXCPT;

๐Ÿ‘‘ JMPENV_JUMP ๐Ÿ‘‘

๐Ÿ‘‘ JMPENV_PUSH ๐Ÿ‘‘

๐Ÿ‘‘ PL_restartop ๐Ÿ‘‘

these three? Described in perlinterp. that's the whole vibe check, go look there ๐Ÿ”ฅ

 void  JMPENV_JUMP (int v)
 void  JMPENV_PUSH (int v)
 OP *  PL_restartop

๐ŸŽ€ XCPT_CATCH ๐ŸŽ€

opens up a catch block. see "Exception Handling" in perlguts. it's giving "try/catch but make it C". ๐Ÿฆ‹

๐ŸŒธ XCPT_RETHROW ๐ŸŒธ

rethrows an exception you caught earlier. see "Exception Handling" in perlguts. yes it's dramatic, that's the point ๐Ÿ’…

   XCPT_RETHROW;

โœจ XCPT_TRY_END โœจ

closes out a try block. see "Exception Handling" in perlguts.

๐ŸŒˆ XCPT_TRY_START ๐ŸŒˆ

starts a try block. see "Exception Handling" in perlguts. okay so you basically always see these two as a matched set and honestly? iconic behaviour. ๐Ÿซถ


๐Ÿ“ Filesystem configuration values ๐Ÿ“

also go peep "List of capability HAS_foo symbols" while you're here ๐Ÿ‘€

๐Ÿ—‚๏ธ DIRNAMLEN ๐Ÿ—‚๏ธ

this symbol, if it's defined, tells your C program that the length of directory entry names is handed to you by a d_namlen field. if it's not defined? you're doing strlen() on the d_name field yourself, bestie. no shortcuts.

๐Ÿ•ต๏ธ DOSUID ๐Ÿ•ต๏ธ

this symbol, if defined, means your C program should check the script it's executing for setuid/setgid bits, and attempt to emulate setuid/setgid on systems that have disabled setuid #! scripts because the kernel can't do it securely.

okay and this is the important part: it is up to the package designer to make sure that emulation is actually done securely. do not skip this.

among other things, it should:

  • do an fstat on the script it just opened, to make sure it really is a setuid/setgid script
  • make sure the arguments passed correspond exactly to the argument on the #! line
  • not trust any subprocesses to which it must pass the filename instead of the file descriptor of the script to be executed

๐ŸŒŠ EOF_NONBLOCK ๐ŸŒŠ

this symbol, if defined, tells your C program that a read() on a non-blocking file descriptor will return 0 on "EOF" โ€” and not the value held in RD_NODATA (which is usually -1, in that case!). yeah. fun.

๐Ÿ”’ FCNTL_CAN_LOCK ๐Ÿ”’

this symbol, if defined, means fcntl() can be used for file locking. normally on Unix systems this is defined. it may be undefined on "VMS".

๐Ÿšฐ FFLUSH_ALL ๐Ÿšฐ

this symbol, if defined, tells you that to flush all pending stdio output you have to loop through every stdio file handle stored in an array and fflush them one by one. cute, right?

heads up: if "fflushNULL" is defined, fflushall will not even be probed for and will be left undefined. ๐Ÿ’€

๐Ÿงด FFLUSH_NULL ๐Ÿงด

this symbol, if defined, tells you that fflush(NULL) correctly flushes all pending stdio output with no side effects. importantly โ€” on some platforms, calling fflush(NULL) still corrupts "STDIN" if it's a pipe. so. yeah. ๐Ÿ˜ญ

๐Ÿงฑ FILE_base ๐Ÿงฑ

this macro accesses the _base field (or its equivalent) of the "FILE" structure pointed to by its argument. this macro will always be defined if "USE_STDIO_BASE" is defined.

 void *  FILE_base(FILE * f)

๐Ÿ“ FILE_bufsiz ๐Ÿ“

this macro figures out how many bytes are in the I/O buffer pointed to by the _base field (or its equivalent) of the "FILE" structure you hand it. this macro will always be defined if "USE_STDIO_BASE" is defined.

 Size_t  FILE_bufsiz(FILE *f)

๐Ÿ”ข FILE_cnt ๐Ÿ”ข

this macro accesses the _cnt field (or its equivalent) of the "FILE" structure pointed to by its argument. this macro will always be defined if "USE_STDIO_PTR" is defined.

 Size_t  FILE_cnt(FILE * f)

๐Ÿ‘‰ FILE_ptr ๐Ÿ‘‰

this macro accesses the _ptr field (or its equivalent) of the "FILE" structure pointed to by its argument. this macro will always be defined if "USE_STDIO_PTR" is defined.

 void *  FILE_ptr(FILE * f)

๐Ÿ“› FLEXFILENAMES ๐Ÿ“›

this symbol, if defined, means the system supports filenames longer than 14 characters. and yes, 14 is a hilariously specific number. iykyk ๐Ÿซถ

๐Ÿท๏ธ HAS_DIR_DD_FD ๐Ÿท๏ธ

this symbol, if defined, means the "DIR"* dirstream structure contains a member variable named "dd_fd".

๐Ÿ‘ฏ HAS_DUP2 ๐Ÿ‘ฏ

this symbol, if defined, means the "dup2" routine is available to duplicate file descriptors.

๐ŸŽ HAS_DUP3 ๐ŸŽ

this symbol, if defined, means the "dup3" routine is available to duplicate file descriptors. (yes it's the sequel โœจ)

โšก HAS_FAST_STDIO โšก

this symbol, if defined, means "fast stdio" is available to manipulate the stdio buffers directly. zoom zoom.

๐Ÿšถ HAS_FCHDIR ๐Ÿšถ

this symbol, if defined, means the "fchdir" routine is available to change directory using a file descriptor.

๐ŸŽ›๏ธ HAS_FCNTL ๐ŸŽ›๏ธ

this symbol, if defined, tells your C program that the fcntl() function exists.

๐Ÿ—๏ธ HAS_FDCLOSE ๐Ÿ—๏ธ

this symbol, if defined, means the "fdclose" routine is available to free a "FILE" structure without closing the underlying file descriptor. this function appeared in "FreeBSD" 10.2. periodt.

๐Ÿ“‚ HAS_FDOPENDIR ๐Ÿ“‚

this symbol, if defined, means the fdopendir() routine is available to open directories using an opened file descriptor that already refers to that directory.

๐Ÿงฎ HAS_FPATHCONF ๐Ÿงฎ

this symbol, if defined, means pathconf() is available to determine file-system related limits and options associated with a given open file descriptor.

๐Ÿ’  HAS_FPOS64_T ๐Ÿ’ 

this symbol will be defined if the C compiler supports "fpos64_t".

๐Ÿ“Š HAS_FSTATFS ๐Ÿ“Š

this symbol, if defined, means the "fstatfs" routine is available to stat filesystems by file descriptors.

๐Ÿ“ˆ HAS_FSTATVFS ๐Ÿ“ˆ

this symbol, if defined, means the "fstatvfs" routine is available to stat filesystems by file descriptors.

๐Ÿ—ƒ๏ธ HAS_GETFSSTAT ๐Ÿ—ƒ๏ธ

this symbol, if defined, means the "getfsstat" routine is available to stat filesystems in bulk. slay, efficient.

๐Ÿงพ HAS_GETMNT ๐Ÿงพ

this symbol, if defined, means the "getmnt" routine is available to get filesystem mount info by filename.

๐Ÿ“š HAS_GETMNTENT ๐Ÿ“š

this symbol, if defined, means the "getmntent" routine is available to iterate through mounted file systems to get their info.

๐Ÿ”Ž HAS_HASMNTOPT ๐Ÿ”Ž

this symbol, if defined, means the "hasmntopt" routine is available to query the mount options of file systems.

๐Ÿงท HAS_LSEEK_PROTO ๐Ÿงท

this symbol, if defined, means the system provides a prototype for the lseek() function. otherwise, it's up to the program to supply one. a good guess is:

 extern off_t lseek(int, off_t, int);

๐Ÿ—๏ธ HAS_MKDIR ๐Ÿ—๏ธ

this symbol, if defined, means the "mkdir" routine is available to create directories. otherwise you should fork off a new process to exec /bin/mkdir. yeah. retro.

๐Ÿงฟ HAS_OFF64_T ๐Ÿงฟ

this symbol will be defined if the C compiler supports "off64_t".

๐Ÿšช HAS_OPENAT ๐Ÿšช

this symbol is defined if the openat() routine is available.

๐ŸŽ‰ HAS_OPEN3 ๐ŸŽ‰

this manifest constant lets the C program know that the three argument form of open(2) is available.

๐ŸŒ€ HAS_POLL ๐ŸŒ€

this symbol, if defined, means the "poll" routine is available to "poll" active file descriptors. and please check "I_POLL" and "I_SYS_POLL" to know which header you should be including as well. don't forget bestie ๐Ÿ™ˆ

๐Ÿ“– HAS_READDIR ๐Ÿ“–

this symbol, if defined, means the "readdir" routine is available to read directory entries. you may have to include dirent.h. see "I_DIRENT".

๐Ÿ” HAS_READDIR64_R ๐Ÿ”

this symbol, if defined, means the "readdir64_r" routine is available to readdir64 re-entrantly.

โช HAS_REWINDDIR โช

this symbol, if defined, means the "rewinddir" routine is available. you may have to include dirent.h. see "I_DIRENT".

๐Ÿ—‘๏ธ HAS_RMDIR ๐Ÿ—‘๏ธ

this symbol, if defined, means the "rmdir" routine is available to remove directories. otherwise you should fork off a new process to exec /bin/rmdir. again. retro.

โฉ HAS_SEEKDIR โฉ

this symbol, if defined, means the "seekdir" routine is available. you may have to include dirent.h. see "I_DIRENT".

๐ŸŽฏ HAS_SELECT ๐ŸŽฏ

this symbol, if defined, means the "select" routine is available to "select" active file descriptors. if the timeout field is used, sys/time.h may need to be included.

๐Ÿงบ HAS_SETVBUF ๐Ÿงบ

this symbol, if defined, means the "setvbuf" routine is available to change buffering on an open stdio stream, to a line-buffered mode.

๐Ÿ—„๏ธ HAS_STDIO_STREAM_ARRAY ๐Ÿ—„๏ธ

this symbol, if defined, tells you that there is an array holding the stdio streams. ๐Ÿ‘‘


HAS_STRUCT_FS_DATA

This symbol, if defined, is basically the compiler going "bestie, we DO have struct fs_data" โ€” it's what you need when you're doing statfs().

HAS_STRUCT_STATFS

If this one is defined, then struct statfs exists for doing statfs(). iconic.

HAS_STRUCT_STATFS_F_FLAGS

Defined means your struct statfs actually has that f_flags member, the one holding the mount flags of the filesystem the file lives on. Heads up tho: this flavor of struct statfs comes from sys/mount.h (BSD 4.3), NOT from sys/statfs.h (SYSV). And the older BSDs (thinking Ultrix energy) don't have statfs() and struct statfs at all โ€” they're out here with ustat() and getmnt() plus struct ustat and struct fs_data instead. different era fr.

HAS_TELLDIR

Defined = the telldir routine is available ๐Ÿ’…. You might have to #include dirent.h for it โ€” peep "I_DIRENT" for that.

HAS_USTAT

Defined = the ustat system call exists, so you can query file system statistics via dev_t. slay.

I_FCNTL

This manifest constant is literally just telling your C program "go include fcntl.h".

#ifdef I_FCNTL
    #include <fcntl.h>
#endif

I_SYS_DIR

Defined = your C program should include sys/dir.h. no cap.

#ifdef I_SYS_DIR
    #include <sys_dir.h>
#endif

I_SYS_FILE

Defined = include sys/file.h so you can get the definition of R_OK and the whole friend group ๐ŸŒธ.

#ifdef I_SYS_FILE
    #include <sys_file.h>
#endif

I_SYS_NDIR

Defined = your C program should include sys/ndir.h. say less.

#ifdef I_SYS_NDIR
    #include <sys_ndir.h>
#endif

I_SYS_STATFS

Defined = sys/statfs.h exists, periodt.

#ifdef I_SYS_STATFS
    #include <sys_statfs.h>
#endif

LSEEKSIZE

This symbol is holding the number of bytes used by the Off_t. that's it, that's the whole job ๐Ÿ’–

RD_NODATA

This symbol holds the return code from read() when there's no data present on the non-blocking file descriptor. But bestie, be careful ๐Ÿ˜ญ โ€” if EOF_NONBLOCK isn't defined, then you literally cannot tell the difference between "no data" and EOF just by issuing a read(). You're gonna have to find another way to tell for sure, fr fr.

READDIR64_R_PROTO

This encodes the prototype of readdir64_r. It's zero if d_readdir64_r is undef, and if d_readdir64_r IS defined it's one of the REENTRANT_PROTO_T_ABC macros from reentr.h. iykyk.

ST_INO_SIGN

Holds the signedness of struct stat's st_ino. 1 for unsigned, -1 for signed. the duality of inode ๐Ÿฆ‹

ST_INO_SIZE

This variable contains the size of struct stat's st_ino, in bytes.

STDCHAR

Defined to be the type of char used in stdio.h. Its values are unsigned char or char. choose your fighter.

STDIO_CNT_LVALUE

Defined if the FILE_cnt macro can be used as an lvalue. ๐Ÿ‘‘

STDIO_PTR_LVAL_NOCHANGE_CNT

Defined if using the FILE_ptr macro as an lvalue to bump the pointer up by n leaves File_cnt(fp) completely unchanged. chill behavior honestly.

STDIO_PTR_LVAL_SETS_CNT

Defined if using the FILE_ptr macro as an lvalue to increase the pointer by n has the side effect of decreasing the value of File_cnt(fp) by n. plot twist, but mathematically consistent โœจ

STDIO_PTR_LVALUE

Defined if the FILE_ptr macro can be used as an lvalue. that's it.

STDIO_STREAM_ARRAY

This tells you the NAME of the array holding the stdio streams. Usual suspects include _iob, __iob, and __sF. it's giving "everyone has a different name for the same vibe" ๐Ÿ™ˆ

VAL_EAGAIN

Holds the errno error code that read() sets when there was no data present on the non-blocking file descriptor.

VAL_O_NONBLOCK

Use this during open() or fcntl(F_SETFL) to turn on non-blocking I/O for the file descriptor. But note โ€” there's no way back, meaning you can't turn it blocking again this way ๐Ÿ’€. If you wanna switch back and forth between blocking and non-blocking, use the ioctl(FIOSNBIO) call instead, but heads up that not every device supports it.

VOID_CLOSEDIR

Defined = the closedir() routine doesn't return a value. void queen ๐Ÿ‘‘


๐ŸŒˆ Floating point ๐ŸŒˆ

Also, List of capability HAS_foo symbols lists capabilities that arent in this section. Like HAS_ASINH, for the hyperbolic sine function. just so you're not out here searching forever ๐Ÿซถ

CASTFLAGS

Contains flags saying what difficulties your compiler has casting odd floating values to unsigned long:

0 = ok
1 = couldn't cast < 0
2 = couldn't cast >= 0x80000000
4 = couldn't cast in argument expression list

CASTNEGFLOAT

Defined if the C compiler can cast negative numbers to unsigned longs, ints and shorts. flex.

DOUBLE_HAS_INF

Defined = the double has the infinity. โ™พ๏ธ

DOUBLE_HAS_NAN

Defined = the double has the not-a-number. the most relatable value fr.

DOUBLE_HAS_NEGATIVE_ZERO

Defined = the double has the negative_zero. yes, -0.0 is real and it's different ๐Ÿ’…

DOUBLE_HAS_SUBNORMALS

Defined = the double has the subnormals (denormals). tiny little divas โœจ

DOUBLE_STYLE_CRAY

Defined = the double is the 64-bit CRAY mainframe format.

DOUBLE_STYLE_IBM

Defined = the double is the 64-bit IBM mainframe format.

DOUBLE_STYLE_IEEE

Defined = the double is the 64-bit IEEE 754.

DOUBLE_STYLE_VAX

Defined = the double is the 64-bit VAX format D or G.

DOUBLEINFBYTES

Defined = a comma-separated list of hexadecimal bytes for the double precision infinity.

DOUBLEKIND

DOUBLEKIND will be one of:

  • DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN
  • DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN
  • DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN
  • DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN
  • DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
  • DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
  • DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE
  • DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
  • DOUBLE_IS_VAX_F_FLOAT
  • DOUBLE_IS_VAX_D_FLOAT
  • DOUBLE_IS_VAX_G_FLOAT
  • DOUBLE_IS_IBM_SINGLE_32_BIT
  • DOUBLE_IS_IBM_DOUBLE_64_BIT
  • DOUBLE_IS_CRAY_SINGLE_64_BIT
  • DOUBLE_IS_UNKNOWN_FORMAT

DOUBLEMANTBITS

Defined = tells you how many mantissa bits live in the double precision floating point format. Little note tho: this is usually DBL_MANT_DIG minus one, because with the standard IEEE 754 formats, DBL_MANT_DIG includes the implicit bit, which doesn't really exist. sneaky ๐Ÿ˜ญ

DOUBLENANBYTES

Defined = a comma-separated list of hexadecimal bytes (0xHH) for the double precision not-a-number.

DOUBLESIZE

Contains the size of a double, so the C preprocessor can make decisions based on it.

Gconvert

This preprocessor macro converts a floating point number to a string without a trailing decimal point. It emulates the behavior of sprintf("%g"), but is sometimes much more efficient ๐Ÿ”ฅ. If gconvert() isn't available, but gcvt() drops the trailing decimal point, then gcvt() gets used. And if all else fails, a macro using sprintf("%g") is used. Arguments for the Gconvert macro are: value, number of digits, whether trailing zeros should be retained, and the output buffer. The usual values are:

d_Gconvert='gconvert((x),(n),(t),(b))'
d_Gconvert='gcvt((x),(n),(b))'
d_Gconvert='sprintf((b),"%.*g",(n),(x))'

The last two assume trailing zeros should not be kept.

char *  Gconvert(double x, Size_t n, bool t, char * b)

HAS_ATOLF

Defined = the atolf routine is available to convert strings into long doubles.

HAS_CLASS

Defined = the class routine is available to classify doubles. Available for example in AIX. The returned values are defined in float.h and are:

FP_PLUS_NORM    Positive normalized, nonzero
FP_MINUS_NORM   Negative normalized, nonzero
FP_PLUS_DENORM  Positive denormalized, nonzero
FP_MINUS_DENORM Negative denormalized, nonzero
FP_PLUS_ZERO    +0.0
FP_MINUS_ZERO   -0.0
FP_PLUS_INF     +INF
FP_MINUS_INF    -INF
FP_NANS         Signaling Not a Number (NaNS)
FP_NANQ         Quiet Not a Number (NaNQ)

HAS_FINITE

Defined = the finite routine is available to check whether a double is finite (non-infinity, non-NaN). little vibe check for your floats ๐ŸŒธ

HAS_FINITEL

Defined = the finitel routine is available to check whether a long double is finite (non-infinity, non-NaN).

HAS_FP_CLASS

Defined = the fp_class routine is available to classify doubles. Available for example in Digital UNIX. The returned values are defined in math.h and are:

FP_SNAN           Signaling NaN (Not-a-Number)
FP_QNAN           Quiet NaN (Not-a-Number)
FP_POS_INF        +infinity
FP_NEG_INF        -infinity
FP_POS_NORM       Positive normalized
FP_NEG_NORM       Negative normalized
FP_POS_DENORM     Positive denormalized
FP_NEG_DENORM     Negative denormalized
FP_POS_ZERO       +0.0 (positive zero)
FP_NEG_ZERO       -0.0 (negative zero)

HAS_FP_CLASSIFY

Defined = the fp_classify routine is available to classify doubles. The values are defined in math.h:

FP_NORMAL     Normalized
FP_ZERO       Zero
FP_INFINITE   Infinity
FP_SUBNORMAL  Denormalized
FP_NAN        NaN

HAS_FP_CLASSL

Defined = the fp_classl routine is available to classify long doubles. Available for example in Digital UNIX. For possible values, peep HAS_FP_CLASS ๐Ÿ‘€

HAS_FPCLASS

Defined = the fpclass routine is available to classify doubles. Available for example in Solaris/SVR4. The returned values are defined in ieeefp.h and are:

  • FP_SNAN โ€” signaling NaN
  • FP_QNAN โ€” quiet NaN
  • FP_NINF โ€” negative infinity
  • FP_PINF โ€” positive infinity
  • FP_NDENORM โ€” negative denormalized non-zero
  • FP_PDENORM โ€” positive denormalized non-zero
  • FP_NZERO โ€” negative zero
  • FP_PZERO โ€” positive zero
  • FP_NNORM โ€” negative normalized non-zero
  • FP_PNORM โ€” positive normalized non-zero

  • HAS_FPCLASSIFY โ€” bestie, if this symbol is defined it means the fpclassify routine exists and can classify doubles for you. It's available in, for example, HP-UX. The values it hands back are defined in math.h, and they are:
    • FP_NORMAL โ€” normalized
    • FP_ZERO โ€” zero
    • FP_INFINITE โ€” infinity
    • FP_SUBNORMAL โ€” denormalized
    • FP_NAN โ€” NaN
  • HAS_FPCLASSL โ€” if this symbol is defined, the fpclassl routine is around to classify long doubles. Available in, for example, IRIX. The values it returns are defined in ieeefp.h and they are:
    • FP_SNAN โ€” signaling NaN
    • FP_QNAN โ€” quiet NaN
    • FP_NINF โ€” negative infinity
    • FP_PINF โ€” positive infinity
    • FP_NDENORM โ€” negative denormalized non-zero
    • FP_PDENORM โ€” positive denormalized non-zero
    • FP_NZERO โ€” negative zero
    • FP_PZERO โ€” positive zero
    • FP_NNORM โ€” negative normalized non-zero
    • FP_PNORM โ€” positive normalized non-zero
  • HAS_FPGETROUND โ€” defined? Then the fpgetround routine is available to get the floating point rounding mode. Slay.
  • HAS_FREXPL โ€” if this is defined, the frexpl routine exists and can break a long double floating-point number into a normalized fraction plus an integral power of 2. It's giving decomposition ๐Ÿ’….
  • HAS_ILOGB โ€” this symbol being defined means the ilogb routine is available to get the integer exponent of a floating-point value.
  • HAS_ISFINITE โ€” if defined, the isfinite routine is available to check whether a double is finite (so: non-infinity, non-NaN).
  • HAS_ISFINITEL โ€” if defined, the isfinitel routine is available to check whether a long double is finite (again: non-infinity, non-NaN).
  • HAS_ISINF โ€” this one being defined means the isinf routine is available to check whether a double is an infinity. Iconic.
  • HAS_ISINFL โ€” defined means the isinfl routine is available to check whether a long double is an infinity.
  • HAS_ISNAN โ€” defined means the isnan routine is available to check whether a double is a NaN. Not me checking if it's not a number ๐Ÿ˜ญ.
  • HAS_ISNANL โ€” defined means the isnanl routine is available to check whether a long double is a NaN.
  • HAS_ISNORMAL โ€” if defined, the isnormal routine is available to check whether a double is normal (meaning non-zero normalized). Vibe check: passed.
  • HAS_J0 โ€” this symbol, if defined, tells the C program that the j0() function is available for Bessel functions of the first kind of the order zero, for doubles.
  • HAS_J0L โ€” same energy, but for long doubles: j0l() is available for Bessel functions of the first kind of the order zero, on long doubles.
  • HAS_LDBL_DIG โ€” if defined, this system's float.h or limits.h defines the symbol LDBL_DIG, which is the number of significant digits in a long double precision number. And unlike DBL_DIG, there is no good guess for LDBL_DIG if it's undefined, so don't try it.
  • HAS_LDEXPL โ€” defined means the ldexpl routine is available to shift a long double floating-point number by an integral power of 2.
  • HAS_LLRINT โ€” if defined, the llrint routine is available to return the long long value closest to a double (per the current rounding mode, bestie).
  • HAS_LLRINTL โ€” if defined, the llrintl routine is available to return the long long value closest to a long double (again, according to the current rounding mode).
  • HAS_LLROUNDL โ€” defined means the llroundl routine is available to return the nearest long long value away from zero of the long double argument value.
  • HAS_LONG_DOUBLE โ€” this symbol will be defined if the C compiler supports long doubles. Periodt.
  • HAS_LRINT โ€” if defined, the lrint routine is available to return the integral value closest to a double (according to the current rounding mode).
  • HAS_LRINTL โ€” if defined, the lrintl routine is available to return the integral value closest to a long double (according to the current rounding mode).
  • HAS_LROUNDL โ€” if defined, the lroundl routine is available to return the nearest integral value away from zero of the long double argument value.
  • HAS_MODFL โ€” defined means the modfl routine is available to split a long double x into a fractional part f and an integer part i such that |f| < 1.0 and (f + i) = x.
  • HAS_NAN โ€” if defined, the nan routine is available to generate NaN. Yes, generation, like it's a whole personality.
  • HAS_NEXTTOWARD โ€” if defined, the nexttoward routine is available to return the next machine representable long double from x in direction y.
  • HAS_REMAINDER โ€” defined means the remainder routine is available to return the floating-point remainder.
  • HAS_SCALBN โ€” if defined, the scalbn routine is available to multiply a floating-point number by an integral power of radix.
  • HAS_SIGNBIT โ€” if defined, the signbit routine is available to check if the given number has the sign bit set. This should include correct testing of -0.0. Heads up though: this will only be set if the signbit() routine is safe to use with the NV type used internally in perl. Users should call Perl_signbit(), which will be #defined to the system's signbit() function or macro if this symbol is defined.
ngl this one has lore. respect the Perl_signbit() wrapper, bestie ๐Ÿ’–
  • HAS_SQRTL โ€” if defined, the sqrtl routine is available to do long double square roots. Math girlies rise.
  • HAS_STRTOD_L โ€” if defined, the strtod_l routine is available to convert strings to long doubles. (yes, long doubles โ€” that's what it says, don't make me lie to you ๐Ÿซถ)
  • HAS_STRTOLD โ€” if defined, the strtold routine is available to convert strings to long doubles.
  • HAS_STRTOLD_L โ€” if defined, the strtold_l routine is available to convert strings to long doubles.
  • HAS_TRUNC โ€” defined means the trunc routine is available to round doubles towards zero.
  • HAS_UNORDERED โ€” if defined, the unordered routine is available to check whether two doubles are "unordered" โ€” which effectively means: whether either of them is NaN.
  • I_FENV โ€” this symbol, if defined, tells the C program that it should include fenv.h to get the floating point environment definitions. Like so:
#ifdef I_FENV
    #include <fenv.h>
#endif
  • I_QUADMATH โ€” if defined, this symbol says quadmath.h exists and should be included. Obsessed honestly:
#ifdef I_QUADMATH
    #include <quadmath.h>
#endif
  • LONG_DOUBLE_STYLE_IEEE โ€” if defined, this means the long double is any of the IEEE 754 style long doubles: LONG_DOUBLE_STYLE_IEEE_STD, LONG_DOUBLE_STYLE_IEEE_EXTENDED, LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE.
  • LONG_DOUBLE_STYLE_IEEE_DOUBLEDOUBLE โ€” if defined, the long double is the 128-bit double-double.
  • LONG_DOUBLE_STYLE_IEEE_EXTENDED โ€” if defined, the long double is the 80-bit IEEE 754. And lowkey a plot twist: despite the word 'extended', this is less than the 'std', since it's an extension of the double precision.
  • LONG_DOUBLE_STYLE_IEEE_STD โ€” if defined, the long double is the 128-bit IEEE 754.
  • LONG_DOUBLE_STYLE_VAX โ€” if defined, the long double is the 128-bit VAX format H.
  • LONG_DOUBLEKIND โ€” this one will be one of the following:
    • LONG_DOUBLE_IS_DOUBLE
    • LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
    • LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
    • LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
    • LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_LE
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LE_BE
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_LE
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
    • LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
    • LONG_DOUBLE_IS_VAX_H_FLOAT
    • LONG_DOUBLE_IS_UNKNOWN_FORMAT

It is only defined if the system supports long doubles.

  • LONG_DOUBLESIZE โ€” this symbol contains the size of a long double, so the C preprocessor can make decisions based on it. Again: only defined if the system supports long doubles. Note that this is sizeof(long double), which may include unused bytes. Yes, may. Unused bytes. Let that sink in ๐Ÿงš
  • LONGDBLINFBYTES โ€” if defined, this symbol is a comma-separated list of hexadecimal bytes for the long double precision infinity.
  • LONGDBLMANTBITS โ€” if defined, this tells you how many mantissa bits there are in long double precision floating point format. Careful though: this can be LDBL_MANT_DIG minus one, because LDBL_MANT_DIG can include the IEEE 754 implicit bit. The common x86-style 80-bit long double does not have an implicit bit. iykyk.
  • LONGDBLNANBYTES โ€” if defined, this symbol is a comma-separated list of hexadecimal bytes (0xHH) for the long double precision not-a-number.
  • NV โ€” described in perlguts. (go read it, bestie, this page isn't gonna do it for you ๐ŸŒธ)
  • NV_OVERFLOWS_INTEGERS_AT โ€” this symbol gives the largest integer value that NVs can hold. This value + 1.0 cannot be stored accurately. It's expressed as a constant floating point expression to reduce the chance of decimal/binary conversion issues. If it can't be determined, the value 0 is given. No cap.

  • NV_PRESERVES_UV โ€” if this one's defined, it means a variable of type NVTYPE can hold on to every single bit of a variable of type UVTYPE. no bits left behind bestie ๐Ÿ’–
  • NV_PRESERVES_UV_BITS โ€” this one's a number, not a yes/no: it tells you how many bits of a UVTYPE variable a NVTYPE variable can preserve. the vibe check count, fr.
  • NV_ZERO_IS_ALLBITS_ZERO โ€” defined? then a variable of type NVTYPE stores 0.0 in memory as all bits zero. iconic little detail โœจ
  • NVMANTBITS โ€” this symbol, if defined, spills how many mantissa bits there are in a Perl NV (and no, the implicit bit is not included, she's not invited). this whole thing depends on which floating point type got chosen.
  • NVSIZE โ€” holds the sizeof(NV). and here's the tea: some floating point formats have unused bytes just sitting there ๐Ÿ˜ญ the most famous example is x86* 80-bit extended precision, which comes in byte sizes of 12 and 16 (for 32 and 64 bit platforms respectively) but only actually uses 10 bytes. Perl compiled with -Duselongdouble on x86* is exactly like this.
  • NVTYPE โ€” the symbol that defines the C type used for Perl's NV. that's it, that's the one ๐Ÿซถ

๐ŸŒˆ General Configuration ๐ŸŒˆ

okay so this section is the grab-bag โ€” all the configuration info that doesn't fit anywhere else in this document. at the end you get a list of #defines where the name alone tells you the whole story, plus a list of #defines that tell you whether you need to #include some files to get the functionality. very "misc drawer in the kitchen" energy ๐ŸŽ€

  • ASCIIish โ€” a preprocessor symbol defined iff the system is an ASCII platform. on EBCDIC platforms this baby would simply not be defined. ๐Ÿ’…
#ifdef  ASCIIish
  • BYTEORDER โ€” holds the hexadecimal constant defined in byteorder, stored in a UV: so like 0x1234 or 0x4321 or 0x12345678, etc. if the compiler does cross-compiling or multiple-architecture binaries, use compiler-defined macros to figure out the byte order, no cap.
  • CAT2 โ€” this macro concatenates 2 tokens together. glue them besties ๐Ÿซถ
token  CAT2(token x, token y)
  • CHARBITS โ€” contains the size of a char, so the C preprocessor can make decisions based on it.
  • DB_VERSION_MAJOR_CFG โ€” if defined, this defines the major version number of Berkeley DB found in the db.h header when Perl was configured.
  • DB_VERSION_MINOR_CFG โ€” if defined, this defines the minor version number of Berkeley DB found in the db.h header when Perl was configured. and heads up: for DB version 1 this is always 0.
  • DB_VERSION_PATCH_CFG โ€” if defined, this defines the patch version number of Berkeley DB found in the db.h header when Perl was configured. again, for DB version 1 this is always 0.
  • DEFAULT_INC_EXCLUDES_DOT โ€” if defined, this removes the legacy default behavior of sticking '.' at the end of @INC. rip to an old tradition ๐Ÿ™ˆ
  • DLSYM_NEEDS_UNDERSCORE โ€” if defined, we gotta prepend an underscore to the symbol name before calling dlsym(). this only makes sense if you actually have dlsym, which we're just gonna presume is the case if you're using dl_dlopen.xs.
  • Drand01 โ€” the macro you use to generate uniformly distributed random numbers over the range [0., 1.[. you might have to supply an 'extern double drand48();' in your program, because SunOS 4.1.3 doesn't hand you anything relevant in its headers. see HAS_DRAND48_PROTO for more ๐Ÿ“
double  Drand01()
  • EBCDIC โ€” if defined, this system uses EBCDIC encoding. noted ๐Ÿ’€
  • HAS_CSH โ€” if defined, the C-shell exists. she's in the building.
  • HAS_GETHOSTNAME โ€” if defined, the C program may use the gethostname() routine to derive the host name. see also HAS_UNAME and PHOSTNAME.
  • HAS_GNULIBC โ€” if defined, it tells the C program that the GNU C library is being used. but lowkey, a better check is to use the __GLIBC__ and __GLIBC_MINOR__ symbols supplied with glibc. do that instead bestie โœจ
  • HAS_LGAMMA โ€” if defined, the lgamma routine is available to do the log gamma function. see also HAS_TGAMMA and HAS_LGAMMA_R.
  • HAS_LGAMMA_R โ€” if defined, the lgamma_r routine is available to do the log gamma function without using the global signgam variable. reentrant queen ๐Ÿ‘‘
  • HAS_NON_INT_BITFIELDS โ€” if defined, the C compiler accepts struct bitfields declared with sizes other than plain 'int' โ€” no error, no warning, just vibes. for example 'unsigned char' is accepted.
  • HAS_PRCTL_SET_NAME โ€” if defined, the prctl routine is available to set process title and it supports PR_SET_NAME.
  • HAS_PROCSELFEXE โ€” defined if PROCSELFEXE_PATH is a symlink to the absolute pathname of the executing program.
  • HAS_PSEUDOFORK โ€” if defined, an emulation of the fork routine is available.
  • HAS_REGCOMP โ€” if defined, the regcomp() routine is available to do some regular pattern matching (usually on POSIX.2 conforming systems).
  • HAS_SETPGID โ€” if defined, the setpgid(pid, gpid) routine is available to set process group ID.
  • HAS_SIGSETJMP โ€” tells the C program that the sigsetjmp() routine is available to save the calling process's registers and stack environment for later use by siglongjmp(), and to optionally save the process's signal mask. see Sigjmp_buf, Sigsetjmp, and Siglongjmp.
  • HAS_STRUCT_CMSGHDR โ€” if defined, the struct cmsghdr is supported.
  • HAS_STRUCT_MSGHDR โ€” if defined, the struct msghdr is supported.
  • HAS_TGAMMA โ€” if defined, the tgamma routine is available to do the gamma function. see also HAS_LGAMMA.
  • HAS_UNAME โ€” if defined, the C program may use the uname() routine to derive the host name. see also HAS_GETHOSTNAME and PHOSTNAME.
  • HAS_UNION_SEMUN โ€” if defined, the union semun is defined by including sys/sem.h. if not... yeah, the user code probably needs to define it itself, like this ๐Ÿซ 
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
}
  • I_DIRENT โ€” if defined, it tells the C program to include dirent.h. using this symbol also triggers the definition of the Direntry_t define, which ends up being "struct dirent" or "struct direct" depending on whether dirent.h is available. โœจ
#ifdef I_DIRENT
    #include <dirent.h>
#endif
  • I_POLL โ€” if defined, poll.h exists and should be included. (see also HAS_POLL) ๐Ÿฆ‹
#ifdef I_POLL
    #include <poll.h>
#endif
  • I_SYS_RESOURCE โ€” if defined, it tells the C program to include sys/resource.h.
#ifdef I_SYS_RESOURCE
    #include <sys_resource.h>
#endif
  • LIBM_LIB_VERSION โ€” if defined, libm exports _LIB_VERSION and math.h defines the enum to manipulate it.
  • NEED_VA_COPY โ€” if defined, the system stores the variable argument list datatype, va_list, in a format that cannot be copied by simple assignment ๐Ÿ˜ญ so some other means must be used when copying is required. and because these systems vary wildly in their provision (or total non-provision) of copying mechanisms, handy.h defines a platform-independent macro, Perl_va_copy(src, dst), to just handle the job for you. thank you handy.h, you ate ๐Ÿ’…
  • OSNAME โ€” contains the name of the operating system, as determined by Configure. but ngl don't lean on it too hard โ€” the specific feature tests from Configure are generally more reliable.
  • OSVERS โ€” contains the version of the operating system, as determined by Configure. same warning as above, bestie: don't rely on it too much, the specific feature tests from Configure are generally more reliable. ๐Ÿ’–
  • PERL_USE_GCC_BRACE_GROUPS โ€” this C pre-processor value, if defined, says it's permissible to use the GCC brace groups extension. HOWEVER โ€” and I need you to hear me on this โ€” use of this extension is DISCOURAGED. use a static inline function instead. periodt. ๐Ÿ”ฅ

the extension, of the form

({ statement ... })

turns the block consisting of statement ... into an expression with a value, unlike plain C language blocks. this can present optimization possibilities, BUT, unless you know for sure that this will never be compiled without this extension being available and not forbidden, you need to specify an alternative. and that means two code paths have to be maintained, which can get out-of-sync ๐Ÿ˜ญ all of these issues are solved by using a static inline function instead.

Perl can be configured to not use this feature by passing the parameter -Accflags=-DPERL_GCC_BRACE_GROUPS_FORBIDDEN to Configure.

#ifdef  PERL_USE_GCC_BRACE_GROUPS
  • PHOSTNAME โ€” if defined, indicates the command to feed to the popen() routine to derive the host name. see also HAS_GETHOSTNAME and HAS_UNAME. note that the command uses a fully qualified path, so it's safe even if used by a process with super-user privileges. safety first babes ๐Ÿ›ก๏ธ
  • PROCSELFEXE_PATH โ€” if HAS_PROCSELFEXE is defined, this symbol is the filename of the symbolic link pointing to the absolute pathname of the executing program.
  • PTRSIZE โ€” contains the size of a pointer, so the C preprocessor can make decisions based on it. it'll be sizeof(void *) if the compiler supports (void *); otherwise it'll be sizeof(char *).
  • RANDBITS โ€” how many bits the function used to generate normalized random numbers produces. values include 15, 16, 31, and 48. ๐ŸŒˆ
  • seedDrand01 โ€” this symbol defines the macro to be used in seeding the random number generator (see Drand01). ๐ŸŽฒ
void  seedDrand01(Rand_seed_t x)
  • SELECT_MIN_BITS โ€” holds the minimum number of bits operated by select. so like, if you do select(n, ...), how many bits at least will be cleared in the masks if some activity is detected. usually this is either n or 32*ceil(n/32) โ€” especially, a lot of little-endians do the latter. this is only useful if you have select(), naturally. iykyk ๐Ÿ’œ
  • SETUID_SCRIPTS_ARE_SECURE_NOW โ€” so bestie, there used to be a nasty bug where setuid scripts were just... not secure. Like at all. This symbol being #defined means that bug is NOT present in your kernel, so setuid scripts can actually be trusted ๐Ÿ’…. If it's not defined, tread carefully, fr.
  • ST_DEV_SIGN โ€” holds the signedness of struct stat's st_dev. It's 1 for unsigned, -1 for signed. That's it, that's the whole vibe check ๐ŸŒธ.
  • ST_DEV_SIZE โ€” this variable has the size of struct stat's st_dev, in bytes. Slay, now you know how many bytes you're dealing with โœจ.
  • STRINGIFY โ€” this macro wraps its token in double quotes. Iconic behaviour, honestly.
string  STRINGIFY(token x)

๐Ÿฆ‹ List of capability "HAS_foo" symbols ๐Ÿฆ‹

okay so this is a list of all the symbols that don't show up anywhere else in this document, and they tell you whether your current platform has a certain capability. They all start with HAS_, obviously ๐Ÿ’…. Only the ones whose capability is directly derivable from the name are listed here โ€” every other one gets its meaning spelled out somewhere else in this doc. This (relatively) compact list exists because the perl5-porters gang figured the full expansion would add little to no value and eat up a ton of space (because there are SO many ๐Ÿซ ). If you think some of them deserve an expansion, email perl5-porters@perl.org.

Each symbol here gets #defined if and only if the platform has that capability. Need more detail? Go look at the matching entry in config.h, bestie. And for your convenience, the list is split so the ones that indicate a reentrant version of a capability get their own lil section ๐Ÿ‘‘

 HAS__FWALK         HAS_GETPROTOBYNAME    HAS_ROUND
 HAS_ACCEPT4        HAS_GETPROTOBYNUMBER  HAS_SCALBNL
 HAS_ACCESS         HAS_GETPROTOENT       HAS_SEM
 HAS_ACCESSX        HAS_GETPRPWNAM        HAS_SENDMSG
 HAS_ACOSH          HAS_GETSERVBYNAME     HAS_SETEGID
 HAS_AINTL          HAS_GETSERVBYPORT     HAS_SETENV
 HAS_ALARM          HAS_GETSERVENT        HAS_SETEUID
 HAS_ASINH          HAS_GETSPNAM          HAS_SETGROUPS
 HAS_ATANH          HAS_HTONL             HAS_SETHOSTENT
 HAS_ATOLL          HAS_HTONS             HAS_SETLINEBUF
 HAS_CBRT           HAS_HYPOT             HAS_SETNETENT
 HAS_CHOWN          HAS_ILOGBL            HAS_SETPGRP
 HAS_CHROOT         HAS_INET_ATON         HAS_SETPGRP2
 HAS_CHSIZE         HAS_INETNTOP          HAS_SETPRIORITY
 HAS_CLEARENV       HAS_INETPTON          HAS_SETPROCTITLE
 HAS_COPYSIGN       HAS_IP_MREQ           HAS_SETPROTOENT
 HAS_COPYSIGNL      HAS_IP_MREQ_SOURCE    HAS_SETREGID
 HAS_CRYPT          HAS_IPV6_MREQ         HAS_SETRESGID
 HAS_CTERMID        HAS_IPV6_MREQ_SOURCE  HAS_SETRESUID
 HAS_CUSERID        HAS_ISASCII           HAS_SETREUID
 HAS_DIRFD          HAS_ISBLANK           HAS_SETRGID
 HAS_DLADDR         HAS_ISLESS            HAS_SETRUID
 HAS_DLERROR        HAS_KILLPG            HAS_SETSERVENT
 HAS_EACCESS        HAS_LCHOWN            HAS_SETSID
 HAS_ENDHOSTENT     HAS_LINK              HAS_SHM
 HAS_ENDNETENT      HAS_LINKAT            HAS_SIGACTION
 HAS_ENDPROTOENT    HAS_LLROUND           HAS_SIGPROCMASK
 HAS_ENDSERVENT     HAS_LOCKF             HAS_SIN6_SCOPE_ID
 HAS_ERF            HAS_LOGB              HAS_SNPRINTF
 HAS_ERFC           HAS_LOG1P             HAS_STAT
 HAS_EXPM1          HAS_LOG2              HAS_STRCOLL
 HAS_EXP2           HAS_LROUND            HAS_STRERROR_L
 HAS_FCHMOD         HAS_LSTAT             HAS_STRLCAT
 HAS_FCHMODAT       HAS_MADVISE           HAS_STRLCPY
 HAS_FCHOWN         HAS_MBLEN             HAS_STRNLEN
 HAS_FD_SET         HAS_MBRLEN            HAS_STRTOD
 HAS_FDIM           HAS_MBRTOWC           HAS_STRTOL
 HAS_FEGETROUND     HAS_MBSTOWCS          HAS_STRTOLL
 HAS_FFS            HAS_MBTOWC            HAS_STRTOQ
 HAS_FFSL           HAS_MEMMEM            HAS_STRTOUL
 HAS_FGETPOS        HAS_MEMRCHR           HAS_STRTOULL
 HAS_FLOCK          HAS_MKDTEMP           HAS_STRTOUQ
 HAS_FMA            HAS_MKFIFO            HAS_STRXFRM
 HAS_FMAX           HAS_MKOSTEMP          HAS_STRXFRM_L
 HAS_FMIN           HAS_MKSTEMP           HAS_SYMLINK
 HAS_FORK           HAS_MKSTEMPS          HAS_SYS_ERRLIST
 HAS_FSEEKO         HAS_MMAP              HAS_SYSCALL
 HAS_FSETPOS        HAS_MPROTECT          HAS_SYSCONF
 HAS_FSYNC          HAS_MSG               HAS_SYSTEM
 HAS_FTELLO         HAS_MSYNC             HAS_TCGETPGRP
 HAS_GAI_STRERROR   HAS_MUNMAP            HAS_TCSETPGRP
 HAS_GETADDRINFO    HAS_NEARBYINT         HAS_TOWLOWER
 HAS_GETCWD         HAS_NEXTAFTER         HAS_TOWUPPER
 HAS_GETENTROPY     HAS_NICE              HAS_TRUNCATE
 HAS_GETESPWNAM     HAS_NTOHL             HAS_TRUNCL
 HAS_GETGROUPS      HAS_NTOHS             HAS_UALARM
 HAS_GETHOSTBYADDR  HAS_PATHCONF          HAS_UMASK
 HAS_GETHOSTBYNAME  HAS_PAUSE             HAS_UNLINKAT
 HAS_GETHOSTENT     HAS_PHOSTNAME         HAS_UNSETENV
 HAS_GETLOGIN       HAS_PIPE              HAS_VFORK
 HAS_GETNAMEINFO    HAS_PIPE2             HAS_VSNPRINTF
 HAS_GETNETBYADDR   HAS_PRCTL             HAS_WAITPID
 HAS_GETNETBYNAME   HAS_PTRDIFF_T         HAS_WAIT4
 HAS_GETNETENT      HAS_READLINK          HAS_WCRTOMB
 HAS_GETPAGESIZE    HAS_READV             HAS_WCSCMP
 HAS_GETPGID        HAS_RECVMSG           HAS_WCSTOMBS
 HAS_GETPGRP        HAS_REMQUO            HAS_WCSXFRM
 HAS_GETPGRP2       HAS_RENAME            HAS_WCTOMB
 HAS_GETPPID        HAS_RENAMEAT          HAS_WRITEV
 HAS_GETPRIORITY    HAS_RINT

and now, the reentrant capabilities (the โœจfancyโœจ ones):

 HAS_CRYPT_R          HAS_GETLOGIN_R          HAS_GETSPNAM_R
 HAS_CTERMID_R        HAS_GETNETBYADDR_R      HAS_RANDOM_R
 HAS_DRAND48_R        HAS_GETNETBYNAME_R      HAS_READDIR_R
 HAS_ENDHOSTENT_R     HAS_GETNETENT_R         HAS_SETHOSTENT_R
 HAS_ENDNETENT_R      HAS_GETPROTOBYNAME_R    HAS_SETNETENT_R
 HAS_ENDPROTOENT_R    HAS_GETPROTOBYNUMBER_R  HAS_SETPROTOENT_R
 HAS_ENDSERVENT_R     HAS_GETPROTOENT_R       HAS_SETSERVENT_R
 HAS_GETGRGID_R       HAS_GETPWNAM_R          HAS_SRANDOM_R
 HAS_GETGRNAM_R       HAS_GETPWUID_R          HAS_SRAND48_R
 HAS_GETHOSTBYADDR_R  HAS_GETSERVBYNAME_R     HAS_STRERROR_R
 HAS_GETHOSTBYNAME_R  HAS_GETSERVBYPORT_R     HAS_TMPNAM_R
 HAS_GETHOSTENT_R     HAS_GETSERVENT_R        HAS_TTYNAME_R

Example usage, so you can see how this actually looks in the wild:

 #ifdef HAS_STRNLEN
   use strnlen()
 #else
   use an alternative implementation
 #endif

๐ŸŒธ List of "#include" needed symbols ๐ŸŒธ

this one is all about the #include files ๐ŸŽ€. It's a list of symbols that tell you whether certain #include files exist on your platform. If your code touches the functionality that one of these is for, you're gonna need to #include it โ€” but only if the matching symbol on this list is #defined, bestie. Need more detail? Same deal: check the corresponding entry in config.h, iykyk ๐Ÿ’œ.

 I_ARPA_INET  I_IEEEFP       I_SGTTY       I_SYS_SECURITY     I_SYSLOG
 I_BFD        I_INTTYPES     I_SHADOW      I_SYS_SELECT       I_SYSMODE
 I_CRYPT      I_LIBUTIL      I_STDBOOL     I_SYS_STAT         I_SYSUIO
 I_DBM        I_MNTENT       I_STDCKDINT   I_SYS_STATVFS      I_SYSUTSNAME
 I_DLFCN      I_NDBM         I_STDINT      I_SYS_SYSCALL      I_TERMIO
 I_EXECINFO   I_NET_ERRNO    I_SUNMATH     I_SYS_TIME         I_TERMIOS
 I_FP         I_NETDB        I_SYS_ACCESS  I_SYS_TIME_KERNEL  I_UNISTD
 I_FP_CLASS   I_NETINET_IN   I_SYS_IOCTL   I_SYS_TIMES        I_USTAT
 I_GDBM       I_NETINET_TCP  I_SYS_MOUNT   I_SYS_TYPES        I_VFORK
 I_GDBM_NDBM  I_PROT         I_SYS_PARAM   I_SYS_UN           I_WCHAR
 I_GDBMNDBM   I_PWD          I_SYS_POLL    I_SYS_VFS          I_WCTYPE
 I_GRP        I_RPCSVC_DBM   I_SYS_RANDOM  I_SYS_WAIT

Example usage, aka how you'd actually write this:

 #ifdef I_WCHAR
   #include <wchar.h>
 #endif

๐Ÿ‘‘ Global Variables ๐Ÿ‘‘

these variables are global to an entire process โ€” like, they're shared between all interpreters and all threads in a process. The main character energy is off the charts, but so is the danger ๐Ÿ™ˆ.

โš ๏ธ Any variables not documented here may be changed or removed without notice, so do NOT use them! Not a drill, bestie.

If you genuinely feel like you need an unlisted variable, first send an email to perl5-porters@perl.org. Maybe someone there will point out a way to do what you need without touching an internal variable โ€” which would be a slay. But if not, you should get a go-ahead to document it, and then use it. Periodt ๐Ÿ”ฅ.

  • PL_check โ€” an array, indexed by opcode, of functions that get called for the "check" phase of optree building while Perl code is being compiled. For most (but not all) types of op, once the op has been initially built and populated with its child ops, it gets filtered through the check function referenced by the appropriate element of this array. The new op is passed in as the sole argument to the check function, and the check function returns the completed op ๐Ÿ’–.

The check function may (as the name suggests, ikr) check the op for validity and signal errors. It can also initialise or modify parts of the ops, or go full surgical and add or remove child ops โ€” or even throw the op away entirely and return a different op in its place ๐Ÿ˜ญ. Chaotic but valid.

This array of function pointers is a super convenient place to hook into the compilation process. An XS module can drop its own custom check function in place of any of the standard ones, to influence how a particular type of op compiles. However, a custom check function must never fully replace a standard check function (or even a custom check function from another module). A module that modifies checking must instead wrap the preexisting check function. And a custom check function has to be selective about when it applies its custom behaviour โ€” in the usual case where it decides not to do anything special with an op, it must chain the preexisting op function. So check functions end up linked in a chain, with the core's base checker sitting at the end ๐Ÿงš.

For thread safety, modules should not write directly to this array. Instead, use the function wrap_op_checker. That's the move, fr fr.

  • PL_infix_plugin โ€” > NOTE: PL_infix_plugin is experimental and may change or be removed without notice. ๐Ÿซ 
NOTE: This API exists entirely for the purpose of making the CPAN module XS::Parse::Infix work. It is not expected that additional modules will make use of it; rather, that they should use XS::Parse::Infix to provide parsing of new infix operators. iykyk.

It's a function pointer, pointing at a function used to handle extended infix operators. The function should be declared as:

        int infix_plugin_function(pTHX_
                char *opname, STRLEN oplen,
                struct Perl_custom_infix **infix_ptr)

and that's the whole โœจvibeโœจ of that lil pointer, bestie โ€” onto the next bit ๐Ÿฆ‹

The function gets called from the tokenizer every time it clocks a possible infix operator. opname points at the operator name sitting in the parser's input buffer, and oplen is the max number of bytes of it that should get eaten โ€” and bestie, it is not null-terminated, so don't go treating it like a C string, okay? ๐Ÿ’… The function is supposed to peek at the operator name (and maybe other state, like %^H) and decide whether it wants to handle that operator name.

So here's the tea: compared to the single stage of PL_keyword_plugin, parsing extra infix operators happens in three separate stages. Why? Because the interactions with the parser are messier and we gotta make sure operator precedence rules actually work right. These stages get co-ordinated through an extra information structure. ๐ŸŽ€

If the function does want to handle the infix operator, it has to set the variable pointed to by infix_ptr to the address of a structure that hands over this additional info about the subsequent parsing stages. If it doesn't want it? Then it should just call the next function in the chain. Simple as. โœจ

That structure looks exactly like this:

struct Perl_custom_infix {
    enum Perl_custom_infix_precedence prec;
    void (*parse)(pTHX_ SV **opdata,
        struct Perl_custom_infix *);
    OP *(*build_op)(pTHX_ SV **opdata, OP *lhs, OP *rhs,
        struct Perl_custom_infix *);
};

Then the function has to return an integer telling you how many bytes got consumed by the name of this operator. If the operator's name is made of identifier characters, that number must equal oplen. But if the operator is named by non-identifier characters, it's allowed to be shorter than oplen โ€” and any extra characters after it don't get claimed by the infix operator at all, they just get consumed by the tokenizer and parser like normal. ๐Ÿซถ

If the optional parse function is provided, the parser calls it right away so the operator's definition can slurp up any additional syntax from the source code. Don't use it for normal operand parsing, bestie โ€” but it's genuinely useful for implementing stuff like parametric operators or meta-operators that consume more syntax all on their own. This function can use the variable pointed to by opdata to hand over an SV containing extra data that gets passed into the build_op function later. ๐Ÿ’–

The info structure carries the operator precedence level in the prec field, which is what tells the parser how much of the surrounding syntax before and after should be counted as operands to the operator.

Then the tokenizer and parser just keep doing their thing as normal until enough extra input has been parsed to form both the left- and right-hand side operands for the operator, according to that precedence level. At that point build_op gets called, handed the left- and right-hand operands as optree fragments. It's expected to combine them into the resulting optree fragment, and return that. ๐ŸŒธ

After build_op returns, if the variable pointed to by opdata was set to a non-NULL value, it gets destroyed by calling SvREFCNT_dec().

For thread safety, modules should not set this variable directly. Use the function wrap_infix_plugin instead. ๐Ÿ’…

But okay, all that being said โ€” the introductory note from up above still applies. This variable exists in core perl only for the benefit of the XS::Parse::Infix module. That module is basically the central registry for infix operators, automatically handling things like deparse support and discovery/reflection, and those abilities only work because it knows about all the registered operators. Other modules should not use this interpreter variable directly to implement their thing, because then those central features would stop working properly. ๐Ÿ˜ญ

And fr fr, it's likely that this (experimental) API gets replaced in a future Perl version by a more complete API that fully implements the central registry and the other semantics currently provided by XS::Parse::Infix โ€” once the module has had enough experimental testing time. This current mechanism is literally just an interim measure to get to that stage. ๐Ÿ‘‘


PL_keyword_plugin

NOTE: PL_keyword_plugin is experimental and may change or be removed without notice. ๐Ÿšจ

Function pointer, pointing at a function used to handle extended keywords. The function should be declared as

int keyword_plugin_function(pTHX_
        char *keyword_ptr, STRLEN keyword_len,
        OP **op_ptr)

The function gets called from the tokeniser whenever a possible keyword shows up. keyword_ptr points at the word inside the parser's input buffer, and keyword_len gives its length โ€” it is not null-terminated. The function is supposed to examine the word, and possibly other state like %^H, to decide whether it wants to handle it as an extended keyword. If it doesn't want it, the function should return KEYWORD_PLUGIN_DECLINE and the normal parser process carries on. โœจ

If the function does want to handle the keyword, it first has to parse anything following the keyword that's part of the syntax introduced by that keyword. See "Lexer interface" for the deets. ๐Ÿฆ‹

When a keyword is being handled, the plugin function must build a tree of OP structures, representing the code that was parsed. The root of the tree has to be stored in op_ptr. The function then returns a constant indicating the syntactic role of the thing it just parsed: KEYWORD_PLUGIN_STMT if it's a complete statement, or KEYWORD_PLUGIN_EXPR if it's an expression. And note this: a statement construct cannot be used inside an expression (except via do BLOCK and similar), and an expression is *not a complete statement โ€” it needs at least a terminating semicolon. ๐Ÿ’…

When a keyword gets handled, the plugin function may also have (compile-time) side effects. It may modify %^H, define functions, and so on. Typically, if side effects are the main purpose of a handler, it doesn't want to generate any ops to be included in the normal compilation. In that case it's still required to supply an op tree โ€” but generating a single null op is enough. ๐ŸŽ€

That's how the PL_keyword_plugin function needs to behave overall. Conventionally, though, you don't completely replace the existing handler function. Instead, you take a copy of PL_keyword_plugin before assigning your own function pointer to it. Your handler function should look for the keywords it's interested in and handle those. Where it's not interested, it should call the saved plugin function, passing on the arguments it received. So PL_keyword_plugin actually points at a *chain of handler functions โ€” all of them get a shot at handling keywords, and only the last function in the chain (the one built into the Perl core) will normally return KEYWORD_PLUGIN_DECLINE. ๐ŸŒˆ

For thread safety, modules should not set this variable directly. Use the function wrap_keyword_plugin instead. ๐Ÿ’œ

PL_phase

A value that indicates the current Perl interpreter's phase. Possible values include PERL_PHASE_CONSTRUCT, PERL_PHASE_START, PERL_PHASE_CHECK, PERL_PHASE_INIT, PERL_PHASE_RUN, PERL_PHASE_END, and PERL_PHASE_DESTRUCT.

For example, this here determines whether the interpreter is in global destruction:

if (PL_phase == PERL_PHASE_DESTRUCT) {
    // we are in global destruction
}

PL_phase was introduced in Perl 5.14; in prior perls you can use PL_dirty (boolean) to figure out whether the interpreter is in global destruction. (Use of PL_dirty is discouraged since 5.14.) โญ

 enum perl_phase  PL_phase

โœจ GV Handling and Stashes โœจ

A GV is a structure which corresponds to a Perl typeglob, i.e., *foo. It's a structure that holds a pointer to a scalar, an array, a hash etc, corresponding to $foo, @foo, %foo.

GVs are usually found as values in stashes (symbol table hashes) where Perl stores its global variables. ๐Ÿ‘‘

A stash is a hash that contains all variables that are defined within a package. See "Stashes and Globs" in perlguts. ๐Ÿงš


amagic_call

Perform the overloaded (active magic) operation given by method. method is one of the values found in overload.h.

flags affects how the operation is performed, like this:

  • AMGf_noleft โ€” left is not to be used in this operation.
  • AMGf_noright โ€” right is not to be used in this operation.
  • AMGf_unary โ€” the operation is done only on just one operand.
  • AMGf_assign โ€” the operation changes one of the operands, e.g., $x += 1
  • AMGf_force_scalar โ€” in many cases amagic_call() uses the GIMME_V context of the current OP when calling the sub handling the overload. This flag forces amagic_call() to use scalar context.
  • AMGf_force_overload โ€” perform overloading even in the context of no overloading;.
 SV *       amagic_call(      SV *left, SV *right, int method,
                              int dir)
 SV *  Perl_amagic_call(pTHX_ SV *left, SV *right, int method,
                              int dir)

amagic_deref_call

Perform method overloading dereferencing on ref, returning the dereferenced result. method must be one of the dereference operations given in overload.h.

If overloading is inactive on ref, it returns ref itself. ๐Ÿซถ

 SV *       amagic_deref_call(      SV *ref, int method)
 SV *  Perl_amagic_deref_call(pTHX_ SV *ref, int method)

gv_add_by_type

Make sure there is a slot of type type in the GV gv. ๐Ÿ’–

 GV *       gv_add_by_type(      GV *gv, svtype type)
 GV *  Perl_gv_add_by_type(pTHX_ GV *gv, svtype type)

Gv_AMupdate

Recalculates overload magic in the package given by stash.

Returns:

  • 1 on success and there is some overload
  • 0 if there is no overload
  • -1 if some error occurred and it couldn't croak (because destructing is true).
 int       Gv_AMupdate(      HV *stash, bool destructing)
 int  Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)

gv_autoload_pv / gv_autoload_pvn / gv_autoload_sv / gv_autoload4 ๐Ÿ”

Okay bestie, these four are the find me an AUTOLOAD method girlies. Each one searches for an "AUTOLOAD" method. No luck? You get NULL. Found it? You get a pointer to its GV โ€” and the package $AUTOLOAD variable gets set to the name (fully qualified, no shortcuts ๐Ÿ’…). Bonus lore: if it's found and the GV's CV is an XSUB, the CV's PV gets set to the name, and its stash gets set to the stash of the GV. Slay.

The searching happens in "MRO" order, exactly like it's specified in "gv_fetchmeth", and it starts with stash if that isn't NULL.

"gv_autoload4" takes a method parameter; the other three take a flags one (both types explained down below ๐Ÿ‘‡). Other than that, these forms only differ in how the name gets specified.

  • In "gv_autoload_pv", namepv is a C language NUL-terminated string.
  • In "gv_autoload_pvn" and "gv_autoload4", name points to the first byte of the name, and an extra parameter, len, tells you its length in bytes. So yes, *name may contain embedded-NUL characters. Not me being extra, that's just how it is.
  • In "gv_autoload_sv", *namesv is an SV, and the name is the PV extracted from it using "SvPV". If the SV is marked as being in UTF-8, the extracted PV will be too. โœจ

The other way to announce that a name is UTF-8 encoded? Set the "SVf_UTF8" bit in flags, for the forms that actually have that parameter. And heads up: the name is never considered UTF-8 in "gv_autoload4". Periodt.

The method parameter in "gv_autoload4" is only there to say that the name is for a method (non-zero) or not (zero). The other forms use the "GV_AUTOLOAD_ISMETHOD" bit in flags for that job.

The only other significant value in flags right now is "GV_SUPER", which โ€” if set โ€” means skip searching for the name in stash. Lowkey huge.

GV *       gv_autoload_pv (      NOCHECK HV *stash,
                                 const char *namepv, U32 flags)
GV *  Perl_gv_autoload_pv (pTHX_ NOCHECK HV *stash,
                                 const char *namepv, U32 flags)
GV *       gv_autoload_pvn(      NOCHECK HV *stash,
                                 const char *name, STRLEN len,
                                 U32 flags)
GV *  Perl_gv_autoload_pvn(pTHX_ NOCHECK HV *stash,
                                 const char *name, STRLEN len,
                                 U32 flags)
GV *       gv_autoload_sv (      NOCHECK HV *stash, SV *namesv,
                                 U32 flags)
GV *  Perl_gv_autoload_sv (pTHX_ NOCHECK HV *stash, SV *namesv,
                                 U32 flags)
GV *       gv_autoload4   (      HV *stash, const char *name,
                                 STRLEN len, I32 method
)

gv_AVadd / gv_HVadd / gv_IOadd / gv_SVadd ๐ŸŽ€

These are the make sure the slot exists squad. They make sure there's a slot of the given type (AV, HV, IO, SV) inside the GV gv. That's the whole vibe. โœจ

GV *       gv_AVadd(      GV *gv)
GV *  Perl_gv_AVadd(pTHX_ GV *gv)
GV *       gv_HVadd(      GV *gv)
GV *  Perl_gv_HVadd(pTHX_ GV *gv)
GV *       gv_IOadd(      GV *gv)
GV *  Perl_gv_IOadd(pTHX_ GV *gv)
GV *       gv_SVadd(      GV *gv)
GV *  Perl_gv_SVadd(pTHX_ GV *gv)

gv_const_sv ๐Ÿ’Ž

If "gv" is a typeglob whose subroutine entry is a constant sub eligible for inlining โ€” or if "gv" is a placeholder reference that would be promoted to such a typeglob โ€” then this returns the value returned by the sub. Otherwise? "NULL". Simple as that, bestie.

SV *       gv_const_sv(      GV *gv)
SV *  Perl_gv_const_sv(pTHX_ GV *gv)

gv_efullname3 / gv_efullname4 / gv_fullname3 / gv_fullname4 ๐ŸŒธ

These put the full package name of "gv" into sv. The "gv_e*" forms instead hand you the effective package name (go look at "HvENAME", iykyk).

If prefix is non-NULL, it's treated as a C language NUL-terminated string, and the stored name gets prefaced with it. Cute.

The other difference between these functions is that the *4 forms have an extra parameter, keepmain. If true, an initial "main::" in the name is kept; if false, it gets stripped. With the *3 forms, it is always kept. No notes.

void       gv_efullname3(      SV *sv, const GV *gv,
                               const char *prefix)
void  Perl_gv_efullname3(pTHX_ SV *sv, const GV *gv,
                               const char *prefix)
void       gv_efullname4(      SV *sv, const GV *gv,
                               const char *prefix, bool keepmain)
void  Perl_gv_efullname4(pTHX_ SV *sv, const GV *gv,
                               const char *prefix, bool keepmain)
void       gv_fullname3 (      SV *sv, const GV *gv,
                               const char *prefix)
void  Perl_gv_fullname3 (pTHX_ SV *sv, const GV *gv,
                               const char *prefix)
void       gv_fullname4 (      SV *sv, const GV *gv,
                               const char *prefix, bool keepmain)
void  Perl_gv_fullname4 (pTHX_ SV *sv, const GV *gv,
                               const char *prefix, bool keepmain)

gv_fetchfile / gv_fetchfile_flags ๐Ÿฆ‹

These return the debugger glob for the file (compiled by Perl, bestie) whose name is given by the "name" parameter.

There are currently exactly two differences between these functions. Exactly two. Count them. ๐Ÿ‘‘

  1. The "name" parameter to "gv_fetchfile" is a C string, meaning it is "NUL"-terminated; whereas the "name" parameter to "gv_fetchfile_flags" is a Perl string, whose length (in bytes) gets passed in via the "namelen" parameter. This means the name may contain embedded "NUL" characters. Also "namelen" doesn't exist in plain "gv_fetchfile".
  2. "gv_fetchfile_flags" has an extra "flags" parameter, which is currently completely ignored, but it's there to allow for possible future extensions. Foreshadowing, honestly. ๐Ÿ”ฎ
GV *       gv_fetchfile      (      const char *name)
GV *  Perl_gv_fetchfile      (pTHX_ const char *name)
GV *       gv_fetchfile_flags(      const char * const name,
                                    const STRLEN len,
                                    const U32 flags)
GV *  Perl_gv_fetchfile_flags(pTHX_ const char * const name,
                                    const STRLEN len,
                                    const U32 flags)

gv_fetchmeth / gv_fetchmeth_autoload / gv_fetchmeth_pv / gv_fetchmeth_pv_autoload / gv_fetchmeth_pvn / gv_fetchmeth_pvn_autoload / gv_fetchmeth_sv / gv_fetchmeth_sv_autoload ๐Ÿ”ฅ

Every single one of these looks for a glob with name name that contains a defined subroutine. Found it? You get the GV of that glob. Didn't? "NULL". ๐Ÿซถ

Not-so-gentle reminder: you probably want to use the "gv_fetchmethod" family of functions instead. Just saying.

Searching is always done in this order, with some steps skipped depending on various criteria. First match found wins, and then the search is over. Also important: "gv_fetchmeth_pv" and "gv_fetchmeth_pv_autoload" lack a flags parameter, so for those two, just pretend "flags" is zero in everything below. ๐Ÿ’…

  1. "stash" is searched first โ€” unless "stash" either is NULL, or "GV_SUPER" is set in "flags".
  2. Stashes accessible via @ISA are searched next. And this searching is conducted according to "MRO" order. โœจ
  3. "UNIVERSAL::" gets searched unless "GV_NOUNIVERSAL" is set.
  4. Autoloaded subroutines are then looked for โ€” but only for the forms whose names end in "_autoload", and only when "stash" is not NULL and "GV_SUPER" is not set.

The argument level should be either 0 or -1. That's it. Those are the options.

  • If -1 โ€” No method caching is done. Nothing. Zero. Nada.
  • If 0 โ€” If "GV_SUPER" is not set in "flags", the method found is cached in "stash". If "GV_SUPER" is set in "flags", then the method is cached in the super cache for "stash". And if the method is not found, a negative cache entry is added. Not me keeping receipts on the misses. ๐Ÿ˜ญ Note that subroutines found in "UNIVERSAL::" are not cached โ€” though this may change.
โš ๏ธ The GV returned from these may be a method cache entry, which is not visible to Perl code. So when you call "call_sv", do not use the GV directly โ€” use the method's CV instead, which you can get from the GV with the "GvCV" macro. And for an autoloaded subroutine without a stub, GvCV() of the result may be zero. Careful bestie!!

The only other significant value for "flags" is "SVf_UTF8", which indicates that "name" should be treated as being encoded in UTF-8. Since plain "gv_fetchmeth" and "gv_fetchmeth_autoload" lack a "flags" parameter, "name" is never UTF-8 for those.

Otherwise, the functions behave identically โ€” except as noted below. ๐Ÿ‘‡

  • In "gv_fetchmeth_pv" and "gv_fetchmeth_pv_autoload", "name" is a C language NUL-terminated string.
  • In "gv_fetchmeth", "gv_fetchmeth_pvn", "gv_fetchmeth_autoload", and "gv_fetchmeth_pvn_autoload", "name" points to the first byte of the name, and an extra parameter, "len", specifies its length in bytes. Hence, the name may contain embedded-NUL characters. ๐Ÿซข
  • In "gv_fetchmeth_sv" and "gv_fetchmeth_sv_autoload", *name is an SV, and the name is the PV extracted from it, using "SvPV". If the SV is marked as being in UTF-8, the extracted PV will be as well. And including "SVf_UTF8" in "flags" will force the name to be considered UTF-8 even if the SV is not marked that way. Main character energy, honestly. ๐ŸŒˆ
GV *       gv_fetchmeth             (      NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level)
GV *  Perl_gv_fetchmeth             (pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level)
GV *       gv_fetchmeth_autoload    (      NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level)
GV *  Perl_gv_fetchmeth_autoload    (pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level)
GV *       gv_fetchmeth_pv          (      NOCHECK HV *stash,
                                           const char *name,
                                           I32 level, U32 flags)
GV *  Perl_gv_fetchmeth_pv          (pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           I32 level, U32 flags)
GV *       gv_fetchmeth_pv_autoload (      NOCHECK HV *stash,
                                           const char *name,
                                           I32 level, U32 flags)
GV *  Perl_gv_fetchmeth_pv_autoload (pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           I32 level, U32 flags)
GV *       gv_fetchmeth_pvn         (      NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level,
                                           U32 flags)
GV *  Perl_gv_fetchmeth_pvn         (pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level,
                                           U32 flags)
GV *       gv_fetchmeth_pvn_autoload(      NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level,
                                           U32 flags)
GV *  Perl_gv_fetchmeth_pvn_autoload(pTHX_ NOCHECK HV *stash,
                                           const char *name,
                                           STRLEN len, I32 level,
                                           U32 flags)
GV *       gv_fetchmeth_sv          (      NOCHECK HV *stash,
                                           SV *namesv, I32 level,
                                           U32 flags)
GV *  Perl_gv_fetchmeth_sv          (pTHX_ NOCHECK HV *stash,
                                           SV *namesv, I32 level,
                                           U32 flags)
GV *       gv_fetchmeth_sv_autoload (      NOCHECK HV *stash,
                                           SV *namesv, I32 level,
                                           U32 flags)
GV *  Perl_gv_fetchmeth_sv_autoload (pTHX_ NOCHECK HV *stash,
                                           SV *namesv, I32 level,
                                           U32 flags)

๐ŸŒˆ "gv_fetchmethod" &nbsp;๐Ÿซถ&nbsp; "gv_fetchmethod_autoload" ๐ŸŒˆ

okay so these two each hand you back the glob that holds the subroutine you're supposed to call to invoke the method on the stash. ๐Ÿ’– and bestie, plot twist โ€” if autoloading is in the picture, that glob might literally be the one for AUTOLOAD. and in that case the matching variable $AUTOLOAD is already set up for you. no extra work, she's ready. โœจ

the third parameter of gv_fetchmethod_autoload is the vibe check on whether the AUTOLOAD lookup even happens when the method you asked for isn't there:

  • non-zero means yesss, go look for AUTOLOAD ๐Ÿ”
  • zero means no, don't bother looking for AUTOLOAD ๐Ÿ™…โ€โ™€๏ธ

and calling gv_fetchmethod is exactly the same as calling gv_fetchmethod_autoload with a non-zero autoload parameter. same thing, different font. ๐Ÿ’…

these functions also grant the SUPER token as a prefix of the method name. iconic of them honestly.

โš ๏ธ now listen, because this is the part that lowkey matters: if you want to keep the returned glob for a long time, you need to check whether it's AUTOLOAD โ€” because at some later time the call may load a different subroutine, on account of $AUTOLOAD changing its value. use the glob that got created as a side effect to do that check. ๐Ÿ‘‘

these functions have the same side-effects as gv_fetchmeth with level==0. and the warning against passing the GV that gv_fetchmeth gave you to call_sv? yeah, that applies to these too. equally. no exemptions, sorry bestie. ๐Ÿ˜ญ

GV *       gv_fetchmethod         (      NOCHECK HV *stash,
                                         const char *name)
GV *  Perl_gv_fetchmethod         (pTHX_ NOCHECK HV *stash,
                                         const char *name)
GV *       gv_fetchmethod_autoload(      NOCHECK HV *stash,
                                         const char *name,
                                         I32 autoload)
GV *  Perl_gv_fetchmethod_autoload(pTHX_ NOCHECK HV *stash,
                                         const char *name,
                                         I32 autoload)

๐ŸŒธ "gv_fetchpv" ๐Ÿฆ‹ "gv_fetchpvn" ๐Ÿฆ‹ "gv_fetchpvn_flags" ๐Ÿฆ‹ "gv_fetchpvs" ๐Ÿฆ‹ "gv_fetchsv" ๐Ÿฆ‹ "gv_fetchsv_nomg" ๐ŸŒธ

all of these return the GV of type sv_type whose name is whatever you fed in as the inputs โ€” or NULL if no GV with that name and that type could be found. ๐Ÿ’€ if you want the lore on stashes and globs, go read "Stashes and Globs" in perlguts. ๐Ÿ“š

the only differences between them are:

  • how the input name is specified, and
  • whether 'get' magic is normally used in getting that name. โœจ
๐Ÿ™ˆ don't get fooled by the fact that only one of these forms has flags right there in its name!! they all have a flags parameter in fact, and all the flag bits have the same meanings for all

so here's the flag tea ๐Ÿต:

  • if any of the flags GV_ADD, GV_ADDMG, GV_ADDWARN, GV_ADDMULTI, or GV_NOINIT is set, a GV gets created if none already exists for the input name and type. ๐Ÿ’…
  • but GV_ADDMG will only do that creation for magical GV's. she's picky. โœจ
  • for all of these flags except GV_NOINIT, gv_init_pvn is called after the addition.
  • GV_ADDWARN is what you use when the caller is expecting that adding won't be necessary, because the symbol should already exist โ€” but if it doesn't, add it anyway, with a warning that it was unexpectedly absent. ๐Ÿ˜ฌ
  • GV_ADDMULTI means pretend the GV has been seen before โ€” i.e., suppress those "Used once" warnings. ๐ŸŽ€
  • the flag GV_NOADD_NOINIT causes gv_init_pvn not be to called if the GV existed but isn't PVGV.
  • if the SVf_UTF8 bit is set, the name is treated as being encoded in UTF-8; otherwise the name won't be considered to be UTF-8 in the pv-named forms, and the UTF-8ness of the underlying SVs will be used in the sv forms. ๐Ÿฆ‹
  • if the flag GV_NOTQUAL is set, the caller is warranting that the input name is a plain symbol name, not qualified with a package โ€” otherwise the name gets checked for being a qualified one. ๐Ÿ”

and the per-form deets:

  • in gv_fetchpv, nambeg is a C string, NUL-terminated with no intermediate NULs. ๐Ÿšซ
  • in gv_fetchpvs, name is a literal C string, enclosed in double quotes. โœจ
  • gv_fetchpvn and gv_fetchpvn_flags are identical. in these, nambeg is a Perl string whose byte length is given by full_len, and it may contain embedded NULs. ๐Ÿ’–
  • in gv_fetchsv and gv_fetchsv_nomg, the name is extracted from the PV of the input name SV. the only difference between these two forms is that 'get' magic is normally done on name in gv_fetchsv, and always skipped with gv_fetchsv_nomg. and btw, including GV_NO_SVGMAGIC in the flags parameter to gv_fetchsv makes it behave identically to gv_fetchsv_nomg. ๐Ÿ˜Œ
GV *       gv_fetchpv       (      const char *nambeg, I32 flags,
                                   const svtype sv_type)
GV *  Perl_gv_fetchpv       (pTHX_ const char *nambeg, I32 flags,
                                   const svtype sv_type)
GV *       gv_fetchpvn      (      const char * nambeg,
                                   STRLEN full_len, I32 flags,
                                   const svtype sv_type)
GV *       gv_fetchpvn_flags(      const char *nambeg,
                                   STRLEN len, I32 flags,
                                   const svtype sv_type)
GV *  Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg,
                                   STRLEN len, I32 flags,
                                   const svtype sv_type)
GV *       gv_fetchpvs      (      "name", I32 flags,
                                   const svtype sv_type)
GV *       gv_fetchsv       (      SV *name, I32 flags,
                                   const svtype sv_type)
GV *  Perl_gv_fetchsv       (pTHX_ SV *name, I32 flags,
                                   const svtype sv_type)
GV *       gv_fetchsv_nomg  (      SV *name, I32 flags,
                                   const svtype sv_type)

๐ŸŽ€ "gv_fullname3*" &nbsp;๐Ÿ’œ&nbsp; "gv_fullname4*" ๐ŸŽ€

described under "gv_efullname3". ๐Ÿ‘€ go look there bestie, they're literally the same girlies.


๐ŸŒˆ "gv_HVadd*" ๐ŸŒˆ

described under "gv_AVadd". ๐Ÿ’– yep, same situation โ€” go read that one.


๐Ÿ‘‘ "gv_init" โœจ "gv_init_pv" โœจ "gv_init_pvn" โœจ "gv_init_sv" ๐Ÿ‘‘

these each convert a scalar into a typeglob. and no cap, it's an incoercible typeglob โ€” so assigning a reference to it will assign to one of its slots, instead of overwriting it like what happens with the typeglobs you get from SvSetSV. ๐Ÿ’…

โš ๏ธ converting any scalar that is SvOK() may produce unpredictable results and is reserved for perl's internal use. so like, don't. fr fr. ๐Ÿ˜ญ

they differ only in how the name is specified, and gv_init lacks a flags parameter โ€” she has a boolean multi parameter instead. ๐Ÿซถ

  • gv is the scalar to be converted. โœจ
  • stash is the parent stash/package, if any; or NULL if none. ๐ŸŒธ
  • in gv_init and gv_init_pvn, name points to the first byte of the string specifying the name, and an additional parameter, len, specifies its length in bytes. hence, name may contain embedded-NUL characters. ๐Ÿฆ‹

the name must be unqualified โ€” meaning it must not include the package name. if gv is a stash element, it is the caller's responsibility to make sure the name passed to this function matches the name of the element. if it does not match, perl's internal bookkeeping will get out of sync. ๐Ÿ’€๐Ÿ’€

gv_init_pv is identical to gv_init_pvn, but takes a NUL-terminated string for the name instead of separate char * and length parameters. ๐Ÿ˜Œ

in gv_init_sv, name is an SV, and the name is the PV extracted from that using SvPV. โœจ

All of these except gv_init take a flags parameter. Set flags to include SVf_UTF8 if name is a UTF-8 string, bestie. In gv_init_sv, if SvUTF8(sv) is non-zero, name is also gonna be considered a UTF-8 string. Lowkey tho โ€” passing that particular flag to gv_init_sv is not a good idea, because it would potentially override the (presumaby known) state of sv. ๐Ÿซ 

flags can also take the GV_ADDMULTI flag, which basically means "pretend we've already seen this GV before" (i.e., suppress those "Used once" warnings). ๐Ÿ’…

gv_init is the old form of gv_init_pvn. It does NOT work with UTF-8 strings, since it has no flags parameter. Setting the multi parameter to non-zero has the same effect as setting the GV_ADDMULTI flag in the other forms.

void       gv_init    (      GV *gv, HV *stash, const char *name,
                             STRLEN len, int multi)
void  Perl_gv_init    (pTHX_ GV *gv, HV *stash, const char *name,
                             STRLEN len, int multi)
void       gv_init_pv (      GV *gv, HV *stash, const char *name,
                             U32 flags)
void  Perl_gv_init_pv (pTHX_ GV *gv, HV *stash, const char *name,
                             U32 flags)
void       gv_init_pvn(      GV *gv, HV *stash, const char *name,
                             STRLEN len, U32 flags)
void  Perl_gv_init_pvn(pTHX_ GV *gv, HV *stash, const char *name,
                             STRLEN len, U32 flags)
void       gv_init_sv (      GV *gv, HV *stash, SV *namesv,
                             U32 flags)
void  Perl_gv_init_sv (pTHX_ GV *gv, HV *stash, SV *namesv,
                             U32 flags)

โœจ gv_IOadd* โœจ

Described under gv_AVadd. ๐ŸŽ€


๐ŸŽ€ gv_name_set ๐ŸŽ€

Set the name for GV gv to name, which is len bytes long. So yeah โ€” it can contain embedded NUL characters. Not a vibe killer, just a fact. ๐Ÿ’…

If flags contains SVf_UTF8, the name is treated as being encoded in UTF-8; otherwise it's not.

void       gv_name_set(      GV *gv, const char *name, U32 len,
                             U32 flags)
void  Perl_gv_name_set(pTHX_ GV *gv, const char *name, U32 len,
                             U32 flags)

๐ŸŒธ gv_stashpv, gv_stashpvn, gv_stashpvs, gv_stashsv ๐ŸŒธ

Heads up bestie: gv_stashsv is strongly preferred for performance reasons. The perf girlies know. โœจ

These each return a pointer to the stash for a specified package.

  • In gv_stashsv, the package is specified by sv.
  • In gv_stashpvs, the package is specified by the literal C string enclosed in double quotes.
  • In the other forms, name specifies the package. In gv_stashpvn, namelen gives the length of the name in bytes, so it may include embedded NUL characters. In gv_stashpv, name ends at the first NUL character.

flags is passed to gv_fetchpvn_flags(), so if you set it to GV_ADD then the package will be created if it does not already exist. And if the package doesn't exist and flags is 0 (or any other setting that doesn't create packages), then NULL gets returned. ๐Ÿ˜ญ

Flags may be one of:

GV_ADD           Create and initialize the package if doesn't
                 already exist
GV_NOADD_NOINIT  Don't create the package,
GV_ADDMG         GV_ADD iff the GV is magical
GV_NOINIT        GV_ADD, but don't initialize
GV_NOEXPAND      Don't expand SvOK() entries to PVGV
SVf_UTF8         The name is in UTF-8

The most important of which are probably GV_ADD and SVf_UTF8. ๐Ÿ‘‘

HV *       gv_stashpv (      const char *name, I32 flags)
HV *  Perl_gv_stashpv (pTHX_ const char *name, I32 flags)
HV *       gv_stashpvn(      const char *name, U32 namelen,
                             I32 flags)
HV *  Perl_gv_stashpvn(pTHX_ const char *name, U32 namelen,
                             I32 flags)
HV*        gv_stashpvs(      "name", I32 create)
HV *       gv_stashsv (      SV *sv, I32 flags)
HV *  Perl_gv_stashsv (pTHX_ SV *sv, I32 flags)

๐Ÿฆ‹ gv_SVadd* ๐Ÿฆ‹

Described under gv_AVadd.


๐Ÿ’– GvAV ๐Ÿ’–

Return the AV from the GV.

AV*  GvAV(GV* gv)

๐Ÿ’– GvCV ๐Ÿ’–

Return the CV from the GV.

CV*  GvCV(GV* gv)

๐Ÿ’– GvHV ๐Ÿ’–

Return the HV from the GV.

HV*  GvHV(GV* gv)

โญ GvREFCNT_inc, GvREFCNT_inc_simple, GvREFCNT_inc_simple_NN โญ

These all increment the reference count of the given SV, which must be a GV. They're lowkey iconic when you're assigning the result into a typed pointer, because they save you from having to cast the result to the appropriate type. So convenient, fr fr. ๐Ÿ’…

GV *  GvREFCNT_inc          (GV *gv)
GV *  GvREFCNT_inc_simple   (GV *gv)
GV *  GvREFCNT_inc_simple_NN(GV *gv)

๐ŸŽ€ GvSV ๐ŸŽ€

Return the SV from the GV.

Use GvSVn if you wish to create an empty scalar when the SV slot is empty. โœจ

SV*  GvSV(GV* gv)

๐ŸŽ€ GvSVn ๐ŸŽ€

Like GvSV, but it creates an empty scalar if none already exists. Iconic behaviour, honestly.

SV*  GvSVn(GV* gv)

๐ŸŒˆ newGVgen, newGVgen_flags ๐ŸŒˆ

Create a new, guaranteed-to-be-unique GV in the package given by the NUL-terminated C language string pack, and return a pointer to it. Unique GV, no cap.

For newGVgen, or if flags in newGVgen_flags is 0, pack is to be considered encoded in Latin-1. The only other legal flags value is SVf_UTF8, which says pack is to be considered encoded in UTF-8.

GV *       newGVgen      (      const char *pack)
GV *  Perl_newGVgen      (pTHX_ const char *pack)
GV *       newGVgen_flags(      const char *pack, U32 flags)
GV *  Perl_newGVgen_flags(pTHX_ const char *pack, U32 flags)

๐Ÿ‘‘ PL_curstash ๐Ÿ‘‘

The stash for the package code will be compiled into. Main character stash tbh. โœจ

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy.

HV*  PL_curstash

๐Ÿ‘‘ PL_defgv ๐Ÿ‘‘

The GV representing *_. Super useful for access to $_. ๐Ÿ’–

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy.

GV *  PL_defgv

โœจ PL_defoutgv โœจ

See setdefout.


โœจ PL_defstash โœจ

Described in perlguts.


๐ŸŒธ save_gp ๐ŸŒธ

Saves the current GP of gv on the save stack to be restored on scope exit.

If empty is true, replace the GP with a new GP.

If empty is false, mark gv with GVf_INTRO so the next reference assigned is localized, which is how local *foo = $someref; works. ๐Ÿช„

void       save_gp(      GV *gv, I32 empty)
void  Perl_save_gp(pTHX_ GV *gv, I32 empty)

๐ŸŽ€ setdefout ๐ŸŽ€

Sets PL_defoutgv, the default file handle for output, to the passed-in typeglob. Since PL_defoutgv "owns" a reference on its typeglob, the reference count of the passed-in typeglob gets increased by one, and the reference count of the typeglob that PL_defoutgv points to gets decreased by one. Math is mathing. ๐Ÿ’…

void       setdefout(      GV *gv)
void  Perl_setdefout(pTHX_ GV *gv)

๐Ÿ’… Hook manipulation

okay bestie, these functions are the whole plug-and-play kit for messing with hook variables, and they're convenient AND thread-safe, which is giving main character energy fr fr. โœจ


๐ŸŽ€ rcpv_copy

Refcount-increments a shared memory refcounted string, and when the refcount hits 0 it frees it using PerlMemShared_free().

It is the caller's responsibility to make sure that the pv is the result of a rcpv_new() call. Like, don't just hand it a random string, that's not the vibe. ๐Ÿ˜ญ

Returns the same pointer that was passed in.

 new = rcpv_copy(pv);
 char *       rcpv_copy(      char * const pv)
 char *  Perl_rcpv_copy(pTHX_ char * const pv)

๐Ÿงš rcpv_free

Refcount-decrements a shared memory refcounted string, and when the refcount hits 0 it frees it using perlmemshared_free().

it is the callers responsibility to ensure that the pv is the result of a rcpv_new() call.

Always returns NULL, so you can use it all cute like this:

 thing = rcpv_free(thing);
 char *       rcpv_free(      char * const pv)
 char *  Perl_rcpv_free(pTHX_ char * const pv)

๐Ÿฆ‹ rcpv_new

Creates a brand new shared memory refcounted string with the requested size, with the requested initialization and a refcount of 1. The actual space allocated will be 1 byte more than requested, and rcpv_new() will make sure that extra byte is a null no matter what your flags settings say. ๐Ÿ’…

If the RCPVf_NO_COPY flag is set, then the pv argument gets straight-up ignored ๐Ÿ™ˆ. Otherwise the contents of the pv pointer get copied into the new buffer โ€” or if it's NULL, the function does nothing and returns NULL.

If the RCPVf_USE_STRLEN flag is set, then the len argument is ignored and recomputed using strlen(pv). It is an error to combine RCPVf_USE_STRLEN and RCPVf_NO_COPY at the same time. pick one bestie, you can't have both ๐Ÿ˜ค

Under DEBUGGING, rcpv_new() will assert() if it's asked to create a 0 length shared string โ€” unless the RCPVf_ALLOW_EMPTY flag is set.

The return value is suitable for passing into rcpv_copy() and rcpv_free(). To access the RCPV * from the returned value, use the RCPVx() macro. The len member of the RCPV struct stores the allocated length (including the extra byte), but the RCPV_LEN() macro returns the requested length (not including the extra byte). slay โœจ

Note that rcpv_new() does NOT use a hash table or anything like that to dedupe inputs that have the same text content. Each call with a non-null pv parameter will produce a distinct pointer with its own refcount, no matter what the input content is. every call is unique, no twinning here ๐Ÿ‘‘

 char *       rcpv_new(      const char * const pv, STRLEN len,
                             U32 flags)
 char *  Perl_rcpv_new(pTHX_ const char * const pv, STRLEN len,
                             U32 flags)

โญ wrap_op_checker

Puts a C function into the chain of check functions for a specified op type. This is the preferred way to manipulate the PL_check array. ๐Ÿ’–

opcode specifies which type of op is to be affected. new_checker is a pointer to the C function that's gonna get added to that opcode's check chain, and old_checker_p points to the storage location where a pointer to the next function in the chain will be stored. The value of new_checker gets written into the PL_check array, while the value previously stored there gets written to *old_checker_p.

PL_check is global to an entire process, and a module wishing to hook op checking may find itself invoked more than once per process โ€” typically in different threads. To handle that whole situation, this function is idempotent. The location *old_checker_p must initially (once per process) contain a null pointer. A C variable of static duration (declared at file scope, typically also marked static to give it internal linkage) will be implicitly initialised appropriately, if it doesn't have an explicit initialiser. This function will only actually modify the check chain if it finds *old_checker_p to be null. This function is also thread safe on the small scale โ€” it uses appropriate locking to avoid race conditions in accessing PL_check. ๐Ÿ”’

When this function is called, the function referenced by new_checker must be ready to be called, except for *old_checker_p being unfilled. In a threading situation, new_checker may be called immediately, even before this function has returned. *old_checker_p will always be appropriately set before new_checker is called. If new_checker decides not to do anything special with an op that it's given (which is the usual case for most uses of op check hooking), it must chain the check function referenced by *old_checker_p.

Taken all together, XS code to hook an op checker should typically look something like this:

 static Perl_check_t nxck_frob;
 static OP *myck_frob(pTHX_ OP *op) {
     ...
     op = nxck_frob(aTHX_ op);
     ...
     return op;
 }
 BOOT:
     wrap_op_checker(OP_FROB, myck_frob, &nxck_frob);

If you want to influence compilation of calls to a specific subroutine, then use cv_set_call_checker_flags rather than hooking checking of all entersub ops. noted bestie, tools matter ๐Ÿ“

 void       wrap_op_checker(      Optype opcode,
                                  Perl_check_t new_checker,
                                  Perl_check_t *old_checker_p)
 void  Perl_wrap_op_checker(pTHX_ Optype opcode,
                                  Perl_check_t new_checker,
                                  Perl_check_t *old_checker_p)

๐ŸŒธ HV Handling

A HV structure represents a Perl hash. It's basically made of an array of pointers, each of which points to a linked list of HE structures. The array is indexed by the hash function of the key, so each linked list represents all the hash entries with the same hash value. Each HE contains a pointer to the actual value, plus a pointer to a HEK structure which holds the key and hash value. it's giving Very Organized Data Structure ๐Ÿ’…


๐Ÿ“ get_hv

Returns the HV of the specified Perl hash. flags get passed to gv_fetchpv. If GV_ADD is set and the Perl variable doesn't exist, then it will be created. If flags is zero (ignoring SVf_UTF8) and the variable doesn't exist, then NULL is returned.

NOTE: the perl_get_hv() form is deprecated. ๐Ÿ’€
 HV *       get_hv(      const char *name, I32 flags)
 HV *  Perl_get_hv(pTHX_ const char *name, I32 flags)

๐Ÿ’œ HE

Described in perlguts. go read it bestie ๐Ÿ“š


๐ŸŒˆ HEf_SVKEY

This flag โ€” used in the length slot of hash entries and magic structures โ€” specifies that the structure contains an SV* pointer where a char* pointer is to be expected. (For information only โ€” not to be used). like, look but don't touch ๐Ÿ™ˆ


๐ŸŽ€ HeHASH

Returns the computed hash stored in the hash entry.

 U32  HeHASH(HE* he)

โœจ HeKEY

Returns the actual pointer stored in the key slot of the hash entry. The pointer may be either char* or SV*, depending on the value of HeKLEN(). Can be assigned to. The HePV() or HeSVKEY() macros are usually preferable for finding the value of a key.

 void*  HeKEY(HE* he)

๐Ÿฆ‹ HeKLEN

If this is negative, and amounts to HEf_SVKEY, it indicates the entry holds an SV* key. Otherwise, it holds the actual length of the key. Can be assigned to. The HePV() macro is usually preferable for finding key lengths.

 STRLEN  HeKLEN(HE* he)

๐Ÿ’– HePV

Returns the key slot of the hash entry as a char* value, doing any necessary dereferencing of possibly SV* keys. The length of the string is placed in len (this is a macro, so do not use &len). If you don't care about what the length of the key is, you may use the global variable PL_na, though this is rather less efficient than using a local variable. Remember though, that hash keys in perl are free to contain embedded nulls, so using strlen() or similar is not a good way to find the length of hash keys. This is very similar to the SvPV() macro described elsewhere in this document. See also HeUTF8.

If you're using HePV to get values to pass to newSVpvn() to create a new SV, you should consider using newSVhek(HeKEY_hek(he)) as it is more efficient. glow-up tip โœจ

 char*  HePV(HE* he, STRLEN len)

๐ŸŒธ HeSVKEY

Returns the key as an SV*, or NULL if the hash entry doesn't contain an SV* key.

 SV*  HeSVKEY(HE* he)

๐Ÿงš HeSVKEY_force

Returns the key as an SV*. Will create and return a temporary mortal SV* if the hash entry contains only a char* key.

 SV*  HeSVKEY_force(HE* he)

๐Ÿ’… HeSVKEY_set

Sets the key to a given SV*, taking care to set the appropriate flags to indicate the presence of an SV* key, and returns the same SV*.

 SV*  HeSVKEY_set(HE* he, SV* sv)

โญ HeUTF8

Returns whether the char * value returned by HePV is encoded in UTF-8, doing any necessary dereferencing of possibly SV* keys. The value returned will be 0 or non-0, not necessarily 1 (or even a value with any low bits set), so do not blindly assign this to a bool variable, as bool may be a typedef for char. i'm serious bestie, don't do it ๐Ÿ˜ญ

 U32  HeUTF8(HE* he)

๐ŸŽ€ HeVAL

Returns the value slot (type SV*) stored in the hash entry. Can be assigned to.

 SV *foo= HeVAL(he);
 HeVAL(he)= sv;
 SV*  HeVAL(HE* he)

๐Ÿ’œ HV

Described in perlguts. again with the perlguts, we love a reference ๐Ÿ“–


๐ŸŒˆ hv_assert

Check that a hash is in an internally consistent state.

 void  Perl_hv_assert(pTHX_ HV *hv)

๐Ÿ“ hv_bucket_ratio

NOTE: hv_bucket_ratio is experimental and may change or be removed without notice. ๐Ÿ‘€

If the hash is tied, dispatches through to the SCALAR tied method. Otherwise, if the hash contains no keys, returns 0. Otherwise, returns a mortal sv containing a string specifying the number of used buckets, followed by a slash, followed by the number of available buckets.

This function is expensive โ€” it must scan all of the buckets to determine which are used, and the count is NOT cached. In a large hash, this could be a lot of buckets. ๐Ÿ’€

 SV *       hv_bucket_ratio(      HV *hv)
 SV *  Perl_hv_bucket_ratio(pTHX_ HV *hv)

๐Ÿงš hv_clear

Frees all the elements of a hash, leaving it empty. The XS equivalent of %hash = (). See also hv_undef.

See av_clear for a note about the hash possibly being invalid on return. โš ๏ธ

 void       hv_clear(      HV *hv)
 void  Perl_hv_clear(pTHX_ HV *hv)

and that's where we pause bestie, more coming ๐Ÿ’–

๐ŸŒธ hv_clear_placeholders ๐ŸŒธ

Okay so bestie, picture a restricted hash โ€” one where some keys got marked readonly. Now imagine somebody deletes one of those readonly keys. The key does not actually get deleted. Instead it gets marked by being assigned a value of &PL_sv_placeholder. That's the tag it wears so future operations (like iterating over the whole hash, bestie, you know the vibe) will just ๐Ÿ‘€ skip right past it โ€” but the hash can still bless that key with a real value again somewhere down the line if it wants.

What hv_clear_placeholders does is exactly what it says on the tin: it clears any such placeholder keys right out of the hash. โœจ

If you wanna see a real-life example of this in action, go peek at Hash::Util::lock_keys(). ๐Ÿ‘‘

 void       hv_clear_placeholders(      HV *hv)
 void  Perl_hv_clear_placeholders(pTHX_ HV *hv)

๐Ÿฆ‹ hv_copy_hints_hv ๐Ÿฆ‹

This one is a specialised version of newHVhv made specifically for copying %^H. So extra. ๐Ÿ’…

Here's the tea:

  • ohv has to be a pointer to a hash (it may have %^H magic, but ngl it should be generally non-magical), or it can be NULL โ€” and if you pass NULL, it's interpreted as an empty hash. No notes.
  • The content of ohv gets copied into a new hash, and that new hash gets the %^H-specific magic added to it. Glow-up included. โœจ
  • A pointer to the new hash is returned. ๐ŸŽ€
 HV *       hv_copy_hints_hv(      HV * const ohv)
 HV *  Perl_hv_copy_hints_hv(pTHX_ HV * const ohv)

๐Ÿ’– hv_delete, hv_deletes, hv_delete_ent ๐Ÿ’–

All three of these delete a key/value pair out of the hash. The value's SV gets removed from the hash, made mortal, and handed right back to whoever called. ๐Ÿซด

How each one wants its key:

  • In hv_deletes, the key has to be a C language string literal, enclosed in double quotes. It is never treated as being in UTF-8. And nope, there is no length parameter. Keep it simple, babe.
  • In hv_delete, the absolute value of klen is the length of the key โ€” which means, yes, the key can contain embedded NUL characters, go off. ๐Ÿ”ฅ If klen is negative, the key is assumed to be in UTF-8-encoded Unicode.
  • In hv_delete_ent, the key is the PV inside keysv, including its length and its UTF8ness. And hash? That can be a valid precomputed hash value, or 0 if you want it to just compute one for you.

For all three, flags will normally be zero. If you set it to G_DISCARD, then NULL gets returned. And NULL also comes back if the key just isn't found. It's giving ghosted. ๐Ÿ˜ญ

 SV *       hv_delete    (      HV *hv, const char *key, I32 klen,
                                I32 flags)
 SV *  Perl_hv_delete    (pTHX_ HV *hv, const char *key, I32 klen,
                                I32 flags)
 SV *       hv_deletes   (      HV *hv, "key", U32 flags)
 SV *       hv_delete_ent(      HV *hv, SV *keysv, I32 flags,
                                U32 hash)
 SV *  Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags,
                                U32 hash)

โœจ hv_exists, hv_existss, hv_exists_ent โœจ

These three each return a boolean telling you whether the specified hash key exists. The only difference between them is how you get to specify the key.

  • In hv_existss, the key must be a C language string literal in double quotes. It is never treated as being in UTF-8. There is no length parameter.
  • In hv_exists, the absolute value of klen is the length of the key. If klen is negative, the key is assumed to be UTF-8-encoded Unicode. And key may absolutely contain embedded NUL characters. ๐Ÿ’…
  • In hv_exists_ent, the key is specified by the SV keysv, and its UTF8ness is the same as that SV's. There's an extra parameter here, hash, which can be a valid precomputed hash value, or 0 to ask for it to be computed.
 bool       hv_exists    (      HV *hv, const char *key, I32 klen)
 bool  Perl_hv_exists    (pTHX_ HV *hv, const char *key, I32 klen)
 bool       hv_existss   (      HV *hv, "key")
 bool       hv_exists_ent(      HV *hv, SV *keysv, U32 hash)
 bool  Perl_hv_exists_ent(pTHX_ HV *hv, SV *keysv, U32 hash)

๐Ÿ’€ hv_fetch, hv_fetchs, hv_fetch_ent ๐Ÿ’€

These each return the value entry in a hash that corresponds to the specified key. Lovely.

First, the boring-but-crucial bit: in all of them, if <hv> is NULL, then NULL is returned. That's it, that's the rule.

They differ mainly in how you specify the key, and in the form of what you get back. Let's break it down:

  • In hv_fetchs, the key must be a C language string literal, enclosed in double quotes. It is never treated as being in UTF-8. There is no length parameter.
  • In hv_fetch, key is either NULL or points to the first byte of the string specifying the key, and its length in bytes is given by the absolute value of an additional parameter, klen. A NULL key means the key is to be treated as undef, and klen is ignored. A non-NULL key may contain embedded-NUL characters. If klen is negative, key is treated as being encoded in UTF-8; otherwise not.
  • In hv_fetch_ent, the key is stored in the SV keysv, which this function extracts using SvPV_const. The key has the same UTF8ness as keysv.

Now the return values, because bestie this is the part where people get caught slipping:

The value entry returned by hv_fetch and hv_fetchs is an SV**. Always check that the return value is non-null before you dereference it to an SV*. Fr fr, do not skip this. ๐Ÿšจ

The value entry returned by hv_fetch_ent is a pointer to a HE structure with all fields set. But heads up: when hv is a tied hash, the HE structure lives in a static location โ€” so if you need to store it somewhere, make a copy of the structure. Also, for MAGICAL hashes, the hent_val field in the returned HE structure will be a mortal sv.

In all of them, if lval is non-zero, then the fetch is part of a store. What that means: if there's no value in the hash associated with the given key, then an SV* is created, and you can reach it through the returned value. โœจ

For more on how to use these functions on tied hashes, go read "Understanding the Magic of Tied Hashes and Arrays" in perlguts.

And finally, hv_fetch_ent has that extra parameter, hash. It has to be a valid precomputed hash number for the given key, or 0 if you want the function to compute it for you.

 SV **       hv_fetch    (      HV *hv, const char *key, I32 klen,
                                I32 lval)
 SV **  Perl_hv_fetch    (pTHX_ HV *hv, const char *key, I32 klen,
                                I32 lval)
 SV**        hv_fetchs   (      HV* hv, "key", I32 lval)
 HE *        hv_fetch_ent(      HV *hv, SV *keysv, I32 lval,
                                U32 hash)
 HE *   Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval,
                                U32 hash)

๐ŸŽ€ hv_iterinit ๐ŸŽ€

Sets up a starting point so you can traverse a hash table. Adventure time, bestie. ๐Ÿ—บ๏ธ

It returns the number of keys in the hash, including placeholders โ€” i.e. the same as HvTOTALKEYS(hv). Just know that the return value is currently only meaningful for hashes without tie magic. ๐Ÿคท

NOTE: Before version 5.004_65, hv_iterinit used to return the number of hash buckets that happen to be in use. If you still need that esoteric little value, you can get it through the macro HvFILL(hv).
 I32       hv_iterinit(      HV *hv)
 I32  Perl_hv_iterinit(pTHX_ HV *hv)

๐Ÿงš hv_iterkey, hv_iterkeysv ๐Ÿงš

These each return the key from wherever the hash iterator is currently pointing. See hv_iterinit.

They differ in the form of the return value:

  • hv_iterkey returns a C language NUL-terminated string.
  • hv_iterkeysv returns a mortal SV* containing a copy of the key. Note that this is unlike "hv_iterval", whose return isn't mortalized. So don't get it twisted. ๐Ÿ’…
 char *       hv_iterkey  (      HE *entry, I32 *retlen)
 char *  Perl_hv_iterkey  (pTHX_ HE *entry, I32 *retlen)
 SV *         hv_iterkeysv(      HE *entry)
 SV *    Perl_hv_iterkeysv(pTHX_ HE *entry)

๐ŸŒˆ hv_iternext, hv_iternext_flags ๐ŸŒˆ

NOTE: hv_iternext_flags is experimental and may change or be removed without notice. You've been warned, babe.

These each return entries from a hash iterator. See hv_iterinit.

Here's a genuinely useful bit: you may call hv_delete or hv_delete_ent on the hash entry your iterator is currently pointing at, without losing your place or invalidating the iterator. Iconic behaviour honestly. ๐Ÿซถ

But โ€” and this is important โ€” in that case the current entry is deleted from the hash while your iterator holds the last reference to it. Your iterator gets flagged to free the entry on the next call to hv_iternext, so you must not immediately discard your iterator, or else that entry will leak. Call hv_iternext to trigger the resource deallocation. Periodt.

hv_iternext_flags has an extra flags parameter, which will normally be zero. When it is zero, it behaves identically to hv_iternext. Cool.

But if the HV_ITERNEXT_WANTPLACEHOLDERS bit is set, then the placeholder keys (for restricted hashes) will be returned in addition to the normal keys. By default, placeholders are automatically skipped over.

Currently a placeholder is implemented with a value that is &PL_sv_placeholder. Note that the implementation of placeholders and restricted hashes may change, and the implementation currently is insufficiently abstracted for any change to be tidy. It's giving chaos, lowkey. ๐Ÿ˜ญ

 HE *       hv_iternext      (      HV *hv)
 HE *  Perl_hv_iternext      (pTHX_ HV *hv)
 HE *       hv_iternext_flags(      HV *hv, I32 flags)
 HE *  Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)

๐ŸŒธ hv_iternextsv ๐ŸŒธ

The multitasker. โœจ It performs an hv_iternext, an hv_iterkey, and an hv_iterval, all in one single operation. Efficiency queen.

 SV *       hv_iternextsv(      HV *hv, char **key, I32 *retlen)
 SV *  Perl_hv_iternextsv(pTHX_ HV *hv, char **key, I32 *retlen)

๐Ÿ’œ hv_iterval ๐Ÿ’œ

Returns the value from wherever the hash iterator is currently sitting.

Note that the return value is not mortalized โ€” unlike hv_iterkey, which is. Keep that distinction in your head, bestie, it matters. ๐Ÿง 

 SV *       hv_iterval(      HV *hv, HE *entry)
 SV *  Perl_hv_iterval(pTHX_ HV *hv, HE *entry)

โญ hv_ksplit โญ

Tries to grow the hash hv so it has at least newmax buckets available. Perl picks the actual number, because it's gonna do what's convenient for it. ๐Ÿ’…

It's the same as writing this in Perl code:

 keys %hv = newmax;
 void       hv_ksplit(      HV *hv, IV newmax)
 void  Perl_hv_ksplit(pTHX_ HV *hv, IV newmax)

๐Ÿ“ hv_magic ๐Ÿ“

Adds magic to a hash. See sv_magic. That's the whole vibe. โœจ

 void       hv_magic(      HV *hv, GV *gv, int how)
 void  Perl_hv_magic(pTHX_ HV *hv, GV *gv, int how)

๐Ÿ‘‘ hv_name_set, hv_name_sets ๐Ÿ‘‘

These each set the name of the stash hv to the specified name. Naming rights, unlocked. ๐ŸŽ€

They differ only in how the name gets specified:

  • In hv_name_sets, the name is a literal C string, enclosed in double quotes.
  • In hv_name_set, name points to the first byte of the name, and an additional parameter, len, specifies its length in bytes. Which means โ€” you guessed it โ€” the name may contain embedded NUL characters. ๐Ÿ’…

So yeah โ€” that means: if "SVf_UTF8" is set in flags, bestie, the name is treated as being in UTF-8. If it's not set, it's not. Simple as that. ๐Ÿ’–

And if "HV_NAME_SETALL" is set in flags, then both the name and the effective name get set. Fancy. ๐Ÿ‘‘

 void       hv_name_set (      HV *hv, const char *name, U32 len,
                               U32 flags)
 void  Perl_hv_name_set (pTHX_ HV *hv, const char *name, U32 len,
                               U32 flags)
 void       hv_name_sets(      HV *hv, "name", U32 flags)

hv_scalar โœจ

Evaluates the hash in scalar context and hands you back the result. That's it, that's the vibe. ๐Ÿฆ‹

When the hash is tied, it dispatches through to the SCALAR method. Otherwise it returns a mortal SV holding the number of keys in the hash. Periodt.

Girlies be warned: prior to 5.25, this function returned what is now returned by the hv_bucket_ratio() function. So don't go blaming me when your old code acts different. ๐Ÿ’€
 SV *       hv_scalar(      HV *hv)
 SV *  Perl_hv_scalar(pTHX_ HV *hv)

hv_store and hv_stores ๐Ÿ’…

These two each store the SV val with the specified key in the hash hv, returning NULL if the operation failed, or if the value did not need to be actually stored within the hash (classic tied-hash behaviour, you know the drill). Otherwise you can dereference the return value to get the original "SV*". ๐ŸŽ€

They differ only in how the hash key is specified. That's the whole tea.

In hv_stores, the key must be a C language string literal, wrapped up in double quotes. It is never treated as being in UTF-8. And there is no length parameter. Nope, none. ๐Ÿ™ˆ

In hv_store, key is either NULL or points to the first byte of the string specifying the key, and its length in bytes is given by the absolute value of an extra parameter, klen. A NULL key means the key is to be treated as undef, and klen is ignored. Otherwise, the key string may contain embedded-NUL bytes. And if klen is negative, the string is treated as being encoded in UTF-8; otherwise not. Got it? Good. ๐Ÿ’–

hv_store also has another extra parameter, hash โ€” a precomputed hash of the key string, or zero if it hasn't been precomputed. This parameter is omitted from hv_stores, since it gets computed automatically at compile time. Slay. ๐Ÿ”ฅ

If hv is NULL, NULL is returned and no action is taken. Nothing happens. The end. ๐Ÿ˜Œ

If val is NULL, it's treated as being undef. Otherwise, you (the caller) are responsible for suitably incrementing the reference count of val before the call, and decrementing it if the function returned NULL. Effectively, a successful hv_store takes ownership of one reference to val. This is usually exactly what you want: a newly created SV has a reference count of one, so if all your code does is create SVs and store them in a hash, hv_store will own the only reference to that new SV, and your code doesn't need to do anything further to tidy up. So chill. ๐Ÿงš

hv_store is not implemented as a call to "hv_store_ent", and it does not create a temporary SV for the key โ€” so if your key data isn't already in SV form, use hv_store in preference to hv_store_ent. iykyk.

See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more info on how to use this function on tied hashes. ๐Ÿช„

 SV **       hv_store (      HV *hv, const char *key, I32 klen,
                             SV *val, U32 hash)
 SV **  Perl_hv_store (pTHX_ HV *hv, const char *key, I32 klen,
                             SV *val, U32 hash)
 SV**        hv_stores(      HV *hv, "name", U32 flags)

hv_store_ent ๐ŸŒธ

Stores val in a hash. The hash key is specified as key. The hash parameter is the precomputed hash value; if it's zero, then Perl will compute it for you. ๐Ÿ’ซ

The return value is the new hash entry so created. It will be NULL if the operation failed, or if the value didn't need to be actually stored within the hash (again โ€” tied hashes, you know how it is). Otherwise, the contents of the return value can be accessed using the He? macros described here. ๐Ÿ“

Now listen: the caller is responsible for suitably incrementing the reference count of val before the call, and decrementing it if the function returned NULL. Effectively, a successful hv_store_ent takes ownership of one reference to val. Usually what you want! A newly created SV has a reference count of one, so if all your code does is create SVs and store them in a hash, hv_store will own the only reference to the new SV, and your code doesn't need to do anything further to tidy up. ๐Ÿซถ

But here's the plot twist: hv_store_ent only reads the key; unlike val, it does not take ownership of it. So maintaining the correct reference count on key is entirely the caller's responsibility. The reason it doesn't take ownership is that key is not used after this function returns, so it can be freed immediately. Efficient! ๐Ÿ’…

hv_store is not implemented as a call to hv_store_ent, and does not create a temporary SV for the key, so if your key data is not already in SV form, then use hv_store in preference to hv_store_ent.

See "Understanding the Magic of Tied Hashes and Arrays" in perlguts for more information on how to use this function on tied hashes. โœจ

 HE *       hv_store_ent(      HV *hv, SV *key, SV *val, U32 hash)
 HE *  Perl_hv_store_ent(pTHX_ HV *hv, SV *key, SV *val, U32 hash)

hv_stores* ๐ŸŽ€

Described under "hv_store". Go read that one, bestie. โฌ†๏ธ


hv_undef ๐Ÿ’€

Undefines the hash. This is the XS equivalent of undef(%hash).

As well as freeing all the elements of the hash (like hv_clear()), this also frees any auxiliary data and storage associated with the hash. Full cleanse. ๐ŸŒฟ

See "av_clear" for a note about the hash possibly being invalid on return. Yeah โ€” invalid. Be careful. ๐Ÿ˜ญ

 void       hv_undef(      HV *hv)
 void  Perl_hv_undef(pTHX_ HV *hv)

HvENAME ๐Ÿ‘‘

Returns the effective name of a stash, or NULL if there is none. The effective name represents a location in the symbol table where this stash resides. It gets updated automatically when packages are aliased or deleted. A stash that's no longer in the symbol table has no effective name. This name is preferable to HvNAME for use in MRO linearisations and isa caches. Noted. โœ๏ธ

 char*  HvENAME(HV* stash)

HvENAMELEN ๐Ÿ“

Returns the length of the stash's effective name. That's the whole thing.

 STRLEN  HvENAMELEN(HV *stash)

HvENAMEUTF8 ๐ŸŒˆ

Returns true if the effective name is in UTF-8 encoding.

 unsigned char  HvENAMEUTF8(HV *stash)

HvFILL ๐Ÿงฎ

Returns the number of hash buckets that happen to be in use.

As of perl 5.25, this function is used only for debugging purposes, and the number of used hash buckets is not in any way cached. So this function can be costly to execute, because it must iterate over all the buckets in the hash. Expensive behaviour, honestly. ๐Ÿ’ธ

 STRLEN  HvFILL(HV *const hv)

HvHasAUX ๐Ÿ”

Returns true if the HV has a "struct xpvhv_aux" extension. Use this to check whether it's valid to call HvAUX(). Vibe check before you touch anything. โœ…

 bool  HvHasAUX(HV *const hv)

HvNAME ๐Ÿท๏ธ

Returns the package name of a stash, or "NULL" if stash isn't a stash. See "SvSTASH" and "CvSTASH".

 char*  HvNAME(HV* stash)

HvNAMELEN ๐Ÿ“

Returns the length of the stash's name.

 STRLEN  HvNAMELEN(HV *stash)

HvNAMEUTF8 ๐Ÿฆ‹

Returns true if the name is in UTF-8 encoding.

 unsigned char  HvNAMEUTF8(HV *stash)

HvREFCNT_inc, HvREFCNT_inc_simple, HvREFCNT_inc_simple_NN ๐Ÿ’–

These all increment the reference count of the given SV, which must be a HV. They're useful when assigning the result into a typed pointer, because they avoid the need to cast the result to the appropriate type. So convenient, so iconic. โœจ

 HV *  HvREFCNT_inc          (HV *hv)
 HV *  HvREFCNT_inc_simple   (HV *hv)
 HV *  HvREFCNT_inc_simple_NN(HV *hv)

newHV ๐ŸŒฑ

Creates a new HV. The reference count is set to 1. Fresh out the box. ๐ŸŽ

 HV *       newHV()
 HV *  Perl_newHV(pTHX)

newHVhv ๐Ÿชž

The content of ohv is copied to a new hash. A pointer to the new hash is returned. Copy-paste but make it C. ๐Ÿ’ซ

 HV *       newHVhv(      HV *ohv)
 HV *  Perl_newHVhv(pTHX_ HV *ohv)

Nullhv โš ๏ธ

DEPRECATED! It is planned to remove Nullhv from a future release of Perl. Do not use it for new code; remove it from existing code. Like, genuinely. ๐Ÿšจ

Null HV pointer.

(deprecated - use "(HV *)NULL" instead)


PERL_HASH ๐Ÿ”

Described in perlguts.

 void  PERL_HASH(U32 hash, char *key, STRLEN klen)

PL_modglobal ๐ŸŒ

PL_modglobal is a general purpose, interpreter global HV for use by extensions that need to keep information on a per-interpreter basis. In a pinch, it can also be used as a symbol table for extensions to share data among each other. It's a good idea to use keys prefixed by the package name of the extension that owns the data. Manners, basically. ๐ŸŽ€

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy. Everyone gets their own. ๐Ÿงต

 HV*  PL_modglobal

๐Ÿ’พ Input/Output ๐Ÿ’พ


do_close ๐Ÿšช

Close an I/O stream. This implements Perl "close" in perlfunc.

gv is the glob associated with the stream.

is_explict is true if this is an explicit close of the stream; false if it's part of another operation, such as closing a pipe (which involves implicitly closing both ends). ๐Ÿšฐ

Returns true if successful; otherwise returns false and sets errno to indicate the cause. Rude, but informative.

 bool       do_close(      GV *gv, bool is_explicit)
 bool  Perl_do_close(pTHX_ GV *gv, bool is_explicit)

IoDIRP, IOf_FLUSH, IOf_UNTAINT, IoFLAGS, IoIFP, IoOFP, IoTYPE ๐Ÿฆ‹

Described in perlguts. All of them. Every single one. โœจ

 DIR *     IoDIRP (IO *io)
 U8        IoFLAGS(IO *io)
 PerlIO *  IoIFP  (IO *io)
 PerlIO *  IoOFP  (IO *io)
 char      IoTYPE (IO *io)

my_chsize ๐Ÿ“

The C library chsize(3) if available, or a Perl implementation of it. Whichever one shows up first. ๐Ÿ’…

 I32       my_chsize(      int fd, Off_t length)
 I32  Perl_my_chsize(pTHX_ int fd, Off_t length)

my_dirfd ๐Ÿ“‚

The C library "dirfd(3)" if available, or a Perl implementation of it, or die if not easily emulatable. Dramatic, but fair. ๐Ÿ’€

 int       my_dirfd(DIR *dir)
 int  Perl_my_dirfd(DIR *dir)

my_pclose ๐Ÿ”’

A wrapper for the C library pclose(3). Don't use the latter, bestie โ€” the Perl version knows things that interact with the rest of the perl interpreter. It's got lore. ๐Ÿ‘‘

 I32       my_pclose(      PerlIO *ptr)
 I32  Perl_my_pclose(pTHX_ PerlIO *ptr)

๐Ÿ’– my_popen

okay so my_popen is literally just a wrapper around the C library popen(3). and bestie, do not use the raw C one, because the Perl version knows โœจthingsโœจ that interact with the rest of the perl interpreter, and the plain one simply does not. she's the one with the lore.

PerlIO *       my_popen(      const char *cmd, const char *mode)
PerlIO *  Perl_my_popen(pTHX_ const char *cmd, const char *mode)

๐Ÿ‘‘ newIO

makes you a brand new IO and sets the reference count to 1. fresh new chapter, main character energy, we love to see it ๐Ÿซถ

IO *       newIO()
IO *  Perl_newIO(pTHX)

๐Ÿšฟ PERL_FLUSHALL_FOR_CHILD

this one defines a way to flush all output buffers. heads up though: that can be a performance issue, so we let people disable it if they want. also, when we're using stdio, there are straight-up broken implementations of fflush(NULL) out there in the wild โ€” Solaris being the most prominent ๐Ÿ’€ iconic behavior honestly.

void  PERL_FLUSHALL_FOR_CHILD

๐ŸŒˆ the whole PerlIO function girlies (round one)

bestie this is a big squad and they're all described in perlapio: PerlIO_apply_layers, PerlIO_binmode, PerlIO_canset_cnt, PerlIO_clearerr, PerlIO_close, PerlIO_debug, PerlIO_eof, PerlIO_error, PerlIO_exportFILE, PerlIO_fast_gets, PerlIO_fdopen, PerlIO_fileno, PerlIO_fill, PerlIO_findFILE, PerlIO_flush, PerlIO_get_base, PerlIO_get_bufsiz, PerlIO_get_cnt, PerlIO_get_ptr, PerlIO_getc, PerlIO_getpos, PerlIO_has_base, PerlIO_has_cntptr, PerlIO_importFILE, PerlIO_open, PerlIO_printf, PerlIO_putc, PerlIO_puts, PerlIO_read, PerlIO_releaseFILE, PerlIO_reopen, PerlIO_rewind, PerlIO_seek, PerlIO_set_cnt, PerlIO_set_ptrcnt, PerlIO_setlinebuf, PerlIO_setpos, PerlIO_stderr, PerlIO_stdin, PerlIO_stdout, PerlIO_stdoutf, PerlIO_tell, PerlIO_ungetc, PerlIO_unread, PerlIO_vprintf, and PerlIO_write.

and here's every single one of their signatures, verbatim, because we do not skip details in this house ๐Ÿ’…

int             PerlIO_apply_layers(pTHX_ PerlIO *f,
                                            const char *mode,
                                            const char *layers)
int             PerlIO_binmode     (pTHX_ PerlIO *f, int ptype,
                                            int imode,
                                            const char *layers)
int             PerlIO_canset_cnt  (      PerlIO *f)
void            PerlIO_clearerr    (      PerlIO *f)
void       Perl_PerlIO_clearerr    (pTHX_ PerlIO *f)
int             PerlIO_close       (      PerlIO *f)
int        Perl_PerlIO_close       (pTHX_ PerlIO *f)
void            PerlIO_debug       (      const char *fmt, ...)
int             PerlIO_eof         (      PerlIO *f)
int        Perl_PerlIO_eof         (pTHX_ PerlIO *f)
int             PerlIO_error       (      PerlIO *f)
int        Perl_PerlIO_error       (pTHX_ PerlIO *f)
FILE *          PerlIO_exportFILE  (      PerlIO *f,
                                            const char *mode)
int             PerlIO_fast_gets   (      PerlIO *f)
PerlIO *        PerlIO_fdopen      (      int fd,
                                            const char *mode)
int             PerlIO_fileno      (      PerlIO *f)
int        Perl_PerlIO_fileno      (pTHX_ PerlIO *f)
int             PerlIO_fill        (      PerlIO *f)
int        Perl_PerlIO_fill        (pTHX_ PerlIO *f)
FILE *          PerlIO_findFILE    (      PerlIO *f)
int             PerlIO_flush       (      PerlIO *f)
int        Perl_PerlIO_flush       (pTHX_ PerlIO *f)
STDCHAR *       PerlIO_get_base    (      PerlIO *f)
STDCHAR *  Perl_PerlIO_get_base    (pTHX_ PerlIO *f)
SSize_t         PerlIO_get_bufsiz  (      PerlIO *f)
SSize_t    Perl_PerlIO_get_bufsiz  (pTHX_ PerlIO *f)
SSize_t         PerlIO_get_cnt     (      PerlIO *f)
SSize_t    Perl_PerlIO_get_cnt     (pTHX_ PerlIO *f)
STDCHAR *       PerlIO_get_ptr     (      PerlIO *f)
STDCHAR *  Perl_PerlIO_get_ptr     (pTHX_ PerlIO *f)
int             PerlIO_getc        (      PerlIO *d)
int             PerlIO_getpos      (      PerlIO *f, SV *save)
int             PerlIO_has_base    (      PerlIO *f)
int             PerlIO_has_cntptr  (      PerlIO *f)
PerlIO *        PerlIO_importFILE  (      FILE *stdio,
                                            const char *mode)
PerlIO *        PerlIO_open        (      const char *path,
                                            const char *mode)
int             PerlIO_printf      (      PerlIO *f,
                                            const char *fmt, ...)
int             PerlIO_putc        (      PerlIO *f, int ch)
int             PerlIO_puts        (      PerlIO *f,
                                            const char *string)
SSize_t         PerlIO_read        (      PerlIO *f, void *vbuf,
                                            Size_t count)
SSize_t    Perl_PerlIO_read        (pTHX_ PerlIO *f, void *vbuf,
                                            Size_t count)
void            PerlIO_releaseFILE (      PerlIO *f, FILE *stdio)
PerlIO *        PerlIO_reopen      (      const char *path,
                                            const char *mode,
                                            PerlIO *old)
void            PerlIO_rewind      (      PerlIO *f)
int             PerlIO_seek        (      PerlIO *f,
                                            Off_t offset,
                                            int whence)
int        Perl_PerlIO_seek        (pTHX_ PerlIO *f,
                                            Off_t offset,
                                            int whence)
void            PerlIO_set_cnt     (      PerlIO *f, SSize_t cnt)
void       Perl_PerlIO_set_cnt     (pTHX_ PerlIO *f, SSize_t cnt)
void            PerlIO_set_ptrcnt  (      PerlIO *f,
                                            STDCHAR *ptr,
                                            SSize_t cnt)
void       Perl_PerlIO_set_ptrcnt  (pTHX_ PerlIO *f,
                                            STDCHAR *ptr,
                                            SSize_t cnt)
void            PerlIO_setlinebuf  (      PerlIO *f)
void       Perl_PerlIO_setlinebuf  (pTHX_ PerlIO *f)
int             PerlIO_setpos      (      PerlIO *f, SV *saved)
PerlIO *        PerlIO_stderr      ()
PerlIO *   Perl_PerlIO_stderr      (pTHX)
PerlIO *        PerlIO_stdin       ()
PerlIO *   Perl_PerlIO_stdin       (pTHX)
PerlIO *        PerlIO_stdout      ()
PerlIO *   Perl_PerlIO_stdout      (pTHX)
int             PerlIO_stdoutf     (      const char *fmt, ...)
Off_t           PerlIO_tell        (      PerlIO *f)
Off_t      Perl_PerlIO_tell        (pTHX_ PerlIO *f)
int             PerlIO_ungetc      (      PerlIO *f, int ch)
SSize_t         PerlIO_unread      (      PerlIO *f,
                                            const void *vbuf,
                                            Size_t count)
SSize_t    Perl_PerlIO_unread      (pTHX_ PerlIO *f,
                                            const void *vbuf,
                                            Size_t count)
int             PerlIO_vprintf     (      PerlIO *f,
                                            const char *fmt,
                                            va_list args)
SSize_t         PerlIO_write       (      PerlIO *f,
                                            const void *vbuf,
                                            Size_t count)
SSize_t    Perl_PerlIO_write       (pTHX_ PerlIO *f,
                                            const void *vbuf,
                                            Size_t count)

๐ŸŽ€ PERLIO_F_* flags

all of these cuties are described in perliol: PERLIO_F_APPEND, PERLIO_F_CANREAD, PERLIO_F_CANWRITE, PERLIO_F_CRLF, PERLIO_F_EOF, PERLIO_F_ERROR, PERLIO_F_FASTGETS, PERLIO_F_LINEBUF, PERLIO_F_OPEN, PERLIO_F_RDBUF, PERLIO_F_TEMP, PERLIO_F_TRUNCATE, PERLIO_F_UNBUF, PERLIO_F_UTF8, and PERLIO_F_WRBUF.

yeah that's a lot of flags, and yeah we listed every single one, because skipping them would be a crime ๐Ÿ™ˆ


๐Ÿฆ‹ more PerlIO girlies

PerlIO_fast_gets*, PerlIO_fdopen*, PerlIO_fileno*, PerlIO_fill*, PerlIO_findFILE*, and PerlIO_flush* โ€” all described in perlapio.


๐ŸŒŸ PERLIO_FUNCS_CAST

casts the pointer func so it's of type PerlIO_funcs *. it's giving type-safety, it's giving glow-up โœจ

PerlIO_funcs *  PERLIO_FUNCS_CAST(PerlIO * func)

๐Ÿงš PERLIO_FUNCS_DECL

declares ftab to be a PerlIO function table, which like, is to say, of type PerlIO_funcs. manifest it and it shall be ๐Ÿ’ซ

  PERLIO_FUNCS_DECL(PerlIO * ftab)

๐Ÿ’œ more PerlIO girlies (the getters and friends)

PerlIO_get_base*, PerlIO_get_bufsiz*, PerlIO_get_cnt*, PerlIO_get_ptr*, PerlIO_getc*, PerlIO_getpos*, PerlIO_has_base*, PerlIO_has_cntptr*, and PerlIO_importFILE* โ€” all described in perlapio.


๐Ÿ”ฅ PERLIO_K_* flags

PERLIO_K_BUFFERED, PERLIO_K_CANCRLF, PERLIO_K_FASTGETS, PERLIO_K_MULTIARG, and PERLIO_K_RAW โ€” all described in perliol.


๐ŸŒธ the rest of the PerlIO squad

PERLIO_NOT_STDIO, PerlIO_open*, PerlIO_printf*, PerlIO_putc*, PerlIO_puts*, PerlIO_read*, PerlIO_releaseFILE*, PerlIO_reopen*, PerlIO_rewind*, PerlIO_seek*, PerlIO_set_cnt*, PerlIO_set_ptrcnt*, PerlIO_setlinebuf*, PerlIO_setpos*, PerlIO_stderr*, PerlIO_stdin*, PerlIO_stdout*, PerlIO_stdoutf*, PerlIO_tell*, PerlIO_ungetc*, PerlIO_unread*, PerlIO_vprintf*, and PerlIO_write* โ€” all described in perlapio.


๐Ÿ“ PL_maxsysfd

described in perliol. that's the whole entry, she's mysterious, we respect it ๐Ÿ™ˆ


๐Ÿ’… repeatcpy

makes count copies of the len bytes starting at from, and drops them into memory starting at to. and heads up bestie: to must be big enough to accommodate them all, no cap, no exceptions ๐Ÿซถ

void       repeatcpy(char *to, const char *from, SSize_t len,
                     IV count)
void  Perl_repeatcpy(char *to, const char *from, SSize_t len,
                     IV count)

โญ SvVSTRING

so if the SV you hand over has vstring magic, this stores the length of it into the variable len and returns the string pointer. and if it doesn't? you get NULL. that's it, that's the deal ๐Ÿ’€

it's a wrapper around the sv_vstring_get function, and it conveniently takes the address of the len variable, in a form that's similar to the SvPV macro family. family reunion vibes, honestly adorable.

const char *  SvVSTRING(SV* sv, STRLEN len)

โœจ Integer โœจ

okay so this is the integer section, and it's giving "lots of macros" energy. but we're gonna slay through it together. ๐Ÿซถ

  • CASTI32 โ€” This symbol is defined if your C compiler can cast negative or large floating point numbers to 32-bit ints. slay. โœจ
  • HAS_INT64_T โ€” This symbol gets defined if your C compiler supports int64_t. Usually inttypes.h needs to be included, but sometimes sys/types.h is enough. iykyk. ๐Ÿ’…
  • HAS_LONG_LONG โ€” This symbol gets defined if your C compiler supports long long. periodt.
  • HAS_QUAD โ€” If this is defined, it tells you there's a 64-bit integer type, Quad_t, and its unsigned counterpart, Uquad_t. QUADKIND will be one of QUAD_IS_INT, QUAD_IS_LONG, QUAD_IS_LONG_LONG, QUAD_IS_INT64_T, or QUAD_IS___INT64. no cap.
  • INTMAX_C โ€” Returns a token the C compiler recognizes for the constant number of the widest integer type on the machine. For example, if the machine has long longs, INTMAX_C(-1) would yield:
-1LL

Use IV to declare variables of the maximum usable size on this platform.

INTMAX_C(number)
  • INTMAXSIZE โ€” This symbol contains the value of sizeof(intmax_t) so the C preprocessor can make decisions based on it. ๐Ÿ’–
  • INTSIZE โ€” This symbol contains the value of sizeof(int) so the C preprocessor can make decisions based on it. โœจ
  • IV, I8, I16, I32, I64 โ€” Described in perlguts. go read that, bestie. ๐Ÿ“š
  • IV_BITS, UV_BITS โ€” These return the number of bits in an IV and UV, respectively. These values vary depending on platform capabilities and Configure options. ๐Ÿงš
unsigned  IV_BITS
unsigned  UV_BITS
  • IV_DIG, UV_DIG โ€” These return the number of decimal digits required to represent any possible number of their respective types. These values vary depending on platform capabilities and Configure options. ๐Ÿ’…
unsigned  IV_DIG
unsigned  UV_DIG
  • IV_MAX โ€” The largest signed integer that fits in an IV on this platform. ๐Ÿ‘‘
IV  IV_MAX
  • IV_MIN โ€” The negative signed integer furthest away from 0 that fits in an IV on this platform.
It is easy to get undefined C behavior with this value. The macros (currently only available for internal use) NEGATE_2UV in perlintern, ABS_IV_MIN in perlintern, and NEGATE_2IV in perlintern avoid undefined behavior when finding the opposite signed equivalent value. โš ๏ธ
IV  IV_MIN
  • IVSIZE โ€” This symbol contains the sizeof(IV). ๐Ÿ“
  • IVTYPE โ€” This symbol defines the C type used for Perl's IV. ๐Ÿ’–
  • I8* โ€” Described in perlguts. ๐Ÿฆ‹
  • I8SIZE โ€” This symbol contains the sizeof(I8). ๐Ÿ“
  • I8TYPE โ€” This symbol defines the C type used for Perl's I8. ๐Ÿ’–
  • I16* โ€” Described in perlguts. ๐Ÿฆ‹
  • I16SIZE โ€” This symbol contains the sizeof(I16). ๐Ÿ“
  • I16TYPE โ€” This symbol defines the C type used for Perl's I16. ๐Ÿ’–
  • I32* โ€” Described in perlguts. ๐Ÿฆ‹
  • I32df โ€” This symbol defines the format string used for printing a Perl I32 as a signed decimal integer. ๐Ÿ’…
  • I32SIZE โ€” This symbol contains the sizeof(I32). ๐Ÿ“
  • I32TYPE โ€” This symbol defines the C type used for Perl's I32. ๐Ÿ’–
  • I64* โ€” Described in perlguts. ๐Ÿฆ‹
  • I64SIZE โ€” This symbol contains the sizeof(I64). ๐Ÿ“
  • I64TYPE โ€” This symbol defines the C type used for Perl's I64. ๐Ÿ’–
  • LONGLONGSIZE โ€” This symbol contains the size of a long long, so the C preprocessor can make decisions based on it. It is only defined if the system supports long long. no cap.
  • LONGSIZE โ€” This symbol contains the value of sizeof(long) so the C preprocessor can make decisions based on it. โœจ
  • memzero โ€” Set the l bytes starting at *d to all zeroes. ๐Ÿ’€
void  memzero(void * d, Size_t l)
  • PERL_INT_FAST8_T, PERL_INT_FAST16_T, PERL_UINT_FAST8_T, PERL_UINT_FAST16_T โ€” These are equivalent to the correspondingly-named C99 typedefs on platforms that have those; they evaluate to int and unsigned int on platforms that don't, so you can portably take advantage of this C99 feature. slay. ๐ŸŒˆ
  • PERL_INT_MAX, PERL_INT_MIN, PERL_LONG_MAX, PERL_LONG_MIN, PERL_QUAD_MAX, PERL_QUAD_MIN, PERL_SHORT_MAX, PERL_SHORT_MIN, PERL_UCHAR_MAX, PERL_UCHAR_MIN, PERL_UINT_MAX, PERL_UINT_MIN, PERL_ULONG_MAX, PERL_ULONG_MIN, PERL_UQUAD_MAX, PERL_UQUAD_MIN, PERL_USHORT_MAX, PERL_USHORT_MIN โ€” These give the largest and smallest number representable in the current platform in variables of the corresponding types.

For signed types, the smallest representable number is the most negative number, the one furthest away from zero.

For C99 and later compilers, these correspond to things like INT_MAX, which are available to the C code. But these constants, furnished by Perl, allow code compiled on earlier compilers to portably have access to the same constants.

int             PERL_INT_MAX
int             PERL_INT_MIN
long            PERL_LONG_MAX
long            PERL_LONG_MIN
IV              PERL_QUAD_MAX
IV              PERL_QUAD_MIN
short           PERL_SHORT_MAX
short           PERL_SHORT_MIN
U8              PERL_UCHAR_MAX
U8              PERL_UCHAR_MIN
unsigned int    PERL_UINT_MAX
unsigned int    PERL_UINT_MIN
unsigned long   PERL_ULONG_MAX
unsigned long   PERL_ULONG_MIN
UV              PERL_UQUAD_MAX
UV              PERL_UQUAD_MIN
unsigned short  PERL_USHORT_MAX
unsigned short  PERL_USHORT_MIN
  • PERL_UINT_FAST8_T*, PERL_UINT_FAST16_T* โ€” Described under PERL_INT_FAST8_T. ๐Ÿ’…
  • SHORTSIZE โ€” This symbol contains the value of sizeof(short) so the C preprocessor can make decisions based on it. โœจ
  • UINTMAX_C โ€” Returns a token the C compiler recognizes for the constant number of the widest unsigned integer type on the machine. For example, if the machine has longs, UINTMAX_C(1) would yield:
1UL

Use UV to declare variables of the maximum usable size on this platform.

UINTMAX_C(number)
  • UV, U8, U16, U32, U64 โ€” Described in perlguts. ๐Ÿ“š
  • UV_BITS* โ€” Described under IV_BITS. ๐Ÿ’…
  • UV_DIG* โ€” Described under IV_DIG. ๐Ÿ’…
  • UV_MAX โ€” The largest unsigned integer that fits in a UV on this platform. ๐Ÿ‘‘
UV  UV_MAX
  • UV_MIN โ€” The smallest unsigned integer that fits in a UV on this platform. It should equal zero. 0๏ธโƒฃ
UV  UV_MIN
  • UVSIZE โ€” This symbol contains the sizeof(UV). ๐Ÿ“
  • UVTYPE โ€” This symbol defines the C type used for Perl's UV. ๐Ÿ’–
  • U8* โ€” Described in perlguts. ๐Ÿฆ‹
  • U8SIZE โ€” This symbol contains the sizeof(U8). ๐Ÿ“
  • U8TYPE โ€” This symbol defines the C type used for Perl's U8. ๐Ÿ’–
  • U16* โ€” Described in perlguts. ๐Ÿฆ‹
  • U16SIZE โ€” This symbol contains the sizeof(U16). ๐Ÿ“
  • U16TYPE โ€” This symbol defines the C type used for Perl's U16. ๐Ÿ’–
  • U32* โ€” Described in perlguts. ๐Ÿฆ‹
  • U32of โ€” This symbol defines the format string used for printing a Perl U32 as an unsigned octal integer. ๐Ÿ’…
  • U32SIZE โ€” This symbol contains the sizeof(U32). ๐Ÿ“
  • U32TYPE โ€” This symbol defines the C type used for Perl's U32. ๐Ÿ’–
  • U32uf โ€” This symbol defines the format string used for printing a Perl U32 as an unsigned decimal integer. ๐Ÿ’…
  • U32Xf โ€” This symbol defines the format string used for printing a Perl U32 as an unsigned hexadecimal integer in uppercase ABCDEF. ๐Ÿ’…
  • U32xf โ€” This symbol defines the format string used for printing a Perl U32 as an unsigned hexadecimal integer in lowercase abcdef. ๐Ÿ’…
  • U64* โ€” Described in perlguts. ๐Ÿฆ‹
  • U64SIZE โ€” This symbol contains the sizeof(U64). ๐Ÿ“
  • U64TYPE โ€” This symbol defines the C type used for Perl's U64. ๐Ÿ’–
  • WIDEST_UTYPE โ€” Yields the widest unsigned integer type on the platform, currently either U32 or U64. This can be used in declarations such as
WIDEST_UTYPE my_uv;

or casts

my_uv = (WIDEST_UTYPE) val;

โœจ I/O Formats โœจ

Okay bestie, so these are the format strings you use to print the right type. ๐Ÿ’… For example, instead of saying

        Perl_newSVpvf(pTHX_ "Create an SV with a %d in it\n", iv);

use

        Perl_newSVpvf(pTHX_ "Create an SV with a " IVdf " in it\n", iv);

This keeps you from having to know if, say an IV, needs to be printed as %d, %ld, or something else. No cap. ๐Ÿงš

  • HvNAMEf, HvNAMEf_QUOTEDPREFIX, HvNAMEfARG โ€” Described in perlguts. ๐Ÿฆ‹
            HvNAMEfARG(HV *hv)
  • IVdf โ€” This symbol defines the format string used for printing a Perl IV as a signed decimal integer. โœจ
  • NVef โ€” This symbol defines the format string used for printing a Perl NV using %e-ish floating point format. ๐Ÿ’–
  • NVff โ€” This symbol defines the format string used for printing a Perl NV using %f-ish floating point format. ๐Ÿ’–
  • NVgf โ€” This symbol defines the format string used for printing a Perl NV using %g-ish floating point format. ๐Ÿ’–
  • PERL_PRIeldbl โ€” This symbol, if defined, contains the string used by stdio to format long doubles (format 'e') for output. ๐ŸŒˆ
  • PERL_PRIfldbl โ€” This symbol, if defined, contains the string used by stdio to format long doubles (format 'f') for output. ๐ŸŒˆ
  • PERL_PRIgldbl โ€” This symbol, if defined, contains the string used by stdio to format long doubles (format 'g') for output. ๐ŸŒˆ
  • PERL_SCNfldbl โ€” This symbol, if defined, contains the string used by stdio to format long doubles (format 'f') for input. ๐ŸŒˆ
  • PRINTF_FORMAT_NULL_OK โ€” Allows __printf__ format to be null when checking printf-style. ๐Ÿ‘‘
  • SVf, SVf_QUOTEDPREFIX, SVfARG, UTF8f, UTF8f_QUOTEDPREFIX, UTF8fARG โ€” Described in perlguts. ๐ŸŽ€
            SVfARG  (SV *sv)
            UTF8fARG(bool is_utf8, Size_t byte_len, char *str)
  • UVf โ€” DEPRECATED! It is planned to remove UVf from a future release of Perl. Do not use it for new code; remove it from existing code. ๐Ÿ˜ญ Obsolete form of UVuf, which you should convert to instead use
          const char *  UVf
  • UVof โ€” This symbol defines the format string used for printing a Perl UV as an unsigned octal integer. ๐Ÿฆ‹
  • UVuf โ€” This symbol defines the format string used for printing a Perl UV as an unsigned decimal integer. ๐Ÿฆ‹
  • UVXf โ€” This symbol defines the format string used for printing a Perl UV as an unsigned hexadecimal integer in uppercase ABCDEF. ๐Ÿ’œ
  • UVxf โ€” This symbol defines the format string used for printing a Perl UV as an unsigned hexadecimal integer in lowercase abcdef. ๐Ÿ’œ

โœจ Lexer interface โœจ

This is the lower layer of the Perl parser, managing characters and tokens. It's giving very much main character energy. ๐Ÿ‘‘

  • BHK โ€” Described in perlguts. ๐Ÿงš
  • lex_bufutf8
NOTE: lex_bufutf8 is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Indicates whether the octets in the lexer buffer (PL_parser->linestr) should be interpreted as the UTF-8 encoding of Unicode characters. If not, they should be interpreted as Latin-1 characters. This is analogous to the SvUTF8 flag for scalars. ๐ŸŒธ

In UTF-8 mode, it is not guaranteed that the lexer buffer actually contains valid UTF-8. Lexing code must be robust in the face of invalid encoding. ๐Ÿ’€

The actual SvUTF8 flag of the PL_parser->linestr scalar is significant, but not the whole story regarding the input character encoding. Normally, when a file is being read, the scalar contains octets and its SvUTF8 flag is off, but the octets should be interpreted as UTF-8 if the use utf8 pragma is in effect. During a string eval, however, the scalar may have the SvUTF8 flag on, and in this case its octets should be interpreted as UTF-8 unless the use bytes pragma is in effect. This logic may change in the future; use this function instead of implementing the logic yourself. ๐Ÿซถ

          bool       lex_bufutf8()
          bool  Perl_lex_bufutf8(pTHX)
  • lex_discard_to
NOTE: lex_discard_to is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Discards the first part of the PL_parser->linestr buffer, up to ptr. The remaining content of the buffer will be moved, and all pointers into the buffer updated appropriately. ptr must not be later in the buffer than the position of PL_parser->bufptr: it is not permitted to discard text that has yet to be lexed. ๐Ÿšซ

Normally it is not necessarily to do this directly, because it suffices to use the implicit discarding behaviour of lex_next_chunk and things based on it. However, if a token stretches across multiple lines, and the lexing code has kept multiple lines of text in the buffer for that purpose, then after completion of the token it would be wise to explicitly discard the now-unneeded earlier lines, to avoid future multi-line tokens growing the buffer without bound. ๐ŸŒ€

          void       lex_discard_to(      char *ptr)
          void  Perl_lex_discard_to(pTHX_ char *ptr)
  • lex_grow_linestr
NOTE: lex_grow_linestr is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Reallocates the lexer buffer (PL_parser->linestr) to accommodate at least len octets (including terminating NUL). Returns a pointer to the reallocated buffer. This is necessary before making any direct modification of the buffer that would increase its length. lex_stuff_pvn provides a more convenient way to insert text into the buffer. โœจ

Do not use SvGROW or sv_grow directly on PL_parser->linestr; this function updates all of the lexer's variables that point directly into the buffer. ๐Ÿ™…โ€โ™€๏ธ

          char *       lex_grow_linestr(      STRLEN len)
          char *  Perl_lex_grow_linestr(pTHX_ STRLEN len)
  • lex_next_chunk
NOTE: lex_next_chunk is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Reads in the next chunk of text to be lexed, appending it to PL_parser->linestr. This should be called when lexing code has looked to the end of the current chunk and wants to know more. It is usual, but not necessary, for lexing to have consumed the entirety of the current chunk at this time. ๐Ÿ“–

If PL_parser->bufptr is pointing to the very end of the current chunk (i.e., the current chunk has been entirely consumed), normally the current chunk will be discarded at the same time that the new chunk is read in. If flags has the LEX_KEEP_PREVIOUS bit set, the current chunk will not be discarded. If the current chunk has not been entirely consumed, then it will not be discarded regardless of the flag. ๐Ÿ”ฅ

Returns true if some new text was added to the buffer, or false if the buffer has reached the end of the input text. ๐ŸŽฏ

          bool       lex_next_chunk(      U32 flags)
          bool  Perl_lex_next_chunk(pTHX_ U32 flags)
  • lex_peek_unichar
NOTE: lex_peek_unichar is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Looks ahead one (Unicode) character in the text currently being lexed. Returns the codepoint (unsigned integer value) of the next character, or -1 if lexing has reached the end of the input text. To consume the peeked character, use lex_read_unichar. ๐Ÿ‘€

If the next character is in (or extends into) the next chunk of input text, the next chunk will be read in. Normally the current chunk will be discarded at the same time, but if flags has the LEX_KEEP_PREVIOUS bit set, then the current chunk will not be discarded. ๐ŸŒŠ

If the input is being interpreted as UTF-8 and a UTF-8 encoding error is encountered, an exception is generated. ๐Ÿ˜ฑ

          I32       lex_peek_unichar(      U32 flags)
          I32  Perl_lex_peek_unichar(pTHX_ U32 flags)
  • lex_read_space
NOTE: lex_read_space is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Reads optional spaces, in Perl style, in the text currently being lexed. The spaces may include ordinary whitespace characters and Perl-style comments. #line directives are processed if encountered. PL_parser->bufptr is moved past the spaces, so that it points at a non-space character (or the end of the input text). ๐Ÿงน

If spaces extend into the next chunk of input text, the next chunk will be read in. Normally the current chunk will be discarded at the same time, but if flags has the LEX_KEEP_PREVIOUS bit set, then the current chunk will not be discarded. ๐ŸŒ€

          void       lex_read_space(      U32 flags)
          void  Perl_lex_read_space(pTHX_ U32 flags)
  • lex_read_to
NOTE: lex_read_to is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Consume text in the lexer buffer, from PL_parser->bufptr up to ptr. This advances PL_parser->bufptr to match ptr, performing the correct bookkeeping whenever a newline character is passed. This is the normal way to consume lexed text. ๐Ÿ“

Interpretation of the buffer's octets can be abstracted out by using the slightly higher-level functions lex_peek_unichar and lex_read_unichar. ๐ŸŽญ

          void       lex_read_to(      char *ptr)
          void  Perl_lex_read_to(pTHX_ char *ptr)
  • lex_read_unichar
NOTE: lex_read_unichar is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Reads the next (Unicode) character in the text currently being lexed. Returns the codepoint (unsigned integer value) of the character read, and moves PL_parser->bufptr past the character, or returns -1 if lexing has reached the end of the input text. To non-destructively examine the next character, use lex_peek_unichar instead. ๐Ÿ“–

If the next character is in (or extends into) the next chunk of input text, the next chunk will be read in. Normally the current chunk will be discarded at the same time, but if flags has the LEX_KEEP_PREVIOUS bit set, then the current chunk will not be discarded. ๐ŸŒŠ

If the input is being interpreted as UTF-8 and a UTF-8 encoding error is encountered, an exception is generated. ๐Ÿ˜ฑ

          I32       lex_read_unichar(      U32 flags)
          I32  Perl_lex_read_unichar(pTHX_ U32 flags)
  • lex_start
NOTE: lex_start is experimental and may change or be removed without notice. ๐Ÿ˜ฌ

Bestie!! Okay so this one's the whole โœจlexer coreโœจ and she is serving, so let's get into it ๐Ÿ’…


So like, lex_start creates and initialises a brand-new lexer/parser state object, giving you a whole context to lex and parse from a shiny new source of Perl code ๐ŸŽ€ A pointer to that new state object gets dropped into PL_parser. And here's the cute part: an entry gets made on the save stack, so the moment things unwind, the new state object gets destroyed and the former value of PL_parser gets restored ๐Ÿซถ Like it never even happened. And that's it!! Nothing else needs doing to clean up the parsing context. Slay.

Where does the code come from, you ask? From line and rsfp, duh ๐Ÿ’–

  • line, if it's non-null, hands you a string (in SV form) containing the code to be parsed. And heads up โ€” a copy of the string is made, so if you go modifying line afterwards, parsing does NOT care. Not your problem, bestie ๐Ÿ˜Œ
  • rsfp, if it's non-null, gives you an input stream that code gets read from, to be parsed ๐Ÿ“–
  • And if both are non-null?? The code in line comes first and must consist of complete lines of input, and then rsfp supplies the remainder of the source. No partial lines, no cap ๐Ÿงš

The flags parameter is reserved for future use. Right now it's only used by perl internally, so if you're an extension: always pass zero. Periodt.

 void       lex_start(      SV *line, PerlIO *rsfp, U32 flags)
 void  Perl_lex_start(pTHX_ SV *line, PerlIO *rsfp, U32 flags)

lex_stuff_pv / lex_stuff_pvn / lex_stuff_pvs / lex_stuff_sv

NOTE: all these forms are experimental and may change or be removed without notice. Like, genuinely, do not build your whole personality on them ๐Ÿ™ˆ

Okay so all four of these insert characters into the lexer buffer โ€” that's PL_parser->linestr โ€” immediately after the current lexing point, which is PL_parser->bufptr, and they reallocate the buffer if they need to. Which means: lexing code that runs later will see those characters as if they'd been in the input the whole time ๐Ÿ‘€

It is not recommended to do this as part of normal parsing, and most uses of this facility run the risk of the inserted characters being interpreted in an unintended manner ๐Ÿ’€ Like, you're sneaking words into the group chat and hoping nobody misreads the vibe. Risky.

Let's break down the flavours, because they are not the same:

  • In lex_stuff_pvs, the string to be inserted is a literal C string, enclosed in double quotes ๐ŸŒธ
  • In lex_stuff_pv and lex_stuff_pvn, the string to be inserted is represented by the octets starting at pv. In lex_stuff_pv, the first NUL octet terminates the string. In lex_stuff_pvn, len octets will be used, hence the string may contain embedded NUL characters ๐Ÿ‘‘
  • In all three of those cases, those octets are interpreted as either UTF-8 or Latin-1, according to whether or not the LEX_STUFF_UTF8 flag is set in flags โœจ
  • In lex_stuff_sv, the string to be inserted is the string value of sv. Here flags must be 0. The string gets interpreted as either UTF-8 or Latin-1, according to whether or not sv has its UTF-8 flag set ๐Ÿฆ‹

And in all three forms, the characters are recoded for the lexer buffer, according to how the buffer is currently being interpreted โ€” that's via lex_bufutf8 ๐Ÿ’œ

 void       lex_stuff_pv (      const char *pv, U32 flags)
 void  Perl_lex_stuff_pv (pTHX_ const char *pv, U32 flags)
 void       lex_stuff_pvn(      const char *pv, STRLEN len,
                                U32 flags)
 void  Perl_lex_stuff_pvn(pTHX_ const char *pv, STRLEN len,
                                U32 flags)
 void       lex_stuff_pvs(      "pv", U32 flags)
 void       lex_stuff_sv (      SV *sv, U32 flags)
 void  Perl_lex_stuff_sv (pTHX_ SV *sv, U32 flags)

lex_unstuff

NOTE: lex_unstuff is experimental and may change or be removed without notice. Same energy, same warning, bestie ๐Ÿ˜ญ

This one discards text about to be lexed, all the way from PL_parser->bufptr up to ptr ๐Ÿงน Text after ptr gets moved, and the buffer gets shortened. So it hides that discarded text from any lexing code running later, as if it had never appeared. Iconic disappearing act ๐ŸŽ€

But lowkey โ€” this is NOT the normal way to consume lexed text. For that, use lex_read_to. Iykyk โœจ
 void       lex_unstuff(      char *ptr)
 void  Perl_lex_unstuff(pTHX_ char *ptr)

parse_arithexpr

NOTE: parse_arithexpr is experimental and may change or be removed without notice ๐ŸŒธ

Parses a Perl arithmetic expression โž•โž–โœ–๏ธโž— This may contain operators of precedence down to the bit shift operators. The expression must be followed (and thus terminated) either by a comparison or lower-precedence operator, or by something that would normally terminate an expression such as a semicolon. No leaving it hanging, babes ๐Ÿ˜ค

If flags has the PARSE_OPTIONAL bit set, the expression is optional; otherwise it is mandatory. And it's on you (the caller) to make sure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the expression ๐Ÿ‘‘

The op tree representing the expression gets returned ๐Ÿ’– If an optional expression is absent, a null pointer comes back; otherwise the pointer will be non-null. Simple as.

If an error happens in parsing or compilation, in most cases a valid op tree is returned anyway ๐Ÿ˜ญ Like, the error is reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. BUT โ€” some compilation errors will throw an exception immediately. So don't get comfy ๐Ÿ’€

 OP *       parse_arithexpr(      U32 flags)
 OP *  Perl_parse_arithexpr(pTHX_ U32 flags)

parse_barestmt

NOTE: parse_barestmt is experimental and may change or be removed without notice ๐Ÿฆ‹

Parses a single unadorned Perl statement โœจ This may be a normal imperative statement, or a declaration that has compile-time effect. It does not include any label or other affixture โ€” bare means bare, bestie, no accessories ๐Ÿ’… And again, it's up to the caller to ensure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the statement.

The op tree representing the statement gets returned. This may be a null pointer if the statement is null โ€” for example if it was actually a subroutine definition (which has compile-time side effects, sneaky ๐Ÿ‘€). If it's not null, it'll be ops directly implementing the statement, suitable to pass to newSTATEOP ๐ŸŒˆ It will not normally include a nextstate or equivalent op โ€” except for those embedded in a scope contained entirely within the statement.

If an error happens in parsing or compilation, in most cases a valid op tree (most likely null) is returned anyway. The error is reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. Some compilation errors, however, will throw an exception immediately ๐Ÿ˜ญ

And the flags parameter? Reserved for future use, and must always be zero. No exceptions, no "but what ifโ€”" ๐Ÿšซ

 OP *       parse_barestmt(      U32 flags)
 OP *  Perl_parse_barestmt(pTHX_ U32 flags)

parse_block

NOTE: parse_block is experimental and may change or be removed without notice ๐Ÿ’œ

Parses a single complete Perl code block โ€” an opening brace, a sequence of statements, and a closing brace ๐ŸŽ€ { } girlies rise. The block constitutes a lexical scope, so my variables and various compile-time effects can live inside it ๐Ÿชบ And yes, once more, it's up to the caller to ensure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the statement.

The op tree representing the code block gets returned โ€” and this one is always a real op, never a null pointer ๐Ÿ‘‘ It'll normally be a lineseq list, including nextstate or equivalent ops. No ops to construct any kind of runtime scope are included just by virtue of it being a block โœจ

If an error happens in parsing or compilation, in most cases a valid op tree (most likely null) is returned anyway. The error is reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. Some compilation errors, however, will throw an exception immediately ๐Ÿ’€

And flags? Reserved for future use, must always be zero ๐Ÿซถ

 OP *       parse_block(      U32 flags)
 OP *  Perl_parse_block(pTHX_ U32 flags)

parse_fullexpr

NOTE: parse_fullexpr is experimental and may change or be removed without notice ๐ŸŒธ

Parses a single complete Perl expression. This allows the full expression grammar โ€” yes, including the lowest-precedence operators like or ๐Ÿ˜ค The expression must be followed (and thus terminated) by a token that an expression would normally be terminated by: end-of-file, closing bracketing punctuation, semicolon, or one of the keywords that signals a postfix expression-statement modifier ๐ŸŒˆ

If flags has the PARSE_OPTIONAL bit set, the expression is optional; otherwise it is mandatory. And it's up to the caller to ensure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the expression โœจ

The op tree representing the expression gets returned ๐Ÿ’– If an optional expression is absent, a null pointer is returned; otherwise the pointer will be non-null.

If an error happens in parsing or compilation, in most cases a valid op tree is returned anyway. The error is reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. Some compilation errors, however, will throw an exception immediately ๐Ÿ˜ญ

 OP *       parse_fullexpr(      U32 flags)
 OP *  Perl_parse_fullexpr(pTHX_ U32 flags)

parse_fullstmt

NOTE: parse_fullstmt is experimental and may change or be removed without notice ๐Ÿฆ‹

Parses a single complete Perl statement ๐Ÿ‘‘ This may be a normal imperative statement, or a declaration that has compile-time effect, and it may include optional labels โ€” so this one got dressed up fr fr ๐Ÿ’… And, once again, it's up to the caller to ensure that the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the statement.

The op tree representing the statement gets returned. This may be a null pointer if the statement is null โ€” for example if it was actually a subroutine definition (which has compile-time side effects ๐Ÿ‘€). If it's not null, it'll be the result of a newSTATEOP call, normally including a nextstate or equivalent op ๐ŸŒŸ

If an error pops off during parsing or compilation, bestie, most of the time you still get a valid op tree back โ€” probs a null one, but valid-ish. The error is living in the parser state, so it usually turns into one single exception at the top level of parsing that covers all the compilation errors that happened. Some compilation errors tho? They throw an exception immediately, no chill. ๐Ÿ˜ญ

The flags parameter is reserved for future use and must always be zero. Periodt.

 OP *       parse_fullstmt(      U32 flags)
 OP *  Perl_parse_fullstmt(pTHX_ U32 flags)

๐ŸŽ€ parse_label ๐ŸŽ€

NOTE: parse_label is experimental and may change or be removed without notice. ๐Ÿซฃ

Parses a single label, possibly optional, of the type that can prefix a Perl statement. It is totally up to you, the caller, to make sure the dynamic parser state (PL_parser et al) is set correctly to reflect where the code being parsed came from. If flags has the PARSE_OPTIONAL bit set, then the label is optional; otherwise it's mandatory, no takebacks.

The name of the label comes back as a fresh scalar. And if an optional label is absent? You get a null pointer. ๐Ÿ’€

If an error happens during parsing โ€” which can only happen if the label is mandatory โ€” a valid label is returned anyway. The error is reflected in the parser state, normally becoming a single exception at the top level of parsing that covers all the compilation errors that occurred.

 SV *       parse_label(      U32 flags)
 SV *  Perl_parse_label(pTHX_ U32 flags)

๐Ÿฆ‹ parse_listexpr ๐Ÿฆ‹

NOTE: parse_listexpr is experimental and may change or be removed without notice. ๐Ÿซฃ

Parses a Perl list expression. This can contain operators of precedence down to the comma operator, so like, we're going deep bestie. The expression has to be followed (and therefore terminated) either by a low-precedence logic operator such as or, or by something that would normally terminate an expression such as a semicolon. If flags has the PARSE_OPTIONAL bit set, the expression is optional; otherwise it's mandatory. It's on you to make sure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code being parsed and the lexical context for the expression.

The op tree representing the expression is what you get back. If an optional expression is absent, you get a null pointer; otherwise the pointer will be non-null.

If an error happens in parsing or compilation, in most cases a valid op tree is returned anyway. The error is reflected in the parser state, normally becoming a single exception at the top level of parsing that covers all the compilation errors that occurred. Some compilation errors, though, will throw an exception immediately. ๐Ÿ˜ค

 OP *       parse_listexpr(      U32 flags)
 OP *  Perl_parse_listexpr(pTHX_ U32 flags)

๐ŸŒธ parse_stmtseq ๐ŸŒธ

NOTE: parse_stmtseq is experimental and may change or be removed without notice. ๐Ÿซฃ

Parses a sequence of zero or more Perl statements. These can be normal imperative statements (including optional labels), or declarations that have compile-time effect, or honestly any mixture of the two. The statement sequence ends when a closing brace or end-of-file is hit in a place where a new statement could have validly started. It's up to you, the caller, to make sure the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code being parsed and the lexical context for the statements.

The op tree representing the statement sequence is returned. This may be a null pointer if the statements were all null โ€” like, if there were no statements at all, or if there were only subroutine definitions (which have compile-time side effects). If it's not null, it'll be a lineseq list, normally including nextstate or equivalent ops.

If an error happens in parsing or compilation, in most cases a valid op tree is returned anyway. The error is reflected in the parser state, normally becoming a single exception at the top level of parsing that covers all the compilation errors that occurred. Some compilation errors will throw an exception immediately, though.

The flags parameter is reserved for future use and must always be zero.

 OP *       parse_stmtseq(      U32 flags)
 OP *  Perl_parse_stmtseq(pTHX_ U32 flags)

๐Ÿ’œ parse_subsignature ๐Ÿ’œ

NOTE: parse_subsignature is experimental and may change or be removed without notice. ๐Ÿซฃ

Parses a subroutine signature declaration. That's the contents of the parentheses following a named or anonymous subroutine declaration when the signatures feature is enabled. Heads up bestie: this function neither expects nor consumes the opening and closing parentheses around the signature โ€” handling those is the caller's job. ๐Ÿ‘‘

This function must only be called during parsing of a subroutine; after start_subparse has been called. It might allocate lexical variables on the pad for the current subroutine.

The op tree to unpack the arguments from the stack at runtime is returned. This op tree should appear at the beginning of the compiled function. You, the caller, may want to use op_append_list to build your function body after it, or splice it together with the body before calling newATTRSUB.

The flags parameter is reserved for future use and must always be zero.

 OP *       parse_subsignature(      U32 flags)
 OP *  Perl_parse_subsignature(pTHX_ U32 flags)

โญ parse_termexpr โญ

NOTE: parse_termexpr is experimental and may change or be removed without notice. ๐Ÿซฃ

Parses a Perl term expression. This may contain operators of precedence down to the assignment operators. The expression must be followed (and thus terminated) either by a comma or lower-precedence operator, or by something that would normally terminate an expression such as a semicolon. If flags has the PARSE_OPTIONAL bit set, the expression is optional; otherwise it's mandatory. It's on the caller โ€” that's you โ€” to ensure that the dynamic parser state (PL_parser et al) is correctly set to reflect the source of the code to be parsed and the lexical context for the expression.

The op tree representing the expression is returned. If an optional expression is absent, a null pointer is returned; otherwise the pointer will be non-null.

If an error occurs in parsing or compilation, in most cases a valid op tree is returned anyway. The error is reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. Some compilation errors, however, will throw an exception immediately.

 OP *       parse_termexpr(      U32 flags)
 OP *  Perl_parse_termexpr(pTHX_ U32 flags)

๐Ÿ‘‘ PL_parser ๐Ÿ‘‘

A pointer to a structure that encapsulates the state of the parsing operation currently in progress. The pointer can be locally changed to perform a nested parse without messing with the state of an outer parse. Individual members of PL_parser have their own documentation. So fancy. ๐Ÿ’…

๐Ÿงš PL_parser->bufend ๐Ÿงš

NOTE: PL_parser->bufend is experimental and may change or be removed without notice. ๐Ÿซฃ

A direct pointer to the end of the chunk of text currently being lexed โ€” the end of the lexer buffer. This is equal to SvPVX(PL_parser->linestr) + SvCUR(PL_parser->linestr). A NUL character (zero octet) always sits at the end of the buffer, and does not count as part of the buffer's contents.

๐Ÿ“ PL_parser->bufptr ๐Ÿ“

NOTE: PL_parser->bufptr is experimental and may change or be removed without notice. ๐Ÿซฃ

Points to the current position of lexing inside the lexer buffer. Characters around this point may be freely examined, within the range delimited by SvPVX(PL_parser->linestr) and PL_parser->bufend. The octets of the buffer may be intended to be interpreted as either UTF-8 or Latin-1, as indicated by lex_bufutf8.

Lexing code (whether it's in the Perl core or not) moves this pointer past the characters that it consumes. It's also expected to do some bookkeeping whenever a newline character gets consumed. This movement can be done way more conveniently with the function lex_read_to, which handles newlines appropriately. โœจ

Interpretation of the buffer's octets can be abstracted out by using the slightly higher-level functions lex_peek_unichar and lex_read_unichar.

๐ŸŒˆ PL_parser->linestart ๐ŸŒˆ

NOTE: PL_parser->linestart is experimental and may change or be removed without notice. ๐Ÿซฃ

Points to the start of the current line inside the lexer buffer. This is useful for indicating at which column an error occurred, and honestly not much else. It must be updated by any lexing code that consumes a newline; the function lex_read_to handles this detail for you.

๐Ÿ’– PL_parser->linestr ๐Ÿ’–

NOTE: PL_parser->linestr is experimental and may change or be removed without notice. ๐Ÿซฃ

A buffer scalar containing the chunk currently under consideration of the text currently being lexed. This is always a plain string scalar (for which SvPOK is true). It's not intended to be used as a scalar by normal scalar means โ€” instead refer to the buffer directly through the pointer variables described below.

The lexer maintains various char* pointers to things in the PL_parser->linestr buffer. If PL_parser->linestr is ever reallocated, all of these pointers must be updated. Don't even think about doing this manually โ€” use lex_grow_linestr instead if you need to reallocate the buffer. ๐Ÿ™ˆ

The content of the text chunk in the buffer is commonly exactly one complete line of input, up to and including a newline terminator, but there are situations where it's otherwise. The octets of the buffer may be intended to be interpreted as either UTF-8 or Latin-1. The function lex_bufutf8 tells you which. Do not use the SvUTF8 flag on this scalar, because it may disagree. ๐Ÿ’€

For direct examination of the buffer, the variable PL_parser->bufend points to the end of the buffer, and the current lexing position is pointed to by PL_parser->bufptr. Direct use of these pointers is usually preferable to examination of the scalar through normal scalar means.

resume_compcv_and_save ๐Ÿ’–

okay so bestie, imagine you paused a compilation and now you wanna pick it back up โ€” this function resumes a buffer that was previously suspended by the suspend_compcv function, and it does it in a way that will be re-suspended at the end of the scope so it can be used again later. โœจ This should be used within an ENTER/LEAVE scoped pair. periodt.

            void       resume_compcv_and_save(
                                            struct suspended_compcv *buffer)
            void  Perl_resume_compcv_and_save(pTHX_
                                             struct suspended_compcv *buffer)

resume_compcv_final ๐Ÿฆ‹

ngl this one resumes the parser state that was previously saved using the suspend_compcv function for a final time before being compiled into a full CV. It's giving last-call energy. This should be used within an ENTER/LEAVE scoped pair, no cap.

            void       resume_compcv_final(  struct suspended_compcv *buffer)
            void  Perl_resume_compcv_final(pTHX_
                                             struct suspended_compcv *buffer)

suspend_compcv ๐Ÿงš

This one implements part of the concept of a "suspended compilation CV" โ€” which can be used to pause the parser and compiler during parsing a CV in order to come back to it later on. It's literally the pause button for your subroutine under compilation. ๐Ÿ’…

This function saves the current state of the subroutine under compilation (PL_compcv) into the supplied buffer. This should be used initially to create the state in the buffer, as the final thing before a LEAVE within a block.

               ENTER;
               start_subparse(0);
               ...

               suspend_compcv(&buffer);
               LEAVE;

Once suspended, the resume_compcv_final or resume_compcv_and_save function can later be used to continue the parsing from the point this stopped. iconic.

            void       suspend_compcv(      struct suspended_compcv *buffer)
            void  Perl_suspend_compcv(pTHX_ struct suspended_compcv *buffer)

valid_identifier_pvn, valid_identifier_pve, valid_identifier_sv ๐ŸŒˆ

These each return true if the string given by their parameters would be considered valid as a Perl identifier. That is, for non-UTF-8 strings, it must begin with a character matching "L/<isIDFIRST">, followed by characters all matching isIDCONT. For UTF-8 strings, the characters must match isIDFIRST_utf8 and isIDCONT_utf8, respectively.

An empty string will return false. (sad, but true)

They differ only in how the string is specified.

In valid_identifier_sv, the string is extracted from sv using SvPV_const, without performing get magic. The string is considered to be encoded in UTF-8 if and only if sv is marked as being UTF-8. ๐Ÿฆ‹

In the other two functions, the first byte of the string is pointed to by s. In valid_identifier_pvn its length is given by len. In valid_identifier_pve the final byte of the string is the one before e. If flags contains the SVf_UTF8 bit, then the string is presumed to be encoded in UTF-8, and suitable Unicode character test functions will be used. ๐Ÿ’œ

            bool       valid_identifier_pvn(      const char *s, STRLEN len,
                                                  U32 flags)
            bool  Perl_valid_identifier_pvn(pTHX_ const char *s, STRLEN len,
                                                  U32 flags)
            bool       valid_identifier_pve(      const char *s,
                                                  const char *end, U32 flags)
            bool  Perl_valid_identifier_pve(pTHX_ const char *s,
                                                  const char *end, U32 flags)
            bool       valid_identifier_sv (      SV *sv)
            bool  Perl_valid_identifier_sv (pTHX_ SV *sv)

wrap_infix_plugin ๐ŸŽ€

NOTE: wrap_infix_plugin is experimental and may change or be removed without notice. ๐Ÿ’€
NOTE: This API exists entirely for the purpose of making the CPAN module XS::Parse::Infix work. It is not expected that additional modules will make use of it; rather, that they should use XS::Parse::Infix to provide parsing of new infix operators. iykyk.

Puts a C function into the chain of infix plugins. This is the preferred way to manipulate the PL_infix_plugin variable. new_plugin is a pointer to the C function that is to be added to the infix plugin chain, and old_plugin_p points to a storage location where a pointer to the next function in the chain will be stored. The value of new_plugin is written into the PL_infix_plugin variable, while the value previously stored there is written to *old_plugin_p.

Direct access to PL_infix_plugin should be avoided. no cap.

            void       wrap_infix_plugin(  Perl_infix_plugin_t new_plugin,
                                           Perl_infix_plugin_t *old_plugin_p)
            void  Perl_wrap_infix_plugin(pTHX_
                                           Perl_infix_plugin_t new_plugin,
                                           Perl_infix_plugin_t *old_plugin_p)

wrap_keyword_plugin ๐Ÿ‘‘

NOTE: wrap_keyword_plugin is experimental and may change or be removed without notice. ๐Ÿ’€

Puts a C function into the chain of keyword plugins. This is the preferred way to manipulate the PL_keyword_plugin variable. new_plugin is a pointer to the C function that is to be added to the keyword plugin chain, and old_plugin_p points to the storage location where a pointer to the next function in the chain will be stored. The value of new_plugin is written into the PL_keyword_plugin variable, while the value previously stored there is written to *old_plugin_p.

PL_keyword_plugin is global to an entire process, and a module wishing to hook keyword parsing may find itself invoked more than once per process, typically in different threads. To handle that situation, this function is idempotent. The location *old_plugin_p must initially (once per process) contain a null pointer. A C variable of static duration (declared at file scope, typically also marked static to give it internal linkage) will be implicitly initialised appropriately, if it does not have an explicit initialiser. This function will only actually modify the plugin chain if it finds *old_plugin_p to be null. This function is also thread safe on the small scale. It uses appropriate locking to avoid race conditions in accessing PL_keyword_plugin. ๐Ÿ”ฅ

When this function is called, the function referenced by new_plugin must be ready to be called, except for *old_plugin_p being unfilled. In a threading situation, new_plugin may be called immediately, even before this function has returned. *old_plugin_p will always be appropriately set before new_plugin is called. If new_plugin decides not to do anything special with the identifier that it is given (which is the usual case for most calls to a keyword plugin), it must chain the plugin function referenced by *old_plugin_p. ๐ŸŒธ

Taken all together, XS code to install a keyword plugin should typically look something like this:

               static Perl_keyword_plugin_t next_keyword_plugin;
               static OP *my_keyword_plugin(pTHX_
                   char *keyword_ptr, STRLEN keyword_len, OP **op_ptr)
               {
                   if (memEQs(keyword_ptr, keyword_len,
                              "my_new_keyword")) {
                       ...
                   } else {
                       return next_keyword_plugin(aTHX_
                           keyword_ptr, keyword_len, op_ptr);
                   }
               }
               BOOT:
                   wrap_keyword_plugin(my_keyword_plugin,
                                       &next_keyword_plugin);

Direct access to PL_keyword_plugin should be avoided.

            void       wrap_keyword_plugin(Perl_keyword_plugin_t new_plugin,
                                         Perl_keyword_plugin_t *old_plugin_p)
            void  Perl_wrap_keyword_plugin(pTHX_
                                         Perl_keyword_plugin_t new_plugin,
                                         Perl_keyword_plugin_t *old_plugin_p)

โœจ Locales โœจ

DECLARATION_FOR_LC_NUMERIC_MANIPULATION ๐Ÿ’…

This macro should be used as a statement. It declares a private variable (whose name begins with an underscore) that is needed by the other macros in this section. Failing to include this correctly should lead to a syntax error. ๐Ÿ˜ญ For compatibility with C89 C compilers it should be placed in a block before any executable statements.

            void  DECLARATION_FOR_LC_NUMERIC_MANIPULATION

HAS_DUPLOCALE ๐Ÿฆ‹

This symbol, if defined, indicates that the duplocale routine is available to duplicate a locale object. slay.

HAS_FREELOCALE ๐Ÿ’–

This symbol, if defined, indicates that the freelocale routine is available to deallocates the resources associated with a locale object. (yes, "deallocates" is in the original, no cap)

HAS_LC_MONETARY_2008 ๐ŸŽ€

This symbol, if defined, indicates that the localeconv routine is available and has the additional members added in POSIX 1003.1-2008.

HAS_LOCALECONV ๐ŸŒˆ

This symbol, if defined, indicates that the localeconv routine is available for numeric and monetary formatting conventions.

HAS_LOCALECONV_L ๐Ÿ’œ

This symbol, if defined, indicates that the localeconv_l routine is available to query certain information about a locale.

HAS_NEWLOCALE โœจ

This symbol, if defined, indicates that the newlocale routine is available to return a new locale object or modify an existing locale object.

HAS_NL_LANGINFO ๐Ÿงš

This symbol, if defined, indicates that the nl_langinfo routine is available to return locale data. You will also need langinfo.h and therefore I_LANGINFO.

HAS_NL_LANGINFO_L ๐Ÿ‘‘

This symbol, if defined, indicates that the nl_langinfo_l routine is available to return locale data. You will also need langinfo.h and therefore I_LANGINFO.

HAS_QUERYLOCALE ๐Ÿ”ฅ

This symbol, if defined, indicates that the querylocale routine is available to return the name of the locale for a category mask.

HAS_SETLOCALE ๐Ÿ’…

This symbol, if defined, indicates that the setlocale routine is available to handle locale-specific ctype implementations.

HAS_SETLOCALE_R ๐Ÿฆ‹

This symbol, if defined, indicates that the setlocale_r routine is available to setlocale re-entrantly.

HAS_USELOCALE ๐ŸŒธ

This symbol, if defined, indicates that the uselocale routine is available to set the current locale for the calling thread.

I_LANGINFO ๐Ÿ’–

This symbol, if defined, indicates that langinfo.h exists and should be included.

            #ifdef I_LANGINFO
                #include <langinfo.h>
            #endif

I_LOCALE ๐ŸŒˆ

This symbol, if defined, indicates to the C program that it should include locale.h.

โ€ฆstill finishing up I_LOCALE, here's the include that comes with it:

#ifdef I_LOCALE
    #include <locale.h>
#endif

I_XLOCALE

bestie, if this symbol is defined it's the C compiler girlies telling you that the header xlocale.h exists and you can totally include it. see also "NEED_XLOCALE_H" ๐Ÿ’–

#ifdef I_XLOCALE
    #include <xlocale.h>
#endif

IN_LOCALE

this one evaluates to TRUE when the plain locale pragma with no parameter ("use locale") is doing its thing. that's it, that's the whole vibe โœจ

bool  IN_LOCALE

IN_LOCALE_COMPILETIME

TRUE when you're compiling a perl program (yes, "eval" counts too) and the plain locale pragma with no parameter ("use locale") is in effect. giving "compile-time era" energy fr fr ๐ŸŽ€

bool  IN_LOCALE_COMPILETIME

IN_LOCALE_RUNTIME

TRUE when you're executing a perl program (also including "eval") and that same plain locale pragma with no parameter ("use locale") is in effect. runtime girlies rise ๐Ÿ’…

bool  IN_LOCALE_RUNTIME

NEED_XLOCALE_H

if this symbol is defined, it means your C program should #include xlocale.h to get newlocale() and all its little friends. the gang's all here ๐Ÿซถ

Perl_langinfo* / Perl_langinfo8*

described down under "sv_langinfo" โ€” scoot down for the tea โ˜•

PERL_LC_ALL_CATEGORY_POSITIONS_INIT

when this symbol is defined, it hands you the C initializer for an array where element [0] is the first category in the string that "setlocale(LC_ALL, NULL)" returns โ€” but only when not all the categories match โ€” and only on systems running that positional notation life. after element [0] comes "LC_ALL_SEPARATOR", then the category at element [1], and so on down the line. it's giving little lineup of categories ๐Ÿ‘‘

PERL_LC_ALL_SEPARATOR

if defined, this is the string that "setlocale(LC_ALL, NULL)" returns to separate categories that live in different locales, on systems using positional notation instead of 'name=value' pairs. an example on some platforms could be the '/' in "C/"de_DE"/C/"en_UK"/C/C" ๐ŸŒˆ

PERL_LC_ALL_USES_NAME_VALUE_PAIRS

if this symbol is defined, it tells your C program that the string from "setlocale(LC_ALL, NULL)" uses 'name=value;' pairs to say what each category's locale is whenever they're not all set to the same locale. like, for example, "LC_NUMERIC"=C;"LC_CTYPE"="de_DE";... โ€” cute little pairs ๐Ÿ’• when it's not defined, the system is on that positional notation instead.

Perl_localeconv

this is the thread-safe version of the libc localeconv(3). it's literally the same as POSIX::localeconv (returns a hash of the localeconv() fields) except you can call it straight from XS code, no detour needed. heads up though: the hash is mortalized, so you gotta deal with it immediately โ€” it will not wait around for you ๐Ÿ˜ญ

HV *  Perl_localeconv(pTHX)

Perl_setlocale

an (almost) drop-in replacement for the system "setlocale(3)" โ€” same parameters, same info returned โ€” except it gives you the correct underlying "LC_NUMERIC" locale. why does that matter? because regular setlocale will just return "C" if the underlying locale has a non-dot decimal point character, or a non-empty thousands separator for showing off floating point numbers. that's because perl keeps that locale category set so it has a dot and an empty separator, and only briefly flips the locale during the operations where the underlying one is actually required. "Perl_setlocale" knows all this and compensates; regular "setlocale" does not. iykyk ๐Ÿ’…

another reason it's not completely a drop-in replacement: it's declared to return "const char *", whereas the system setlocale omits the "const" (presumably because its API was locked in ages ago and can't be updated; and also because it's straight-up illegal to change the info "setlocale" returns โ€” do that and you get segfaults ๐Ÿ’€).

and finally, "Perl_setlocale" works under all circumstances, whereas plain "setlocale" can be completely ineffective on some platforms under some configurations. iconic behavior from Perl_setlocale, truly.

changing the locale is not a good idea when more than one thread is running โ€” unless you're on systems where the predefined variable "${^SAFE_LOCALES}" is non-zero. on those other systems the locale is global to the entire process, not local to just the thread calling the function, so changing it in one thread instantaneously changes it in all of them. ๐Ÿ˜ฑ and on some such systems, the system setlocale() is ineffective โ€” returns the wrong info and fails to actually change the locale. z/OS straight up refuses to try changing the locale once a second thread is created. "Perl_setlocale" should give you accurate results of what actually happened on these problematic platforms, returning NULL if the system forbade the locale change. periodt.

the return points to a per-thread static buffer, which gets overwritten the next time "Perl_setlocale" is called from the same thread. so don't hold onto it, bestie ๐Ÿ™ˆ

const char *  Perl_setlocale(const int category,
                             const char *locale)

RESTORE_LC_NUMERIC

this works as a duo with one of the macros "STORE_LC_NUMERIC_SET_TO_NEEDED" and "STORE_LC_NUMERIC_FORCE_TO_UNDERLYING" to properly restore the "LC_NUMERIC" state. the comeback arc โœจ

a call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have already been made, to declare at compile time a private variable that this macro and the two "STORE" ones all use. and call this macro as a single statement, not an expression, with an empty argument list, like so:

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   RESTORE_LC_NUMERIC();
    ...
}
void  RESTORE_LC_NUMERIC()

SETLOCALE_ACCEPTS_ANY_LOCALE_NAME

if this symbol is defined, it means the setlocale routine is available and it will accept any input locale name as valid. no judgment, no gatekeeping ๐Ÿซถ

STORE_LC_NUMERIC_FORCE_TO_UNDERLYING

this one's for XS code that's "LC_NUMERIC" locale-aware and wants to force the locale for category "LC_NUMERIC" to be whatever perl thinks the current underlying locale is.

quick tea: the perl interpreter could be wrong about what the underlying locale actually is, if some C or XS code called the C library function setlocale(3) behind its back. calling "sync_locale" before calling this macro will update perl's records. ๐Ÿ‘€

a call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have been made to declare at compile time a private variable used by this macro. call this macro as a single statement, not an expression, with an empty argument list, like this:

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
    ...
   RESTORE_LC_NUMERIC();
    ...
}

that private variable is what saves the current locale state, so the requisite matching call to "RESTORE_LC_NUMERIC" can bring it back. ๐ŸŽ€

on threaded perls that aren't operating with thread-safe functionality, this macro uses a mutex to force a critical section. so the matching RESTORE should be close by and guaranteed to be called โ€” no ghosting it, fr fr.

void  STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()

STORE_LC_NUMERIC_SET_TO_NEEDED

this helps you wrap XS or C code that's "LC_NUMERIC" locale-aware. that locale category is generally kept set to a locale where the decimal radix character is a dot and the separator between groups of digits is empty โ€” because most XS code reading floating point numbers expects exactly that syntax. it's giving "we keep it in this one specific fit" ๐Ÿ’…

this macro makes sure the current "LC_NUMERIC" state is set properly: aware of the locale if the call to the XS or C code from the Perl program comes from within the scope of a "use locale"; or ignoring locale if the call comes from outside such scope.

this macro is the start of wrapping the C or XS code. the wrap ending is done by calling the "RESTORE_LC_NUMERIC" macro after the operation. otherwise the state can get changed and adversely affect other XS code โ€” not the plot twist we want ๐Ÿ˜ญ

a call to "DECLARATION_FOR_LC_NUMERIC_MANIPULATION" must have been made to declare at compile time a private variable used by this macro. call this macro as a single statement, not an expression, with an empty argument list, like this:

{
   DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    ...
   STORE_LC_NUMERIC_SET_TO_NEEDED();
    ...
   RESTORE_LC_NUMERIC();
    ...
}

on threaded perls not operating with thread-safe functionality, this macro uses a mutex to force a critical section. so the matching RESTORE should be close by and guaranteed to be called; see "WITH_LC_NUMERIC_SET_TO_NEEDED" for a more contained way to make sure of that. ๐Ÿซถ

void  STORE_LC_NUMERIC_SET_TO_NEEDED()

STORE_LC_NUMERIC_SET_TO_NEEDED_IN

same as "STORE_LC_NUMERIC_SET_TO_NEEDED", except with in_lc_numeric handed in as the precalculated value of IN_LC(LC_NUMERIC). it is the caller's responsibility to make sure the status of "PL_compiling" and "PL_hints" cannot have changed since that precalculation. so yeah, that's on you bestie ๐ŸŒธ

void  STORE_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric)

sv_langinfo / Perl_langinfo / Perl_langinfo8

these do the equivalent thing as the system "nl_langinfo(3)", taking the same "item" parameter values โ€” but they're preferred over calling that directly, because they're portable to platforms lacking that function, they're thread-safe, and they can automatically handle UTF-8 strings. we love an upgrade ๐Ÿฆ‹

the simplest to use is "sv_langinfo". it returns an SV containing the correct PV and UTF8ness, requiring zero extra muss or fuss from you. new code should use this form. no notes ๐Ÿ’–

"Perl_langinfo" and "Perl_langinfo8" are retained for backwards compatibility. "Perl_langinfo" is an (almost) drop-in replacement for the system "nl_langinfo(3)", except it exists on systems that lack a native "nl_langinfo" too.

"Perl_langinfo8" is identical to "Perl_langinfo" except for one extra parameter: a pointer to a variable declared as "utf8ness_t", into which it returns to you how you should treat the returned string with regards to it being encoded in UTF-8 or not. it's literally the "wait, is this UTF-8?" note ๐Ÿ’œ

"Perl_langinfo" and "Perl_langinfo8" share private per-thread memory that will be changed the next time either one of them is called with any input โ€” but not before. so same energy as the static buffer situation earlier: grab what you need while you can ๐Ÿ™ˆ

concerning the differences between these functions and plain nl_langinfo():

  • a. Perl_langinfo8 has an extra parameter, bestie, which we already talked about above โ˜๏ธ. But like, that's not even the only reason these two aren't a perfect drop-in swap. The other reason is actually a glow-up, not a problem ๐Ÿ’…: the const-ness of the return value means your compiler can catch you trying to write back into the returned buffer โ€” which is illegal and could literally cause run-time crashes. So the compiler is your bodyguard fr fr ๐Ÿซถ.
  • b. They give you the correct results for the RADIXCHAR and THOUSEP items without you having to write a single extra line. Like, why would you even need extra code? Because those two come from the LC_NUMERIC locale category, and Perl normally keeps that category pinned so that the radix is a dot and the separator is the empty string โ€” no matter what the underlying locale is supposed to be ๐ŸŒธ. So to get the expected results you'd have to temporarily toggle into the underlying locale and then toggle back ๐Ÿ™ˆ. (You could use plain nl_langinfo and STORE_LC_NUMERIC_FORCE_TO_UNDERLYING for this, but then you'd be throwing away all the other perks of Perl_langinfo(). And also โ€” not keeping LC_NUMERIC in the C (or equivalent) locale would break a lot of CPAN, which fully expects the radix (decimal point) character to be a dot ๐Ÿ’€.)
  • c. The system function these replace has a static return buffer that can get absolutely obliterated โ€” not just by a later call to that same function, but by a freelocale, a setlocale, or any other locale change ๐Ÿ˜ญ. sv_langinfo sidesteps this whole mess entirely; the returned buffers of the other two aren't touched until the next call to one or the other, so the buffer is never sitting there in a trashed state. Iconic behaviour, honestly ๐Ÿ‘‘.
  • d. The return buffer of Perl_langinfo and Perl_langinfo8 is per-thread, so it also never gets overwritten by a call to these functions from another thread โ€” unlike the function they replace ๐ŸŒˆ. Multi-threaded besties, you're safe.
  • e. But most importantly?? They work on systems that don't have nl_langinfo at all โ€” like Windows โ€” which makes your code way more portable ๐ŸŒโœจ. Out of the fifty-some possible items specified by the POSIX 2008 standard (<https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>), only one is completely unimplemented โ€” though on non-Windows platforms, another significant one is not fully implemented either. They use a bunch of techniques to recover the other items, including calling localeconv(3) and strftime(3), both of which are specified in C89, so they should always be available ๐ŸŽ€. Later strftime() versions have extra capabilities on top. And if an item just isn't available on your system? It returns either the value associated with the C locale, or simply "", whichever is more appropriate ๐Ÿฆ‹.
โš ๏ธ Super important note!! When it's called with an item that gets recovered by using localeconv, the buffer from any previous explicit call to localeconv(3) will be overwritten. But like, you shouldn't be using localeconv anyway, because it is very much not thread-safe, and it suffers from the exact same problems outlined in item b. above for the fields it returns that are controlled by the LC_NUMERIC locale category ๐Ÿ’€. Instead? Dodge all of those problems by calling Perl_localeconv, which is thread-safe โ€” or by using the methods given in perlcall to call POSIX::localeconv(), which is also thread-safe ๐Ÿซถ.

The details for those items which may deviate from what this emulation returns versus what a native nl_langinfo() would return are specified in I18N::Langinfo ๐Ÿ“š.

           SV *               sv_langinfo   (      const nl_item item)
           SV *          Perl_sv_langinfo   (pTHX_ const nl_item item)
           const char *       Perl_langinfo (      const nl_item item)
           const char *       Perl_langinfo8(      const nl_item item,
                                                    utf8ness_t *utf8ness)

โœจ switch_to_global_locale โœจ

Okay so this function copies the locale state of the calling thread into the program's global locale, and then converts that thread to use the global locale ๐ŸŒ€.

Why would you ever want this? It's so Perl can be safely used alongside C libraries that access the global locale and that just can't be converted to not access it ๐Ÿ™ƒ. In practice, that means libraries which call setlocale(3) on non-Windows systems. (And fr, for portability it's a good idea to use it on Windows too ๐ŸชŸ.)

The downside, bestie, is that it disables all the services Perl provides to hide locale gotchas from your code ๐Ÿ˜ญ. The service you'll miss the most? The one about the radix character (decimal point) in floating point numbers. Code that runs after this function is called can no longer just assume that character is correct for the current circumstances. It's giving chaos energy.

To return to Perl control and restart those anti-gotcha services, call sync_locale ๐Ÿ”„. And heads up: behavior is undefined for any pure Perl code that executes while the switch is in effect ๐Ÿšจ.

The global locale and the per-thread locales are totally independent. As long as just one thread converts to the global locale, everything runs smoothly ๐ŸŒธ. But if more than one does?? They can easily interfere with each other, and races are likely ๐Ÿ’€. On Windows systems prior to Visual Studio 15 (that's the version where Microsoft fixed a bug), races can occur โ€” even if only one thread has been converted to the global locale โ€” but only if you use the following operations:

POSIX::localeconv
I18N::Langinfo, items "CRNCYSTR" and "THOUSEP"
"sv_langinfo" in perlapi, items "CRNCYSTR" and "THOUSEP"

The first item isn't fixable (except by upgrading to a later Visual Studio release ๐Ÿ˜ฌ), but it would be possible to work around the latter two by having Perl change its algorithm for calculating these to use Windows API functions (likely GetNumberFormat and GetCurrencyFormat) โ€” so like, patches welcome!! ๐Ÿ™

And a big one: XS code should never call plain setlocale. Instead it should be converted to either call Perl_setlocale (which is a drop-in for the system setlocale), or use the methods given in perlcall to call POSIX::setlocale ๐ŸŒŸ. Either one transparently handles all the cases of single- vs multi-thread, POSIX 2008-supported or not. Chef's kiss.

            void       switch_to_global_locale()
            void  Perl_switch_to_global_locale(pTHX)

โœจ sync_locale โœจ

This one copies the state of the program global locale into the calling thread, and converts that thread to using per-thread locales if it wasn't already โ€” assuming the platform supports them ๐ŸŒ€. And the LC_NUMERIC locale gets toggled into the standard state (using the C locale's conventions) if you're not within the lexical scope of use locale.

After this, Perl will now consider itself to have control of the locale ๐Ÿ‘‘.

Fun fact: since unthreaded perls only have a global locale, this function is a no-op when there are no threads ๐Ÿซ .

It's intended for use with C libraries that do locale manipulation โ€” it lets Perl accommodate the use of them ๐Ÿ™Œ. Call this function before transferring back to Perl space, so it knows what state the C code has left things in ๐Ÿง .

XS code should not manipulate the locale on its own. Instead, Perl_setlocale can be used at any time to query or change the locale โ€” though, real talk, changing the locale is antisocial and dangerous on multi-threaded systems that don't have multi-thread safe locale operations โš ๏ธ (see "Multi-threaded operation" in perllocale).

Using the libc setlocale(3) function should be avoided ๐Ÿšซ. Nevertheless, certain non-Perl libraries called from XS do call it, and their behavior may not be able to be changed. So this function, along with switch_to_global_locale, can be used to get seamless behavior in these circumstances โ€” as long as only one thread is involved ๐ŸŽ€.

Oh and, if the library has an option to turn off its locale manipulation, doing that is preferable to using this mechanism ๐ŸŒˆ. Gtk is such a library, iykyk.

The return value is a boolean: TRUE if the global locale at the time of call was in effect for the caller, and FALSE if a per-thread locale was in effect โœจ.

            bool       sync_locale()
            bool  Perl_sync_locale(pTHX)

โœจ WITH_LC_NUMERIC_SET_TO_NEEDED โœจ

This macro invokes the statement or block you hand it, inside the context of a STORE_LC_NUMERIC_SET_TO_NEEDED .. RESTORE_LC_NUMERIC pair โ€” but only if it's required ๐Ÿช„. So, for example, this:

  WITH_LC_NUMERIC_SET_TO_NEEDED(
    SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis)
  );

is equivalent to:

  {
#ifdef USE_LOCALE_NUMERIC
    DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
    STORE_LC_NUMERIC_SET_TO_NEEDED();
#endif
    SNPRINTF_G(fv, ebuf, sizeof(ebuf), precis);
#ifdef USE_LOCALE_NUMERIC
    RESTORE_LC_NUMERIC();
#endif
  }
            void  WITH_LC_NUMERIC_SET_TO_NEEDED(block)

โœจ WITH_LC_NUMERIC_SET_TO_NEEDED_IN โœจ

Same as WITH_LC_NUMERIC_SET_TO_NEEDED, bestie, except with in_lc_numeric provided as the precalculated value of IN_LC(LC_NUMERIC) ๐Ÿงฎ. And it is the caller's responsibility to make sure that the status of PL_compiling and PL_hints cannot have changed since that precalculation ๐Ÿ™. No cap.

            void  WITH_LC_NUMERIC_SET_TO_NEEDED_IN(bool in_lc_numeric, block)

๐Ÿช„ Magic ๐Ÿช„

Okay so bestie, "Magic" is this special data that gets attached to SV structures to give them "magical" properties. The whole vibe: when any Perl code tries to read from, or assign to, an SV marked as magical, it calls the 'get' or 'set' function associated with that SV's magic. A get runs before reading an SV, so it gets a chance to update its internal value (get on $. writes the line number of the last read filehandle into the SV's IV slot). A set runs after an SV has been written to, so it can actually make use of its changed value (set on $/ copies the SV's new value to the PL_rs global variable). Fr fr, that's the whole concept. โœจ

Magic is implemented as a linked list of MAGIC structures attached to the SV. Each MAGIC struct holds the type of the magic, a pointer to an array of functions that implement the get(), set(), length() etc. functions, plus space for some flags and pointers. Like, for example, a tied variable has a MAGIC structure that contains a pointer to the object associated with the tie. ๐Ÿ’…

"mg_clear"

Clear something magical that the SV represents. See "sv_magic".

 int       mg_clear(      SV *sv)
 int  Perl_mg_clear(pTHX_ SV *sv)

"mg_copy"

Copies the magic from one SV to another. See "sv_magic".

 int       mg_copy(      SV *sv, SV *nsv, const char *key,
                         I32 klen)
 int  Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key,
                         I32 klen)

"mg_find"

Finds the magic pointer for type matching the SV. See "sv_magic".

 MAGIC *       mg_find(const SV *sv, int type)
 MAGIC *  Perl_mg_find(const SV *sv, int type)

"mg_findext"

Finds the magic pointer of type with the given vtbl for the SV. See "sv_magicext".

 MAGIC *       mg_findext(const SV *sv, int type,
                          const MGVTBL *vtbl)
 MAGIC *  Perl_mg_findext(const SV *sv, int type,
                          const MGVTBL *vtbl)

"mg_free"

Free any magic storage used by the SV. See "sv_magic".

 int       mg_free(      SV *sv)
 int  Perl_mg_free(pTHX_ SV *sv)

"mg_free_type"

Remove any magic of type how from the SV sv. See "sv_magic".

 void       mg_free_type(      SV *sv, int how)
 void  Perl_mg_free_type(pTHX_ SV *sv, int how)

"mg_freeext"

Remove any magic of type how using virtual table vtbl from the SV sv. See "sv_magic".

Heads up bestie: mg_freeext(sv, how, NULL) is equivalent to mg_free_type(sv, how).

 void       mg_freeext(      SV *sv, int how, const MGVTBL *vtbl)
 void  Perl_mg_freeext(pTHX_ SV *sv, int how, const MGVTBL *vtbl)

"mg_get"

Do magic before a value is retrieved from the SV. The type of SV must be >= SVt_PVMG. See "sv_magic".

 int       mg_get(      SV *sv)
 int  Perl_mg_get(pTHX_ SV *sv)

"mg_magical"

Turns on the magical status of an SV. See "sv_magic".

 void       mg_magical(SV *sv)
 void  Perl_mg_magical(SV *sv)

"mg_set"

Do magic after a value is assigned to the SV. See "sv_magic".

 int       mg_set(      SV *sv)
 int  Perl_mg_set(pTHX_ SV *sv)

The Magic Constants โœจ

All of these bad boys right here:

  • MGf_COPY
  • MGf_DUP
  • MGf_LOCAL
  • MGVTBL
  • PERL_MAGIC_arylen
  • PERL_MAGIC_arylen_p
  • PERL_MAGIC_backref
  • PERL_MAGIC_bm
  • PERL_MAGIC_checkcall
  • PERL_MAGIC_collxfrm
  • PERL_MAGIC_dbfile
  • PERL_MAGIC_dbline
  • PERL_MAGIC_debugvar
  • PERL_MAGIC_defelem
  • PERL_MAGIC_destruct
  • PERL_MAGIC_env
  • PERL_MAGIC_envelem
  • PERL_MAGIC_ext
  • PERL_MAGIC_extvalue
  • PERL_MAGIC_fm
  • PERL_MAGIC_hints
  • PERL_MAGIC_hintselem
  • PERL_MAGIC_hook
  • PERL_MAGIC_hookelem
  • PERL_MAGIC_isa
  • PERL_MAGIC_isaelem
  • PERL_MAGIC_lvref
  • PERL_MAGIC_nkeys
  • PERL_MAGIC_nonelem
  • PERL_MAGIC_overload_table
  • PERL_MAGIC_pos
  • PERL_MAGIC_qr
  • PERL_MAGIC_regdata
  • PERL_MAGIC_regdatum
  • PERL_MAGIC_regex_global
  • PERL_MAGIC_rhash
  • PERL_MAGIC_shared
  • PERL_MAGIC_shared_scalar
  • PERL_MAGIC_sig
  • PERL_MAGIC_sigelem
  • PERL_MAGIC_substr
  • PERL_MAGIC_sv
  • PERL_MAGIC_symtab
  • PERL_MAGIC_taint
  • PERL_MAGIC_tied
  • PERL_MAGIC_tiedelem
  • PERL_MAGIC_tiedscalar
  • PERL_MAGIC_utf8
  • PERL_MAGIC_uvar
  • PERL_MAGIC_uvar_elem
  • PERL_MAGIC_vec
  • PERL_MAGIC_vstring

Described in perlguts. ๐Ÿ“–

"SvTIED_obj"

Described in perlinterp.

 SvTIED_obj(SV *sv, MAGIC *mg)

๐Ÿง  Memory Management ๐Ÿง 

"dump_mstats"

When enabled by compiling with -DDEBUGGING_MSTATS, print out statistics about malloc as two lines of numbers, one showing the length of the free list for each size category, the second showing the number of mallocs - frees for each size category.

s, if not NULL, is used as a phrase to include in the output, such as "after compilation".

 void       dump_mstats(      const char *s)
 void  Perl_dump_mstats(pTHX_ const char *s)

"HAS_MALLOC_GOOD_SIZE"

This symbol, if defined, indicates that the malloc_good_size routine is available for use.

"HAS_MALLOC_SIZE"

This symbol, if defined, indicates that the malloc_size routine is available for use.

"HASATTRIBUTE_MALLOC"

Can we handle GCC attribute for malloc-style functions.

"I_MALLOCMALLOC"

This symbol, if defined, indicates to the C program that it should include malloc/malloc.h.

 #ifdef I_MALLOCMALLOC
     #include <mallocmalloc.h>
 #endif

"MYMALLOC"

This symbol, if defined, indicates that we're using our own malloc.

"Newx", "safemalloc"

The XSUB-writer's interface to the C malloc function.

โš ๏ธ Memory obtained by this should ONLY be freed with Safefree.

In 5.9.3, Newx() and friends replace the older New() API, and drops the first parameter, x, a debug aid which allowed callers to identify themselves. That aid has been superseded by a new build option, PERL_MEM_LOG (see "PERL_MEM_LOG" in perlhacktips). The older API is still there for use in XS modules supporting older perls.

 void   Newx      (void* ptr, int nitems, type)
 void*  safemalloc(size_t size)

"Newxc"

The XSUB-writer's interface to the C malloc function, with cast. See also "Newx".

โš ๏ธ Memory obtained by this should ONLY be freed with Safefree.
 void  Newxc(void* ptr, int nitems, type, cast)

"Newxz", "safecalloc"

The XSUB-writer's interface to the C calloc function. The allocated memory is zeroed with memzero. See also "Newx".

โš ๏ธ Memory obtained by this should ONLY be freed with Safefree.
 void   Newxz     (void* ptr, int nitems, type)
 void*  safecalloc(size_t nitems, size_t item_size)

"PERL_MALLOC_WRAP"

This symbol, if defined, indicates that we'd like malloc wrap checks.

"Renew", "saferealloc"

The XSUB-writer's interface to the C realloc function.

โš ๏ธ Memory obtained by this should ONLY be freed with Safefree.
 void   Renew      (void* ptr, int nitems, type)
 void*  saferealloc(void *ptr, size_t size)

"Renewc"

The XSUB-writer's interface to the C realloc function, with cast.

โš ๏ธ Memory obtained by this should ONLY be freed with Safefree.
 void  Renewc(void* ptr, int nitems, type, cast)

"safecalloc*"

Described under "Newxz"

"Safefree"

The XSUB-writer's interface to the C free function.

๐Ÿšจ This should ONLY be used on memory obtained using Newx and friends.
 void  Safefree(void* ptr)

"safemalloc*"

Described under "Newx"

"saferealloc*"

Described under "Renew"

"safesyscalloc"

Safe version of system's calloc()

 Malloc_t       safesyscalloc(MEM_SIZE elements, MEM_SIZE size)
 Malloc_t  Perl_safesyscalloc(MEM_SIZE elements, MEM_SIZE size)

"safesysfree"

Safe version of system's free()

 Free_t       safesysfree(Malloc_t where)
 Free_t  Perl_safesysfree(Malloc_t where)

"safesysmalloc"

Paranoid version of system's malloc()

 Malloc_t       safesysmalloc(MEM_SIZE nbytes)
 Malloc_t  Perl_safesysmalloc(MEM_SIZE nbytes)

"safesysrealloc"

Paranoid version of system's realloc()

 Malloc_t       safesysrealloc(Malloc_t where, MEM_SIZE nbytes)
 Malloc_t  Perl_safesysrealloc(Malloc_t where, MEM_SIZE nbytes)

๐ŸŽ€ MRO ๐ŸŽ€

okay bestie so these functions are all about the method resolution order of perl classes โ€” like, whose method wins when the inheritance drama kicks in. Also go look at perlmroapi for the whole side quest. ๐Ÿฆ‹


HvMROMETA

Described in perlmroapi.

struct mro_meta *  HvMROMETA(HV *hv)

mro_get_from_name

Hands you back the mro that got registered earlier under name, or NULL if nobody ever registered that name. See "mro_register".

const struct mro_alg *  Perl_mro_get_from_name(pTHX_ SV *name)

mro_get_linear_isa

Returns the mro linearisation for the stash you pass in. By default that's whatever mro_get_linear_isa_dfs gives you, unless some other MRO is in effect for that stash. The thing you get back is a read-only AV* whose values are string SVs holding class names.

โš ๏ธ bestie, listen: you are responsible for SvREFCNT_inc() on the return value if you're planning to stash it anywhere semi-permanently. Otherwise it might get deleted right out from under you the next time the cache gets invalidated. ๐Ÿ˜ญ
AV *       mro_get_linear_isa(      HV *stash)
AV *  Perl_mro_get_linear_isa(pTHX_ HV *stash)

MRO_GET_PRIVATE_DATA

Described in perlmroapi.

SV*  MRO_GET_PRIVATE_DATA(struct mro_meta *const smeta,
                          const struct mro_alg *const which)

mro_method_changed_in

Invalidates method caching on any child classes of the stash you give it, so they get a chance to notice the changes you made to this one. ๐Ÿ’…

Ideally, every single instance of PL_sub_generation++ in perl source outside of mro.c should be replaced by calls to this. That's the dream.

Perl already handles most of the common ways a method might get redefined, automatically. However โ€” plot twist โ€” there are a few ways you could change a method in a stash without the cache code noticing, and in that case you gotta call this method afterwards:

  1. Directly manipulating the stash HV entries from XS code.
  2. Assigning a reference to a readonly scalar constant into a stash entry in order to create a constant subroutine (like constant.pm does).

This same method is available from pure perl via, mro::method_changed_in(classname).

void       mro_method_changed_in(      HV *stash)
void  Perl_mro_method_changed_in(pTHX_ HV *stash)

mro_register

Registers a custom mro plugin. See perlmroapi for the details on this and the other mro functions. โœจ

void  Perl_mro_register(pTHX_ const struct mro_alg *mro)

mro_set_mro

Sets meta to the value contained in the registered mro plugin whose name is name. ๐Ÿซถ

Croaks if name hasn't been registered. no cap.
void  Perl_mro_set_mro(pTHX_ struct mro_meta * const meta,
                             SV * const name)

mro_set_private_data

Described in perlmroapi.

SV *  Perl_mro_set_private_data(pTHX_
                              struct mro_meta * const smeta,
                              const struct mro_alg * const which,
                              SV * const data)

๐ŸŒˆ Multicall Functions ๐ŸŒˆ

dMULTICALL

Declares the local variables for a multicall. See "LIGHTWEIGHT CALLBACKS" in perlcall. ๐Ÿ’–

dMULTICALL;

MULTICALL

Makes a lightweight callback. See "LIGHTWEIGHT CALLBACKS" in perlcall.

MULTICALL;

POP_MULTICALL

The closing bracket for a lightweight callback. See "LIGHTWEIGHT CALLBACKS" in perlcall.

POP_MULTICALL;

PUSH_MULTICALL

The opening bracket for a lightweight callback. See "LIGHTWEIGHT CALLBACKS" in perlcall.

PUSH_MULTICALL(CV* the_cv);

๐Ÿ“ Numeric Functions ๐Ÿ“

Atof*

Described under "my_atof".

grok_atoUV

Parses a string, looking for a decimal unsigned integer. ๐Ÿ”ข

On entry, pv points to the beginning of the string; valptr points to a UV that will receive the converted value, if found; endptr is either NULL or points to a variable that points to one byte beyond the point in pv that this routine should examine. If endptr is NULL, pv is assumed to be NUL-terminated.

Returns FALSE if pv doesn't represent a valid unsigned integer value (with no leading zeros). Otherwise it returns TRUE, and sets *valptr to that value.

If you constrain the portion of pv that gets looked at by this function (by passing a non-NULL endptr), and if the initial bytes of that portion form a valid value, it will return TRUE, setting *endptr to the byte following the final digit of the value. But if there's no constraint on what's looked at, all of pv must be valid for TRUE to be returned. *endptr is unchanged from its value on input if FALSE is returned.

The only characters this accepts are the decimal digits '0'..'9'.

As opposed to atoi(3) or strtol(3), grok_atoUV does NOT allow optional leading whitespace, nor negative inputs. If such features are required, the calling code needs to explicitly implement those. it's giving DIY ๐Ÿ’€

Note that this function returns FALSE for inputs that would overflow a UV, or that have leading zeros. So a single 0 is accepted, but not 00 nor 01, 002, etc. ๐Ÿ™ˆ

Background: atoi has severe problems with illegal inputs, it cannot be used for incremental parsing, and therefore should be avoided. atoi and strtol are also affected by locale settings, which can also be seen as a bug (global state controlled by user environment). yikes.

bool       grok_atoUV(const char *pv, UV *valptr,
                      const char **endptr)
bool  Perl_grok_atoUV(const char *pv, UV *valptr,
                      const char **endptr)

grok_infnan

The helper for grok_number(), it accepts various ways of spelling "infinity" or "not a number", and returns one of the following flag combinations: โœจ

IS_NUMBER_INFINITY
IS_NUMBER_NAN
IS_NUMBER_INFINITY | IS_NUMBER_NEG
IS_NUMBER_NAN | IS_NUMBER_NEG
0

...possibly |-ed with "IS_NUMBER_TRAILING".

If an infinity or a not-a-number is recognized, *sp will point to one byte past the end of the recognized string. If the recognition fails, zero is returned, and *sp will not move.

int       grok_infnan(      const char **sp, const char *send)
int  Perl_grok_infnan(pTHX_ const char **sp, const char *send)

grok_number

grok_number_flags

Look for a base 10 number in the len bytes starting at pv. If one isn't found, return 0; otherwise return its type (and optionally its value). In grok_number all len bytes must be either leading isSPACE characters or part of the number. Same energy in grok_number_flags, unless flags contains the PERL_SCAN_TRAILING bit, which allows for trailing non-numeric text. (That's literally the only difference between the two functions, bestie.)

The returned type is the ORing of various bits (#defined in perl.h) as described below:

  • If the number is negative, the returned type will include the IS_NUMBER_NEG bit.
  • If the absolute value of the integral portion of the found number fits in a UV, the returned type will include the IS_NUMBER_IN_UV bit. If it won't fit, instead the IS_NUMBER_GREATER_THAN_UV_MAX bit will be included.
  • If the found number is not an integer, the returned type will include the IS_NUMBER_NOT_INT bit. This happens either if the number is expressed in exponential e notation, or if it includes a decimal point (radix) character. If exponential notation is used, then neither IS_NUMBER_IN_UV nor IS_NUMBER_GREATER_THAN_UV_MAX bits are set. Otherwise, the integer part of the number is used to determine the IS_NUMBER_IN_UV and IS_NUMBER_GREATER_THAN_UV_MAX bits.
  • If the found number is a string indicating it is infinity, the IS_NUMBER_INFINITY and IS_NUMBER_NOT_INT bits are included in the returned type.
  • If the found number is a string indicating it is not a number, the IS_NUMBER_NAN and IS_NUMBER_NOT_INT bits are included in the returned type.

You can get the number's absolute integral value returned to you by calling these functions with a non-NULL valuep argument. If the returned type includes the IS_NUMBER_IN_UV bit, *valuep will be set to the correct value. Otherwise, it could well have been zapped with garbage. ๐Ÿ™ˆ lowkey cursed.

In grok_number_flags when flags contains the PERL_SCAN_TRAILING bit, and trailing non-numeric text was found, the returned type will include the IS_NUMBER_TRAILING bit.

int       grok_number      (      const char *pv, STRLEN len,
                                  UV *valuep)
int  Perl_grok_number      (pTHX_ const char *pv, STRLEN len,
                                  UV *valuep)
int       grok_number_flags(      const char *pv, STRLEN len,
                                  UV *valuep, U32 flags)
int  Perl_grok_number_flags(pTHX_ const char *pv, STRLEN len,
                                  UV *valuep, U32 flags)

grok_numeric_radix

GROK_NUMERIC_RADIX

These two are identical. twins fr fr. ๐Ÿ‘ฏ

Scan and skip for a numeric decimal separator (radix).

bool       grok_numeric_radix(      const char **sp,
                                    const char *send)
bool  Perl_grok_numeric_radix(pTHX_ const char **sp,
                                    const char *send)
bool       GROK_NUMERIC_RADIX(      const char **sp,
                                    const char *send)

isinfnan

Perl_isinfnan() is a utility function that returns true if the NV argument is either an infinity or a "NaN", and false otherwise. To test in more detail, use Perl_isinf() and Perl_isnan(). ๐Ÿฆ‹

This is also the logical inverse of Perl_isfinite().

bool       isinfnan(NV nv)
bool  Perl_isinfnan(NV nv)

my_atof

Atof

These each are atof(3), but properly working with Perl locale handling โ€” they accept a dot radix character always, but also the current locale's radix character if and only if called from within the lexical scope of a Perl use locale statement. ๐ŸŒ

N.B. s must be NUL terminated. just so you know bestie.
NV       my_atof(      const char *s)
NV  Perl_my_atof(pTHX_ const char *s)
NV       Atof   (      const char * const s)

my_strtod

Strtod

These are identical.

They act like the libc strtod(3) function, with three exceptions:

  1. Their return value is an NV. Plain strod returns a double precision value.
  2. Plain strtod is always gonna expect the radix character (or string) to be whatever the underlying locale the program is running in says it is. And like, that's almost universally a dot (U+002E) or a comma (U+002C). ๐Ÿ’…

But these ones? They expect the radix to be a dot, except when you're calling them from inside the scope of use locale โ€” in that case they act just like plain strtod, expecting whatever radix the current locale specifies. ๐ŸŒ

  1. These are available even on platforms that straight up don't have plain strtod(). Iconic behavior honestly.
NV       my_strtod(const char * const s, char **e)
NV  Perl_my_strtod(const char * const s, char **e)
NV       Strtod   (const char * const s, char **e)

PERL_ABS ๐Ÿซถ

Typeless abs or fabs, etc. (the usage below says it's for integers but bestie it works for any type). Use this instead of the C library ones, because those force their argument to be what they expect and that can lead to disaster ๐Ÿ˜ญ. But also, heads up: this evaluates its argument twice, so no x++. She's greedy like that.

 int  PERL_ABS(int x)

The math girlies: Perl_acos, Perl_asin, Perl_atan, Perl_atan2, Perl_ceil, Perl_cos, Perl_cosh, Perl_exp, Perl_floor, Perl_fmod, Perl_frexp, Perl_isfinite, Perl_isinf, Perl_isnan, Perl_ldexp, Perl_log, Perl_log10, Perl_modf, Perl_pow, Perl_sin, Perl_sinh, Perl_sqrt, Perl_tan, Perl_tanh ๐ŸŒˆ

All of these do the corresponding mathematical operation on the operand(s), using the libc function built for the job that has just enough precision for an NV on this platform. And if no such function with sufficient precision exists? Then you get the highest precision one that does exist. Something is better than nothing, periodt. โœจ

NV  Perl_acos    (NV x)
NV  Perl_asin    (NV x)
NV  Perl_atan    (NV x)
NV  Perl_atan2   (NV x, NV y)
NV  Perl_ceil    (NV x)
NV  Perl_cos     (NV x)
NV  Perl_cosh    (NV x)
NV  Perl_exp     (NV x)
NV  Perl_floor   (NV x)
NV  Perl_fmod    (NV x, NV y)
NV  Perl_frexp   (NV x, int *exp)
IV  Perl_isfinite(NV x)
IV  Perl_isinf   (NV x)
IV  Perl_isnan   (NV x)
NV  Perl_ldexp   (NV x, int exp)
NV  Perl_log     (NV x)
NV  Perl_log10   (NV x)
NV  Perl_modf    (NV x, NV *iptr)
NV  Perl_pow     (NV x, NV y)
NV  Perl_sin     (NV x)
NV  Perl_sinh    (NV x)
NV  Perl_sqrt    (NV x)
NV  Perl_tan     (NV x)
NV  Perl_tanh    (NV x)

Perl_signbit ๐Ÿšจ

NOTE: Perl_signbit is experimental and may change or be removed without notice. Ma'am is on thin ice.

Returns a non-zero integer if the sign bit on an NV is set, and 0 if it is not. ๐Ÿ’€

If Configure detects that this system has a signbit() that'll work with our NVs, then we just use it via the #define in perl.h. Otherwise we fall back on this implementation. The main use of this function is catching -0.0. Yes, negative zero is real and she's lurking.

Configure notes: this function is called Perl_signbit instead of a plain signbit because it's so easy to imagine a system having a signbit() function or macro that just doesn't happen to work with our particular choice of NVs. We shouldn't just re-#define signbit as Perl_signbit and expect the standard system headers to be happy about it. ๐Ÿ™ˆ Also, this is a no-context function (no pTHX_) because Perl_signbit() is usually re-#defined in perl.h as a simple macro call to the system's signbit(). Users should just always call Perl_signbit(). No cap.

 int  Perl_signbit(NV f)

Perl_sin*, Perl_sinh*, Perl_sqrt*, Perl_tan*, Perl_tanh* ๐ŸŒธ

Described under Perl_acos. Go look, bestie, they're all hanging out up there together.

PL_hexdigit ๐Ÿ”ข

This array, indexed by an integer, converts that value into the character that represents it. Like, if the input is 8, the return will be a string whose first character is '8'. What you actually get back is a pointer into a string, and all you care about is the first character of that string. Feral but fine.

Wanna get uppercase letters (for the values 10..15)? Add 16 to the index. Hence, PL_hexdigit[11] is 'b', and PL_hexdigit[11+16] is 'B'. And adding 16 to an index whose representation is '0'..'9' gives you the same thing as not adding 16. Cute.

Indices outside the range 0..31 result in bad undefined behavior. Stay in your lane, babes. ๐Ÿšซ

READ_XDIGIT โญ

Returns the value of an ASCII-range hex digit and advances the string pointer. Behaviour is only well defined when isXDIGIT(*str) is true. That's it, that's the whole vibe.

 U8  READ_XDIGIT(char str*)

scan_bin ๐Ÿฆ‹

For backwards compatibility. Use grok_bin instead. She's a legacy queen, respect her, but move on. ๐Ÿ’œ

 NV       scan_bin(      const char *start, STRLEN len,
                                STRLEN *retlen)
 NV  Perl_scan_bin(pTHX_ const char *start, STRLEN len,
                                STRLEN *retlen)

scan_hex ๐Ÿงš

For backwards compatibility. Use grok_hex instead.

 NV       scan_hex(      const char *start, STRLEN len,
                                STRLEN *retlen)
 NV  Perl_scan_hex(pTHX_ const char *start, STRLEN len,
                                STRLEN *retlen)

scan_oct ๐Ÿ’–

For backwards compatibility. Use grok_oct instead.

 NV       scan_oct(      const char *start, STRLEN len,
                                STRLEN *retlen)
 NV  Perl_scan_oct(pTHX_ const char *start, STRLEN len,
                                STRLEN *retlen)

Strtod* ๐ŸŒŸ

Described under my_strtod. Same family, same reunion, just scroll up a lil.

Strtol ๐Ÿ‘‘

Platform and configuration independent strtol. This expands to the appropriate strotol-like function based on the platform and Configure options>. So like, it could expand to strtoll or strtoq instead of strtol. Surprise! She's versatile.

 NV  Strtol(const char * const s, char ** e, int base)

Strtoul ๐ŸŽ€

Platform and configuration independent strtoul. This expands to the appropriate strotoul-like function based on the platform and Configure options>. For example it could expand to strtoull or strtouq instead of strtoul. Unsigned and unbothered.

 NV  Strtoul(const char * const s, char ** e, int base)

๐ŸŒณ Optrees ๐ŸŒณ

alloccopstash ๐Ÿ”ฅ

NOTE: alloccopstash is experimental and may change or be removed without notice.

Available only under threaded builds, this function allocates an entry in PL_stashpad for the stash passed to it. Threaded builds only, bestie โ€” if you're not threaded, this is not your moment.

 PADOFFSET       alloccopstash(      HV *hv)
 PADOFFSET  Perl_alloccopstash(pTHX_ HV *hv)

BINOP ๐Ÿ’…

Described in perlguts. Go read it, iykyk.

block_end ๐ŸŽ€

Handles compile-time scope exit. floor is the savestack index returned by block_start, and seq is the body of the block. Returns the block, possibly modified. She closes the door behind you, gently. ๐Ÿซถ

 OP *       block_end(      I32 floor, OP *seq)
 OP *  Perl_block_end(pTHX_ I32 floor, OP *seq)

block_start โœจ

Handles compile-time scope entry. Arranges for hints to be restored on block exit and also handles pad sequence numbers so lexical variables scope right. Returns a savestack index for use with block_end. She opens the door AND leaves you a key (the index). main character energy.

 int       block_start(      int full)
 int  Perl_block_start(pTHX_ int full)

ck_entersub_args_list ๐ŸŒธ

Performs the default fixup of the arguments part of an entersub op tree. This consists of applying list context to each of the argument ops. This is the standard treatment used on a call marked with &, or a method call, or a call through a subroutine reference, or any other call where the callee can't be identified at compile time, or a call where the callee has no prototype. Basically the everything-else bucket and she handles it flawlessly. ๐Ÿ’–

 OP *       ck_entersub_args_list(      OP *entersubop)
 OP *  Perl_ck_entersub_args_list(pTHX_ OP *entersubop)

ck_entersub_args_proto ๐Ÿฆ‹

Performs the fixup of the arguments part of an entersub op tree based on a subroutine prototype. This makes various modifications to the argument ops, from applying context up to inserting refgen ops, and checking the number and syntactic types of arguments, as directed by the prototype. This is the standard treatment used on a subroutine call, not marked with &, where the callee can be identified at compile time and has a prototype. She's the strict one, but make it fashion. ๐Ÿ’…

protosv supplies the subroutine prototype to be applied to the call. It may be a normal defined scalar, in which case the string value will be used. Alternatively, for convenience, it may be a subroutine object (a CV* that has been cast to SV*) which has a prototype. The prototype supplied, in whichever form, does not need to match the actual callee referenced by the op tree. Yes really, she's chill like that.

If the argument ops disagree with the prototype, like by having an unacceptable number of arguments, a valid op tree is returned anyway. The error gets reflected in the parser state, normally resulting in a single exception at the top level of parsing which covers all the compilation errors that occurred. In the error message, the callee is referred to by the name defined by the namegv parameter. So she reports it, but she doesn't panic. ๐Ÿ‘‘

 OP *       ck_entersub_args_proto(      OP *entersubop,
                                         GV *namegv, SV *protosv)
 OP *  Perl_ck_entersub_args_proto(pTHX_ OP *entersubop,
                                         GV *namegv, SV *protosv)

ck_entersub_args_proto_or_list ๐ŸŒˆ

Performs the fixup of the arguments part of an entersub op tree either based on a subroutine prototype or using default list-context processing. This is the standard treatment used on a subroutine call, not marked with &, where the callee can be identified at compile time. She's the flexible icon who decides which of her two friends to call. ๐Ÿซถ

protosv supplies the subroutine prototype to be applied to the call, or indicates that there is no prototype. It may be a normal scalar, in which case if it is defined then the string value will be used as a prototype, and if it is undefined then there is no prototype. Alternatively, for convenience, it may be a subroutine object (a CV* that has been cast to SV*), of which the prototype will be used if it has one. The prototype (or lack thereof) supplied, in whichever form, does not need to match the actual callee referenced by the op tree. Same energy as her sister up there. ๐Ÿ’œ

Okay bestie, this one's a chonk, so grab a snack ๐Ÿ“ โ€” we're in the middle of a call-checker glow-up and there's SO much here.

If the argument ops are out here disagreeing with the prototype โ€” like, showing up with an unacceptable number of arguments, rude ๐Ÿ’€ โ€” a valid op tree gets returned anyway. The drama doesn't vanish, it just gets reflected in the parser state, and that normally turns into a single exception at the top level of parsing, one that covers every compilation error that happened. And in that error message, the callee is referred to by the name that the namegv parameter defines. Iykyk.

OP *       ck_entersub_args_proto_or_list(      OP *entersubop,
                                                GV *namegv,
                                                SV *protosv)
OP *  Perl_ck_entersub_args_proto_or_list(pTHX_ OP *entersubop,
                                                GV *namegv,
                                                SV *protosv)

cop_disable_warning

Makes sure the set of warning bits a COP is carrying does not include the warning you point at โ€” you pick that warning with one of the WARN_... constants from warnings.h. โœจ

If the COP already doesn't include that warning, nothing changes, no notes. But if it does, the stored warning bitmask gets cloned, and your given warning bit gets disabled inside that clone. The COP itself is modified in-place, which is exactly why this function is only meant to be used at compiletime, while the optree is being constructed. Don't come for it at runtime, fr.

void       cop_disable_warning(      COP *cop, int warn_bit)
void  Perl_cop_disable_warning(pTHX_ COP *cop, int warn_bit)

cop_enable_warning

The mirror twin ๐Ÿชž โ€” this one makes sure the set of warning bits the COP is carrying does include the warning you name, again picked from the WARN_... constants in warnings.h.

If the COP already includes that warning, no modification happens, easy. Otherwise, the stored warning bitmask is cloned and the given warning bit gets enabled inside it. Same deal as its sibling: the COP is modified in-place, so this is compiletime-only territory, for when the optree is being built. ๐Ÿ› ๏ธ

void       cop_enable_warning(      COP *cop, int warn_bit)
void  Perl_cop_enable_warning(pTHX_ COP *cop, int warn_bit)

cop_has_warning

Returns true ๐Ÿ’– if the set of warning bits contained by the COP โ€” or implied by it โ€” contains the given warning, as specified by one of the WARN_... constants from warnings.h. That's it, that's the whole vibe check.

bool       cop_has_warning(      const COP *cop, int warn_bit)
bool  Perl_cop_has_warning(pTHX_ const COP *cop, int warn_bit)

cv_const_sv

If cv is a constant sub that's eligible for inlining, this hands you back the constant value that the sub returns. If it's not, you get NULL. No half measures, periodt.

Constant subs can be made with newCONSTSUB, or the way it's described in "Constant Functions" in perlsub. ๐Ÿ‘‘

SV *       cv_const_sv(const CV * const cv)
SV *  Perl_cv_const_sv(const CV * const cv)

cv_get_call_checker

This is the original form of cv_get_call_checker_flags, and the one difference is that it does not return checker flags. Heads up though: when you're using a checker function that was returned by this function, it's only safe to call it with a genuine GV as its namegv argument. No substitutes, bestie. ๐Ÿšซ

void       cv_get_call_checker(      CV *cv,
                                     Perl_call_checker *ckfun_p,
                                     SV **ckobj_p)
void  Perl_cv_get_call_checker(pTHX_ CV *cv,
                                     Perl_call_checker *ckfun_p,
                                     SV **ckobj_p)

cv_get_call_checker_flags

This retrieves the function that's gonna be used to fix up a call to cv. To be specific: the function gets applied to an entersub op tree for a subroutine call that is not marked with &, where the callee can be identified at compile time as cv. Like, that's the whole assignment. ๐Ÿ’…

The C-level function pointer comes back in *ckfun_p, an SV argument for it comes back in *ckobj_p, and the control flags come back in *ckflags_p. The function is intended to be called like this:

entersubop = (*ckfun_p)(aTHX_ entersubop, namegv, (*ckobj_p));

In that call, entersubop is a pointer to the entersub op โ€” which the check function may replace โ€” and namegv supplies the name the check function should use to refer to the callee of the entersub op, if it needs to emit any diagnostics. And yes, it is permitted to apply the check function in non-standard situations, like to a call to a different subroutine, or to a method call. Go off I guess โœจ

Now, namegv may not actually be a GV. If the CALL_CHECKER_REQUIRE_GV bit is clear in *ckflags_p, it's permitted to pass a CV or other SV instead โ€” literally anything that can be used as the first argument to cv_name. But if the CALL_CHECKER_REQUIRE_GV bit is set in *ckflags_p, then the check function requires namegv to be a genuine GV. No cosplay allowed. ๐ŸŽญ

By default, the check function is Perl_ck_entersub_args_proto_or_list, the SV parameter is cv itself, and the CALL_CHECKER_REQUIRE_GV flag is clear. That's what implements standard prototype processing. You can change it, for a particular subroutine, with cv_set_call_checker_flags.

Okay here's the flag lore: if the CALL_CHECKER_REQUIRE_GV bit is set in gflags, that indicates the caller only knows about the genuine GV version of namegv, and accordingly the corresponding bit will always be set in *ckflags_p, regardless of what the check function recorded as its requirements. If the CALL_CHECKER_REQUIRE_GV bit is clear in gflags, that indicates the caller knows about the possibility of passing something other than a GV as namegv, and accordingly the corresponding bit may be either set or clear in *ckflags_p, indicating the check function's recorded requirements. ๐Ÿง 

gflags is a bitset passed into cv_get_call_checker_flags, and in it only the CALL_CHECKER_REQUIRE_GV bit currently has a defined meaning (see the paragraph you just read ๐Ÿ’–). All other bits should be clear.

void       cv_get_call_checker_flags(CV *cv, U32 gflags,
                                     Perl_call_checker *ckfun_p,
                                     SV **ckobj_p,
                                     U32 *ckflags_p)
void  Perl_cv_get_call_checker_flags(pTHX_ CV *cv, U32 gflags,
                                     Perl_call_checker *ckfun_p,
                                     SV **ckobj_p,
                                     U32 *ckflags_p)

cv_set_call_checker

The original form of cv_set_call_checker_flags, which just passes it the CALL_CHECKER_REQUIRE_GV flag for backward-compatibility. And the effect of setting that flag is that the check function is guaranteed to get a genuine GV as its namegv argument. No surprises, chef's kiss ๐Ÿ‘จโ€๐Ÿณ๐Ÿ’‹

void       cv_set_call_checker(      CV *cv,
                                     Perl_call_checker ckfun,
                                     SV *ckobj)
void  Perl_cv_set_call_checker(pTHX_ CV *cv,
                                     Perl_call_checker ckfun,
                                     SV *ckobj)

cv_set_call_checker_flags

Sets the function that will be used to fix up a call to cv. Same deal as the getter: the function is applied to an entersub op tree for a subroutine call not marked with &, where the callee can be identified at compile time as cv. ๐ŸŽฏ

The C-level function pointer is supplied in ckfun, an SV argument for it is supplied in ckobj, and control flags are supplied in ckflags. The function should be defined like this:

static OP * ckfun(pTHX_ OP *op, GV *namegv, SV *ckobj)

And it's intended to be called in this manner:

entersubop = ckfun(aTHX_ entersubop, namegv, ckobj);

In that call, entersubop is a pointer to the entersub op โ€” which may be replaced by the check function โ€” and namegv supplies the name that should be used by the check function to refer to the callee of the entersub op if it needs to emit any diagnostics. It is permitted to apply the check function in non-standard situations, such as to a call to a different subroutine or to a method call. Non-standard? We love a little chaos ๐Ÿฆ‹

namegv may not actually be a GV. For efficiency, perl may pass a CV or other SV instead. Whatever gets passed can be used as the first argument to cv_name. And if you really need a real GV, you can force perl to pass one by including CALL_CHECKER_REQUIRE_GV in the ckflags. ๐Ÿ’ช

ckflags is a bitset, and in it only the CALL_CHECKER_REQUIRE_GV bit currently has a defined meaning (for which, see above ๐Ÿ’–). All other bits should be clear.

You can grab the current setting for a particular CV with cv_get_call_checker_flags.

void       cv_set_call_checker_flags(    CV *cv,
                                         Perl_call_checker ckfun,
                                         SV *ckobj, U32 ckflags)
void  Perl_cv_set_call_checker_flags(pTHX_ CV *cv,
                                         Perl_call_checker ckfun,
                                         SV *ckobj, U32 ckflags)

finalize_optree

This function finalizes the optree. It should be called directly after the complete optree is built โ€” like, right after, don't dawdle. It does some additional checking that can't be done in the normal ck_xxx functions, and it makes the tree thread-safe. ๐Ÿงตโœจ

void       finalize_optree(      OP *o)
void  Perl_finalize_optree(pTHX_ OP *o)

forbid_outofblock_ops

NOTE: forbid_outofblock_ops is experimental and may change or be removed without notice. Bestie, do not build your whole personality on this one. ๐Ÿ˜ญ

It checks an optree that implements a block, to make sure there are no control-flow ops that are trying to leave the block. Any OP_RETURN is forbidden, and so is any OP_GOTO. Loops get analysed too, so any LOOPEX op (OP_NEXT, OP_LAST or OP_REDO) that affects a loop which contains it within the block is permitted โ€” but any of those that don't? Forbidden. ๐Ÿšซ

If any of these forbidden constructions get detected, an exception is thrown, using the op name and the blockname argument to construct a suitable message.

And a big caveat, because this matters: this function alone is not sufficient to ensure the optree doesn't perform any of these forbidden activities during runtime. Why? Because it might call a different function that performs a non-local LOOPEX, or a string-eval() that performs a goto, or various other things. It's intended purely as a compile-time check for the stuff that could be detected statically. Additional runtime checks may be required depending on the circumstance it's used for. โš ๏ธ

Also note, currently all OP_GOTO ops are forbidden, even in cases where they might otherwise be safe to execute. That may be permitted in a later version, so watch this space. ๐Ÿ‘€


            void       forbid_outofblock_ops(      OP *o,
                                                   const char *blockname)
            void  Perl_forbid_outofblock_ops(pTHX_ OP *o,
                                                   const char *blockname)

That's the last of that one, bestie โ€” moving on ๐Ÿ’…

okay so you hand this the root of an optree and it links the whole tree in execution order using the op_next pointers, then returns the very first op that gets executed. ๐Ÿฆ‹

If this has already been done? It does not redo it โ€” it just returns o->op_next. And if o->op_next isn't already set, then heads up: o should be at least an UNOP. No exceptions, fr fr.

 OP*  LINKLIST(OP *o)

"LISTOP"

"LOGOP"

"LOOP"

Described in perlguts. (go read it, iykyk ๐Ÿ“–โœจ)

"newANONATTRSUB"

Constructs a nameless (anonymous) Perl subroutine โ€” and yes, it also does some surrounding jobs while it's at it. multitasking queen ๐Ÿ‘‘

This is the same as "newATTRSUB_x" in perlintern with its o_is_gv parameter set to FALSE, and its o parameter to NULL. For more details, see "newATTRSUB_x" in perlintern.

 OP *       newANONATTRSUB(      I32 floor, OP *proto, OP *attrs,
                                 OP *block)
 OP *  Perl_newANONATTRSUB(pTHX_ I32 floor, OP *proto, OP *attrs,
                                 OP *block)

"newANONHASH"

Constructs, checks, and returns an anonymous hash op. cute and anonymous ๐Ÿ’œ

 OP *       newANONHASH(      OP *o)
 OP *  Perl_newANONHASH(pTHX_ OP *o)

"newANONLIST"

Constructs, checks, and returns an anonymous list op. ๐Ÿ’–

 OP *       newANONLIST(      OP *o)
 OP *  Perl_newANONLIST(pTHX_ OP *o)

"newANONSUB"

Constructs a nameless (anonymous) Perl subroutine without attributes, also performing some surrounding jobs. no attrs, all vibe ๐ŸŒธ

This is the same as "newATTRSUB_x" in perlintern with its o_is_gv parameter set to FALSE, and its o and attrs parameters to NULL. For more details, see "newATTRSUB_x" in perlintern.

 OP *       newANONSUB(      I32 floor, OP *proto, OP *block)
 OP *  Perl_newANONSUB(pTHX_ I32 floor, OP *proto, OP *block)

"newARGDEFELEMOP"

Constructs and returns a new OP_ARGDEFELEM op which provides a defaulting expression given by expr for the signature parameter at the index given by argindex. The expression optree is consumed by this function and becomes part of the returned optree. so like, it's yours now, the op took it ๐Ÿซถ

 OP *       newARGDEFELEMOP(      I32 flags, OP *expr,
                                  I32 argindex)
 OP *  Perl_newARGDEFELEMOP(pTHX_ I32 flags, OP *expr,
                                  I32 argindex)

"newASSIGNOP"

Constructs, checks, and returns an assignment op. left and right supply the parameters of the assignment; they are consumed by this function and become part of the constructed op tree.

okay so here's the tea on optype โ˜•:

  • If optype is OP_ANDASSIGN, OP_ORASSIGN, or OP_DORASSIGN, then a suitable conditional optree gets constructed.
  • If optype is the opcode of a binary operator, such as OP_BIT_OR, then an op is constructed that performs the binary operation and assigns the result to the left argument.
  • Either way, if optype is non-zero then flags has no effect. (periodt ๐Ÿ’…)

If optype is zero, then a plain scalar or list assignment is constructed. Which type of assignment it is is automatically determined. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically, and, shifted up eight bits, the eight bits of op_private, except that the bit with value 1 or 2 is automatically set as required.

 OP *       newASSIGNOP(      I32 flags, OP *left, I32 optype,
                              OP *right)
 OP *  Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype,
                              OP *right)

"newATTRSUB"

Constructs a Perl subroutine, also performing some surrounding jobs, returning a pointer to the constructed subroutine. so much going on, honestly iconic ๐Ÿ”ฅ

This is the same as "newATTRSUB_x" in perlintern with its o_is_gv parameter set to FALSE. This means that if o is null, the new sub will be anonymous; otherwise the name will be derived from o in the way described (as with all other details) in "newATTRSUB_x" in perlintern.

 CV *       newATTRSUB(      I32 floor, OP *o, OP *proto,
                             OP *attrs, OP *block)
 CV *  Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto,
                             OP *attrs, OP *block)

"newAVREF"

Constructs, checks, and returns an arrary reference op. ๐ŸŽ€

(that's "arrary" as printed bestie, i don't make the typos, i just faithfully preserve them โœจ)

 OP *       newAVREF(      OP *o)
 OP *  Perl_newAVREF(pTHX_ OP *o)

"newBINOP"

Constructs, checks, and returns an op of any binary type. type is the opcode. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically, and, shifted up eight bits, the eight bits of op_private, except that the bit with value 1 or 2 is automatically set as required. first and last supply up to two ops to be the direct children of the binary op; they are consumed by this function and become part of the constructed op tree.

 OP *       newBINOP(      I32 type, I32 flags, OP *first,
                           OP *last)
 OP *  Perl_newBINOP(pTHX_ I32 type, I32 flags, OP *first,
                           OP *last)

"newCONDOP"

Constructs, checks, and returns a conditional-expression (cond_expr) op. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically, and, shifted up eight bits, the eight bits of op_private, except that the bit with value 1 is automatically set. first supplies the expression selecting between the two branches, and trueop and falseop supply the branches; they are consumed by this function and become part of the constructed op tree. choosing sides but make it structural ๐ŸŒˆ

 OP *       newCONDOP(      I32 flags, OP *first, OP *trueop,
                            OP *falseop)
 OP *  Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop,
                            OP *falseop)

"newCONSTSUB"

"newCONSTSUB_flags"

Constructs a constant subroutine, also performing some surrounding jobs. A scalar constant-valued subroutine is eligible for inlining at compile-time, and in Perl code can be created by sub FOO () { 123 }. Other kinds of constant subroutine have other treatment. constant queen behavior ๐Ÿ‘‘

The subroutine will have an empty prototype and will ignore any arguments when called. Its constant behaviour is determined by sv:

  • If sv is null, the subroutine will yield an empty list.
  • If sv points to a scalar, the subroutine will always yield that scalar.
  • If sv points to an array, the subroutine will always yield a list of the elements of that array in list context, or the number of elements in the array in scalar context.

This function takes ownership of one counted reference to the scalar or array, and will arrange for the object to live as long as the subroutine does. If sv points to a scalar then the inlining assumes that the value of the scalar will never change, so the caller must ensure that the scalar is not subsequently written to. If sv points to an array then no such assumption is made, so it is ostensibly safe to mutate the array or its elements, but whether this is really supported has not been determined.

so like, scalar = don't you dare touch it after, understood? array = allegedly fine but nobody's actually confirmed that bestie ๐Ÿ’€

The subroutine will have CvFILE set according to PL_curcop. Other aspects of the subroutine will be left in their default state. The caller is free to mutate the subroutine beyond its initial state after this function has returned.

If name is null then the subroutine will be anonymous, with its CvGV referring to an __ANON__ glob. If name is non-null then the subroutine will be named accordingly, referenced by the appropriate glob.

name is a string, giving a sigilless symbol name. For /newCONSTSUB, name is NUL-terminated, interpreted as Latin-1.

For /newCONSTSUB_flags, name has length len bytes, hence may contain embedded NULs. It is interpreted as UTF-8 if flags has the SVf_UTF8 bit set, and Latin-1 otherwise. flags should not have bits set other than SVf_UTF8.

The name may be either qualified or unqualified. If the name is unqualified then it defaults to being in the stash specified by stash if that is non-null, or to PL_curstash if stash is null. The symbol is always added to the stash if necessary, with GV_ADDMULTI semantics.

If there is already a subroutine of the specified name, then the new sub will replace the existing one in the glob. A warning may be generated about the redefinition.

If the subroutine has one of a few special names, such as BEGIN or END, then it will be claimed by the appropriate queue for automatic running of phase-related subroutines. In this case the relevant glob will be left not containing any subroutine, even if it did contain one before. Execution of the subroutine will likely be a no-op, unless sv was a tied array or the caller modified the subroutine in some interesting way before it was executed.

๐Ÿšจ In the case of BEGIN, the treatment is buggy: the sub will be executed when only half built, and may be deleted prematurely, possibly causing a crash. not cute, not slay, be careful!!

The function returns a pointer to the constructed subroutine. If the sub is anonymous then ownership of one counted reference to the subroutine is transferred to the caller. If the sub is named then the caller does not get ownership of a reference. In most such cases, where the sub has a non-phase name, the sub will be alive at the point it is returned by virtue of being contained in the glob that names it. A phase-named subroutine will usually be alive by virtue of the reference owned by the phase's automatic run queue. A BEGIN subroutine may have been destroyed already by the time this function returns, but currently bugs occur in that case before the caller gets control. It is the caller's responsibility to ensure that it knows which of these situations applies. ๐Ÿซ 

 CV *       newCONSTSUB      (      HV *stash, const char *name,
                                    SV *sv)
 CV *  Perl_newCONSTSUB      (pTHX_ HV *stash, const char *name,
                                    SV *sv)
 CV *       newCONSTSUB_flags(      HV *stash, const char *name,
                                    STRLEN len, U32 flags, SV *sv)
 CV *  Perl_newCONSTSUB_flags(pTHX_ HV *stash, const char *name,
                                    STRLEN len, U32 flags, SV *sv)

newCVREF

constructs, checks, and hands you back a code reference op ๐Ÿ’–

OP *       newCVREF(      I32 flags, OP *o)
OP *  Perl_newCVREF(pTHX_ I32 flags, OP *o)

newDEFEROP

โš ๏ธ bestie heads up: newDEFEROP is experimental and may change or get yeeted without notice ๐Ÿ˜ญ

Constructs and returns a deferred-block statement โ€” the thing that makes defer semantics happen โœจ The block optree gets consumed by this function and becomes part of the returned optree, so likeโ€ฆ it's not yours anymore, she ate it ๐Ÿ’…

The flags argument carries extra flags to set on the returned op, op_private field included.

OP *       newDEFEROP(      I32 flags, OP *block)
OP *  Perl_newDEFEROP(pTHX_ I32 flags, OP *block)

newDEFSVOP

constructs and returns an op that accesses $_ ๐Ÿซถ

OP *       newDEFSVOP()
OP *  Perl_newDEFSVOP(pTHX)

newFOROP

Constructs, checks, and returns an op tree that expresses a foreach loop โ€” aka iteration through a list of values ๐Ÿ”ฅ This one is a heavyweight loop, ok? Structure-wise it's built to let you exit the loop with last and all that good stuff.

sv optionally supplies the variable(s) that get aliased to each item in turn; if it's null, it defaults to $_. expr supplies the list of values to iterate over. block supplies the main body of the loop, and cont optionally supplies a continue block that works as a second half of the body ๐ŸŒธ All of these optree inputs get consumed by this function and become part of the constructed op tree.

flags gives the eight bits of op_flags for the leaveloop op and, shifted up eight bits, the eight bits of op_private for the leaveloop op โ€” except that (in both cases) some bits get set automatically, because of course they do ๐Ÿ™ˆ

OP *       newFOROP(      I32 flags, OP *sv, OP *expr, OP *block,
                          OP *cont)
OP *  Perl_newFOROP(pTHX_ I32 flags, OP *sv, OP *expr, OP *block,
                          OP *cont)

newGIVENOP

Constructs, checks, and returns an op tree expressing a given block โœจ cond supplies the expression to whose value $_ will be locally aliased, and block supplies the body of the given construct; they get consumed by this function and become part of the constructed op tree. defsv_off must be zero (it used to identify the pad slot of lexical $_ โ€” that era is over, no cap).

OP *       newGIVENOP(      OP *cond, OP *block,
                            PADOFFSET defsv_off)
OP *  Perl_newGIVENOP(pTHX_ OP *cond, OP *block,
                            PADOFFSET defsv_off)

newGVOP

Constructs, checks, and returns an op of any type that involves an embedded reference to a GV ๐Ÿ‘‘ type is the opcode. flags gives the eight bits of op_flags. gv identifies the GV that the op should reference โ€” and real talk: calling this function does not transfer ownership of any reference to it. nope, not even a little ๐Ÿซถ

OP *       newGVOP(      I32 type, I32 flags, GV *gv)
OP *  Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv)

newGVREF

constructs, checks, and returns a glob reference op ๐ŸŒˆ

OP *       newGVREF(      I32 type, OP *o)
OP *  Perl_newGVREF(pTHX_ I32 type, OP *o)

newHVREF

constructs, checks, and returns a hash reference op ๐Ÿ’œ

OP *       newHVREF(      OP *o)
OP *  Perl_newHVREF(pTHX_ OP *o)

newLISTOP

Constructs, checks, and returns an op of any list type โœจ type is the opcode. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically if it's required. first and last supply up to two ops to be direct children of the list op; they get consumed by this function and become part of the constructed op tree.

Now here's the tea for most list operators: the check function expects all the kid ops to already be present, so calling newLISTOP(OP_JOIN, ...) (e.g.) is not it, bestie ๐Ÿ’€ What you actually want to do in that case is create an op of type OP_LIST, append more children to it, and then call op_convert_list. See op_convert_list for more info ๐Ÿ‘€

If a compiletime-known fixed list of child ops is required, the newLISTOPn function can be used as a convenient shortcut โ€” avoiding the need to create a temporary plain OP_LIST in a new variable. slay ๐ŸŽ€

OP *       newLISTOP(      I32 type, I32 flags, OP *first,
                           OP *last)
OP *  Perl_newLISTOP(pTHX_ I32 type, I32 flags, OP *first,
                           OP *last)

newLISTOPn

Constructs, checks, and returns an op of any list type ๐Ÿ’– type is the opcode. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically if it's required. The variable number of arguments after flags must all be OP pointers, terminated by a final NULL pointer. All of them get consumed as direct children of the list op and become part of the constructed op tree.

๐Ÿšจ do not forget to end the arguments list with a NULL pointer. I'm so serious rn ๐Ÿ˜ญ

This function is useful as a shortcut to performing the sequence of newLISTOP(), op_append_elem() on each element and final op_convert_list() in the case where a compiletime-known fixed sequence of child ops is required. If you need a variable number of elements, or you're splicing in an entire sub-list of child ops, see newLISTOP and op_convert_list instead ๐ŸŒธ

OP *       newLISTOPn(      I32 type, I32 flags, ...)
OP *  Perl_newLISTOPn(pTHX_ I32 type, I32 flags, ...)

newLOGOP

Constructs, checks, and returns a logical (flow control) op โœจ type is the opcode. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically, and, shifted up eight bits, the eight bits of op_private, except that the bit with value 1 is automatically set. first supplies the expression controlling the flow, and other supplies the side (alternate) chain of ops; they get consumed by this function and become part of the constructed op tree.

OP *       newLOGOP(      I32 optype, I32 flags, OP *first,
                          OP *other)
OP *  Perl_newLOGOP(pTHX_ I32 optype, I32 flags, OP *first,
                          OP *other)

newLOOPEX

Constructs, checks, and returns a loop-exiting op (like goto or last ๐Ÿ˜ค). type is the opcode. label supplies the parameter determining the target of the op; it gets consumed by this function and becomes part of the constructed op tree.

OP *       newLOOPEX(      I32 type, OP *label)
OP *  Perl_newLOOPEX(pTHX_ I32 type, OP *label)

newLOOPOP

Constructs, checks, and returns an op tree expressing a loop ๐Ÿ”ฅ This is only a loop in the control flow through the op tree; it does not have the heavyweight loop structure that lets you exit by last and suchlike. So likeโ€ฆ lightweight loop behavior, not the whole production ๐ŸŽ€

flags gives the eight bits of op_flags for the top-level op, except that some bits get set automatically as required. expr supplies the expression controlling loop iteration, and block supplies the body of the loop; they get consumed by this function and become part of the constructed op tree. debuggable is currently unused and should always be 1.

OP *       newLOOPOP(      I32 flags, I32 debuggable, OP *expr,
                           OP *block)
OP *  Perl_newLOOPOP(pTHX_ I32 flags, I32 debuggable, OP *expr,
                           OP *block)

newMETHOP

Constructs, checks, and returns an op of method type with a method name evaluated at runtime ๐Ÿฆ‹ type is the opcode. flags gives the eight bits of op_flags, except that OPf_KIDS will be set automatically, and, shifted up eight bits, the eight bits of op_private, except that the bit with value 1 is automatically set. dynamic_meth supplies an op which evaluates the method name; it gets consumed by this function and becomes part of the constructed op tree. Supported optypes: OP_METHOD.

OP *       newMETHOP(      I32 type, I32 flags, OP *dynamic_meth)
OP *  Perl_newMETHOP(pTHX_ I32 type, I32 flags, OP *dynamic_meth)

newMETHOP_named

Constructs, checks, and returns an op of method type with a constant method name ๐Ÿ’… type is the opcode. flags gives the eight bits of op_flags, and, shifted up eight bits, the eight bits of op_private. const_meth supplies a constant method name; it must be a shared COW string. Supported optypes: OP_METHOD_NAMED.

OP *       newMETHOP_named(      I32 type, I32 flags,
                                 SV * const_meth)
OP *  Perl_newMETHOP_named(pTHX_ I32 type, I32 flags,
                                 SV * const_meth)

newNULLLIST

Constructs, checks, and returns a new stub op, which represents an empty list expression ๐Ÿซถ

OP *       newNULLLIST()
OP *  Perl_newNULLLIST(pTHX)

newOP

Constructs, checks, and returns an op of any base type โ€” any type that has no extra fields โœจ type is the opcode. flags gives the eight bits of op_flags, and, shifted up eight bits, the eight bits of op_private.

OP *       newOP(      I32 optype, I32 flags)
OP *  Perl_newOP(pTHX_ I32 optype, I32 flags)

newPADOP

Constructs, checks, and returns an op of any type that involves a reference to a pad element ๐Ÿ’œ type is the opcode. flags gives the eight bits of op_flags. A pad slot is automatically allocated, and it gets populated with sv; this function takes ownership of one reference to it.

๐Ÿ‘€ this function only exists if Perl has been compiled to use ithreads.
OP *       newPADOP(      I32 type, I32 flags, SV *sv)
OP *  Perl_newPADOP(pTHX_ I32 type, I32 flags, SV *sv)

newPMOP

Constructs, checks, and returns an op of any pattern matching type ๐ŸŒˆ type is the opcode. flags gives the eight bits of op_flags and, shifted up eight bits, the eight bits of op_private.

OP *       newPMOP(      I32 type, I32 flags)
OP *  Perl_newPMOP(pTHX_ I32 type, I32 flags)

newPVOP

Constructs, checks, and returns an op of any type that involves an embedded C-level pointer (PV) โญ type is the opcode. flags gives the eight bits of op_flags. pv supplies the C-level pointer.

๐Ÿ˜ญ careful bestie: depending on the op type, the memory referenced by pv may be freed when the op is destroyed. If the op is of a freeing type, pv must have been allocated using PerlMemShared_malloc.
            OP *       newPVOP(      I32 type, I32 flags, char *pv)
            OP *  Perl_newPVOP(pTHX_ I32 type, I32 flags, char *pv)

(the newPVOP lore continues, bestie โ€” you already got the deets up top, here's the sig again so you don't have to scroll ๐Ÿ’…)


newRANGE

Okay so this one constructs and returns a range op, and it brings friends โ€” subordinate flip and flop ops come along with it. iconic trio behavior honestly.

WAIT. flags is doing double duty here, and you gotta pay attention: it gives the eight bits of op_flags for the flip op and, shifted up eight bits, the eight bits of op_private for both the flip and range ops โ€” except that the bit with value 1 is automatically set, so don't you dare try to manage that one yourself โœจ

left and right supply the expressions controlling the endpoints of the range. And heads up: they are consumed by this function and become part of the constructed op tree. Eaten. Gone. Belongs to the tree now ๐Ÿฆ‹

            OP *       newRANGE(      I32 flags, OP *left, OP *right)
            OP *  Perl_newRANGE(pTHX_ I32 flags, OP *left, OP *right)

newSLICEOP

Constructs, checks, and returns an lslice (list slice) op. the full glow-up pipeline, checks included ๐Ÿ’–

flags gives the eight bits of op_flags โ€” except that OPf_KIDS will be set automatically, no input needed โ€” and, shifted up eight bits, the eight bits of op_private โ€” except that the bit with value 1 or 2 is automatically set as required. so yeah, the function is doing some of your homework for you, you're welcome.

listval and subscript supply the parameters of the slice; they are consumed by this function and become part of the constructed op tree. (note the signature calls the second one listop โ€” that's the listval in question, don't @ me, that's just how it is ๐Ÿ™ˆ)

            OP *       newSLICEOP(      I32 flags, OP *subscript, OP *listop)
            OP *  Perl_newSLICEOP(pTHX_ I32 flags, OP *subscript, OP *listop)

newSTATEOP

Constructs a state op (a COP, for the cop-enjoyers out there ๐Ÿ‘‘). Normally it's a nextstate op, BUT โ€” plot twist โ€” it'll be a dbstate op if debugging is enabled for currently-compiled code. main character can change outfits, it's fine.

The state op gets populated from PL_curcop (or PL_compiling).

If label is non-null, it hands over the name of a label to attach to the state op. And listen: this function takes ownership of the memory pointed at by label, and will free it. so don't go freeing it yourself afterward, that's a double-free jumpscare ๐Ÿ˜ญ

flags gives the eight bits of op_flags for the state op.

If o is null, the state op is just returned. Otherwise the state op gets combined with o into a lineseq list op, and that's what gets returned. o is consumed by this function and becomes part of the returned op tree, as always, the op tree hungers ๐ŸŒธ

            OP *       newSTATEOP(      I32 flags, char *label, OP *o)
            OP *  Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)

newSUB

Constructs a Perl subroutine without attributes, and also handles some surrounding jobs on the side, returning a pointer to the constructed sub. multi-tasking queen ๐ŸŽ€

Here's the tea: this is literally the same as "newATTRSUB_x" in perlintern, just with its o_is_gv parameter set to FALSE and its attrs parameter set to NULL. That's the whole diff.

Which means: if o is null, the new sub will be anonymous. otherwise the name gets derived from o in the way described โ€” along with all the other details โ€” over in "newATTRSUB_x" in perlintern. go read that one for the deep lore, iykyk ๐Ÿ’œ

            CV *       newSUB(      I32 floor, OP *o, OP *proto, OP *block)
            CV *  Perl_newSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *block)

newSVOP

Constructs, checks, and returns an op of any type that involves an embedded SV. versatile!

type is the opcode. flags gives the eight bits of op_flags. sv gives the SV to embed in the op โ€” and this function takes ownership of one reference to it, so mind your refcounts bestie โœจ

            OP *       newSVOP(      I32 type, I32 flags, SV *sv)
            OP *  Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv)

newSVREF

Constructs, checks, and returns a scalar reference op. that's it that's the whole vibe. short king ๐Ÿ‘‘

            OP *       newSVREF(      OP *o)
            OP *  Perl_newSVREF(pTHX_ OP *o)

newTRYCATCHOP

โš ๏ธ NOTE: newTRYCATCHOP is experimental and may change or be removed without notice. do not get attached. do not build your whole personality on it. it could simply evaporate ๐Ÿ’€

Constructs and returns a conditional execution statement that implements the try/catch semantics. so: first, the op tree in tryblock is executed, inside a context that traps exceptions. if an exception occurs, then the optree in catchblock is executed, with the trapped exception set into the lexical variable given by catchvar โ€” and catchvar must be an op of type OP_PADSV, no substitutes accepted.

All the optrees are consumed by this function and become part of the returned op tree. all of them. every last one ๐Ÿฆ‹

The flags argument is currently ignored. (it's just there, chilling, doing nothing, honestly relatable ๐ŸŒธ)

            OP *       newTRYCATCHOP(      I32 flags, OP *tryblock,
                                           OP *catchvar, OP *catchblock)
            OP *  Perl_newTRYCATCHOP(pTHX_ I32 flags, OP *tryblock,
                                           OP *catchvar, OP *catchblock)

newUNOP

Constructs, checks, and returns an op of any unary type. type is the opcode.

flags gives the eight bits of op_flags โ€” except that OPf_KIDS will be set automatically if required โ€” and, shifted up eight bits, the eight bits of op_private โ€” except that the bit with value 1 is automatically set. yes, more auto-setting. the function is generous like that ๐Ÿ’…

first supplies an optional op to be the direct child of the unary op; it is consumed by this function and become part of the constructed op tree.

            OP *       newUNOP(      I32 type, I32 flags, OP *first)
            OP *  Perl_newUNOP(pTHX_ I32 type, I32 flags, OP *first)

newUNOP_AUX

Similar to newUNOP, but it creates an UNOP_AUX struct instead, with op_aux initialised to aux. same energy, different struct, glow-up achieved โœจ

            OP *       newUNOP_AUX(      I32 type, I32 flags, OP *first,
                                         UNOP_AUX_item *aux)
            OP *  Perl_newUNOP_AUX(pTHX_ I32 type, I32 flags, OP *first,
                                         UNOP_AUX_item *aux)

newWHENOP

Constructs, checks, and returns an op tree expressing a when block. ๐ŸŽ€

cond supplies the test expression, and block supplies the block that gets executed if the test evaluates to true. both are consumed by this function and become part of the constructed op tree.

cond will be interpreted DWIMically โ€” often as a comparison against $_ โ€” and it may be null to generate a default block. yes, null cond = the default case, the fallback, the "and if none of that worked" energy ๐Ÿฆ‹

            OP *       newWHENOP(      OP *cond, OP *block)
            OP *  Perl_newWHENOP(pTHX_ OP *cond, OP *block)

newWHILEOP

Constructs, checks, and returns an op tree expressing a while loop. and this is a heavyweight loop, bestie โ€” structure so thicc it lets you bail out of the loop with last and suchlike. no lightweight shortcutting here ๐Ÿซถ

loop is an optional preconstructed enterloop op to use in the loop; if it's null, a suitable op gets constructed automatically, so it's genuinely optional, don't stress.

expr supplies the loop's controlling expression. block supplies the main body of the loop, and cont optionally supplies a continue block that operates as a second half of the body. All of these optree inputs are consumed by this function and become part of the constructed op tree โ€” you know the drill by now ๐Ÿ’€

flags gives the eight bits of op_flags for the leaveloop op and, shifted up eight bits, the eight bits of op_private for the leaveloop op โ€” except that (in both cases) some bits will be set automatically. of course they will.

debuggable is currently unused and should always be 1. so like, just pass 1, okay? it's not doing anything but the vibe check requires it.

has_my can be supplied as true to force the loop body to be enclosed in its own scope. very "i need my own space" of it ๐ŸŒธ

            OP *       newWHILEOP(      I32 flags, I32 debuggable,
                                        LOOP *loop, OP *expr, OP *block,
                                        OP *cont, I32 has_my)
            OP *  Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable,
                                        LOOP *loop, OP *expr, OP *block,
                                        OP *cont, I32 has_my)

newXS

Used by xsubpp to hook up XSUBs as Perl subs. and here's the crucial bit, don't miss it: filename needs to be static storage, as it is used directly as CvFILE(), without a copy being made. so like. if you hand it something that goes away, that's on you and it will hurt ๐Ÿ˜ญ

OA_BASEOP, OA_BINOP, OA_COP, OA_LISTOP, OA_LOGOP, OA_LOOP, OA_PADOP, OA_PMOP, OA_PVOP_OR_SVOP, OA_SVOP, OA_UNOP, OP

Described in perlguts. ๐Ÿ‘‘


op_append_elem

Append an item to the list of ops contained directly within a list-type op, returning the lengthened list. so it's giving "add one more thing to the group chat" energy ๐Ÿ’–

first is the list-type op, and last is the op to append to the list. optype specifies the intended opcode for the list. If first is not already a list of the right type, it will be upgraded into one. glow-up, mandatory edition โœจ

If either first or last is null, the other is returned unchanged. no drama, no fuss.

            OP *       op_append_elem(      I32 optype, OP *first, OP *last)
            OP *  Perl_op_append_elem(pTHX_ I32 optype, OP *first, OP *last)

op_append_list

Concatenate the lists of ops contained directly within two list-type ops, returning the combined list. merging the group chats, periodt ๐Ÿ’…

first and last are the list-type ops to concatenate. optype specifies the intended opcode for the list. If either first or last is not already a list of the right type, it will be upgraded into one. If either first or last is null, the other is returned unchanged.

            OP *       op_append_list(      I32 optype, OP *first, OP *last)
            OP *  Perl_op_append_list(pTHX_ I32 optype, OP *first, OP *last)

OP_CLASS

Return the class of the provided OP: that is, which of the OP structures it uses. so like, "what is this op actually made of" โ€” a personality test for ops ๐Ÿฆ‹

For core ops this currently gets the information out of PL_opargs, which does not always accurately reflect the type used. nglll. but from v5.26 onwards, see also the function op_class which can do a better job of determining the used type. so if you're on a newer perl, go use that one, it actually knows what it's talking about.

For custom ops the type is returned from the registration, and it is up to the registree to ensure it is accurate. so the accuracy of custom ops is a you problem, respectfully ๐Ÿ’€

The value returned will be one of the OA_* constants from op.h.

            U32  OP_CLASS(OP *o)

op_clear

Clean up anything allocated for an OP, except the OP itself. so it tidies the insides but leaves the shell standing.

You may want to use op_null() or op_free() instead. (fr fr, read those first before you go clearing stuff ๐Ÿ™ˆ)

            void       op_clear(      OP *o)
            void  Perl_op_clear(pTHX_ OP *o)

op_contextualize

Applies a syntactic context to an op tree representing an expression. o is the op tree, and context must be G_SCALAR, G_LIST, or G_VOID to specify the context to apply. no other options, those are the three, pick one, choose your fighter ๐ŸŒˆ

The modified op tree is returned.

            OP *       op_contextualize(      OP *o, I32 context)
            OP *  Perl_op_contextualize(pTHX_ OP *o, I32 context)

op_convert_list

Converts o into a list op if it is not one already, and then converts it into the specified type, calling its check function, allocating a target if it needs one, and folding constants. it's the whole makeover sequence in one call โ€” check, target, fold, slay ๐Ÿ’…

A list-type op is usually constructed one kid at a time via newLISTOP, op_prepend_elem and op_append_elem. Then finally it is passed to op_convert_list to make it the right type. that's the workflow, remember it ๐ŸŽ€

            OP *       op_convert_list(      I32 optype, I32 flags, OP *o)
            OP *  Perl_op_convert_list(pTHX_ I32 optype, I32 flags, OP *o)

OP_DESC

Return a short description of the provided OP. just a lil blurb. one-liner. the op's bio, essentially ๐ŸŒธ

            const char *  OP_DESC(OP *o)

op_force_list ๐Ÿ’…

So bestie, this one promotes o โ€” and any siblings it's rolling with โ€” to be an "OP_LIST" if it isn't already one. And if a shiny new "OP_LIST" op had to be created? Its first child is gonna be "OP_PUSHMARK". The returned node itself gets nulled out, leaving only its children behind. It's giving glow-up, but make it structural.

This is lowkey often exactly what you want before you toss an optree into list context, like:

o = op_contextualize(op_force_list(o), G_LIST);
OP *       op_force_list(      OP *o)
OP *  Perl_op_force_list(pTHX_ OP *o)

op_free ๐Ÿฆ‹

Free an op and all its children. Only do this when the op is no longer linked from any optree, okay? No dangling friendships allowed.

Now remember: any op with "OPf_KIDS" set is expected to have a valid "op_first" pointer. So if you're trying to free an op but keep its child op alive, make sure to clear that flag before you call op_free(). Like, for example:

OP *kid = o->op_first; o->op_first = NULL;
o->op_flags &= ~OPf_KIDS;
op_free(o);
void       op_free(      OP *arg)
void  Perl_op_free(pTHX_ OP *arg)

This function is literally the implementation of the "LINKLIST" macro. Do not call it directly, bestie. It's not for you.

OP *       op_linklist(      OP *o)
OP *  Perl_op_linklist(pTHX_ OP *o)

op_lvalue ๐ŸŽ€

NOTE: "op_lvalue" is experimental and may change or be removed without notice. It's giving "vibes may shift, don't build your whole life on it."

So what it does: it propagates lvalue ("modifiable") context to an op and its children. "type" represents the context type, roughly based on the type of op that would do the modifying โ€” except local() is represented by "OP_NULL", 'cause it has no op type of its own (it gets signalled by a flag on the lvalue op instead). Iconic little exception, honestly.

This function detects things that can't be modified, like "$x+1", and generates errors for them. For example, "$x+1 = 2" would cause it to be called with an op of type "OP_ADD" and a "type" argument of "OP_SASSIGN". Not it. Not today.

It also flags things that need to behave specially in an lvalue context, like "$$x = 5" โ€” which might have to vivify a reference in $x. Slay.

OP *       op_lvalue(      OP *o, I32 type)
OP *  Perl_op_lvalue(pTHX_ OP *o, I32 type)

OP_NAME ๐ŸŒธ

Returns the name of the OP you hand it. For core ops it looks the name up from the op_type; for custom ops it gets it from the op_ppaddr. Know your roots, periodt.

const char *  OP_NAME(OP *o)

op_null ๐Ÿ’œ

Neutralizes an op when it's no longer needed but is still linked to from other ops. It's not gone, bestie โ€” it's just serving cunt from the void.

void       op_null(      OP *o)
void  Perl_op_null(pTHX_ OP *o)

op_parent ๐Ÿซถ

Returns the parent OP of "o", if it has a parent. Returns "NULL" otherwise. Orphan arc, valid.

OP *       op_parent(OP *o)
OP *  Perl_op_parent(pTHX_ OP *o)

op_prepend_elem โญ

Prepends an item to the list of ops contained directly within a list-type op, returning the lengthened list. "first" is the op you're prepending to the list, and "last" is the list-type op. "optype" specifies the intended opcode for the list. If "last" isn't already a list of the right type, it gets upgraded into one โ€” glow-up round two. And if either "first" or "last" is null, the other is returned unchanged. Fair.

OP *       op_prepend_elem(      I32 optype, OP *first, OP *last)
OP *  Perl_op_prepend_elem(pTHX_ I32 optype, OP *first, OP *last)

op_scope ๐Ÿ”ฅ

NOTE: "op_scope" is experimental and may change or be removed without notice.

Wraps up an op tree with some additional ops so that at runtime a dynamic scope will be created. The original ops run in the new dynamic scope, and then โ€” provided that they exit normally โ€” the scope gets unwound. The additional ops used to create and unwind the dynamic scope are normally an "enter"/"leave" pair, but a "scope" op may be used instead if the ops are simple enough to not need the full dynamic scope structure. Choose your fighter.

OP *       op_scope(      OP *o)
OP *  Perl_op_scope(pTHX_ OP *o)

op_sibling_splice ๐Ÿงš

A general function for editing the structure of an existing chain of op_sibling nodes. By analogy with the perl-level splice() function, it lets you delete zero or more sequential nodes, replacing them with zero or more different nodes. It performs the necessary op_first/op_last housekeeping on the parent node, plus op_sibling manipulation on the children. The last deleted node gets marked as the last node by updating the op_sibling/op_sibparent or op_moresib field as appropriate. Housekeeping but make it structural. ๐Ÿ’…

Note that op_next is not manipulated, and nodes are not freed โ€” that's the caller's whole responsibility, bestie. It also won't create a new list op for an empty list etc; use higher-level functions like op_append_elem() for that.

"parent" is the parent node of the sibling chain. It may be passed as "NULL" if the splicing doesn't affect the first or last op in the chain.

"start" is the node preceding the first node to be spliced. Node(s) following it will be deleted, and ops will be inserted after it. If it's "NULL", the first node onwards is deleted, and nodes are inserted at the beginning.

"del_count" is the number of nodes to delete. If zero, no nodes are deleted. If -1, or greater than or equal to the number of remaining kids, all remaining kids are deleted. Bye.

"insert" is the first of a chain of nodes to be inserted in place of the nodes. If "NULL", no nodes are inserted.

The head of the chain of deleted ops is returned, or "NULL" if no ops were deleted.

For example:

action                    before      after         returns
------                    -----       -----         -------

                          P           P
splice(P, A, 2, X-Y-Z)    |           |             B-C
                          A-B-C-D     A-X-Y-Z-D

                          P           P
splice(P, NULL, 1, X-Y)   |           |             A
                          A-B-C-D     X-Y-B-C-D

                          P           P
splice(P, NULL, 3, NULL)  |           |             A-B-C
                          A-B-C-D     D

                          P           P
splice(P, B, 0, X-Y)      |           |             NULL
                          A-B-C-D     A-B-X-Y-C-D

For lower-level direct manipulation of "op_sibparent" and "op_moresib", see "OpMORESIB_set", "OpLASTSIB_set", "OpMAYBESIB_set".

OP *       op_sibling_splice(      OP *parent, OP *start,
                                   int del_count, OP *insert)
OP *  Perl_op_sibling_splice(pTHX_ OP *parent, OP *start,
                                   int del_count, OP *insert)

OP_TYPE_IS ๐ŸŒˆ

Returns true if the given OP is not a "NULL" pointer and if it's of the given type. Vibe check: passed.

The negation of this macro, "OP_TYPE_ISNT", is also available, as well as "OP_TYPE_IS_NN" and "OP_TYPE_ISNT_NN" โ€” which elide the NULL pointer check. Efficiency queen.

bool  OP_TYPE_IS(OP *o, Optype type)

OP_TYPE_IS_OR_WAS ๐Ÿ’€

Returns true if the given OP is not a NULL pointer and if it's of the given type, or used to be before being replaced by an OP of type OP_NULL. It's giving former self, still valid.

The negation of this macro, "OP_TYPE_ISNT_AND_WASNT", is also available, as well as "OP_TYPE_IS_OR_WAS_NN" and "OP_TYPE_ISNT_AND_WASNT_NN" โ€” which elide the "NULL" pointer check.

bool  OP_TYPE_IS_OR_WAS(OP *o, Optype type)

op_wrap_finally ๐ŸŒŸ

NOTE: "op_wrap_finally" is experimental and may change or be removed without notice.

Wraps the given "block" optree fragment in its own scoped block, arranging for the "finally" optree fragment to be invoked when leaving that block for any reason. Both optree fragments are consumed, and the combined result is returned. No leftovers, we ate. ๐Ÿ“

OP *       op_wrap_finally(      OP *block, OP *finally)
OP *  Perl_op_wrap_finally(pTHX_ OP *block, OP *finally)

opcode ๐Ÿ‘‘

An enum of all the legal Perl opcodes, defined in opnames.h. The whole alphabet of ops, fr fr.

OpHAS_SIBLING ๐ŸŽ€

Returns true if "o" has a sibling. Not lonely.

bool  OpHAS_SIBLING(OP *o)

OpLASTSIB_set ๐Ÿ’œ

Marks "o" as having no further siblings and marks o as having the specified parent. See also "OpMORESIB_set" and "OpMAYBESIB_set". For a higher-level interface, see "op_sibling_splice". And that's the last one, literally.

void  OpLASTSIB_set(OP *o, OP *parent)

OpMAYBESIB_set โœจ

Conditionally does "OpMORESIB_set" or "OpLASTSIB_set" depending on whether "sib" is non-null. For a higher-level interface, see "op_sibling_splice". It's giving "we'll see".

void  OpMAYBESIB_set(OP *o, OP *sib, OP *parent)

OpMORESIB_set ๐Ÿฆ‹

Sets the sibling of "o" to the non-zero value "sib". See also "OpLASTSIB_set" and "OpMAYBESIB_set". For a higher-level interface, see "op_sibling_splice". More siblings? Yes ma'am.

void  OpMORESIB_set(OP *o, OP *sib)

OpSIBLING ๐ŸŒธ

Returns the sibling of "o", or "NULL" if there's no sibling. Either way, we're checking.

OP*  OpSIBLING(OP *o)

optimize_optree ๐Ÿ”ฅ

This function applies some optimisations to the optree in top-down order. It gets called before the peephole optimizer, which processes ops in execution order. Note that finalize_optree() also does a top-down scan, but is called after the peephole optimizer. Order matters, bestie.

void       optimize_optree(      OP *o)
void  Perl_optimize_optree(pTHX_ OP *o)

peep_t, Perl_cpeep_t ๐Ÿ‘‘

Described in perlguts. Go read that one, iykyk.

PL_opfreehook ๐Ÿ’–

When non-"NULL", the function pointed to by this variable will be called each time an OP is freed, with the corresponding OP as the argument. This allows extensions to free any extra attribute they have locally attached to an OP. It's also assured to first fire for the parent OP and then for its kids โ€” parents first, always. ๐Ÿ‘‘

When you replace this variable, it's considered a good practice to store the possibly previously installed hook and to recall it inside your own. Chain of custody, but make it code.

On threaded perls, each thread has an independent copy of this variable; each initialized at creation time with the current value of the creating thread's copy. Every thread gets its own.

Perl_ophook_t  PL_opfreehook

PL_peepp ๐Ÿซถ

Pointer to the per-subroutine peephole optimiser. This is a function that gets called at the end of compilation of a Perl subroutine (or equivalently independent piece of Perl code) to perform fixups of some ops and to perform small-scale optimisations. The function is called once for each subroutine that is compiled, and is passed, as its sole parameter, a pointer to the op that is the entry point to the subroutine. It modifies the op tree in place. No copies, no notes. ๐Ÿ’…


Okay so like โ€” the peephole optimiser should never be completely replaced. Ever. Bestie, don't do it. Instead, you add code to it by wrapping the existing optimiser, and the basic way to do that is shown in "Compile pass 3: peephole optimization" in perlguts. And if your new code wants to operate on ops throughout the whole subroutine's structure rather than just at the top level, it's probably gonna be way more convenient to wrap the PL_rpeepp hook instead. ๐Ÿซถ

On threaded perls, each thread has an independent copy of this variable; each one gets initialized at creation time with the current value of the creating thread's copy. No sharing, no drama. โœจ

peep_t  PL_peepp

PL_rpeepp

Pointer to the recursive peephole optimiser. ๐Ÿ’… This is a function that gets called at the end of compilation of a Perl subroutine (or, equivalently, an independent piece of Perl code) to perform fixups of some ops and to perform small-scale optimisations. It's called once for each chain of ops linked through their op_next fields, and it's recursively called to handle each side chain. As its sole parameter it gets a pointer to the op at the head of the chain. And it modifies the op tree in place. obviously.

Same energy as before: the peephole optimiser should never be completely replaced. Add code to it by wrapping the existing optimiser instead โ€” the basic way to do that is in "Compile pass 3: peephole optimization" in perlguts. But if your new code only wants to mess with ops at a subroutine's top level rather than throughout the whole structure, it's probably more convenient to wrap the PL_peepp hook. ๐ŸŽ€

And on threaded perls, each thread has an independent copy of this variable, each initialized at creation time with the current value of the creating thread's copy. Same as its sibling up there.

peep_t  PL_rpeepp

-

PMOP

Described in perlguts. That's it, that's the whole entry, go read perlguts bestie ๐Ÿ“–

-

rv2cv_op_cv

This one examines an op, which is expected to identify a subroutine at runtime, and it tries to determine at compile time which subroutine it identifies. Normally this gets used during Perl compilation to figure out whether a prototype can be applied to a function call. cvop is the op being considered โ€” normally an rv2cv op. If it could be determined statically, you get a pointer to the identified subroutine back; if it wasn't possible to determine statically, you get a null pointer. sad but valid. ๐Ÿ˜ญ

Right now, the subroutine can be identified statically if the RV that the rv2cv is operating on is provided by a suitable gv or const op. A gv op is suitable if the GV's CV slot is populated. A const op is suitable if the constant value must be an RV pointing to a CV. Heads up tho โ€” the details of this process may change in future versions of Perl, so don't hardcode your whole personality around it. Also: if the rv2cv op has the OPpENTERSUB_AMPER flag set, then no attempt is made to identify the subroutine statically at all. That flag exists to suppress compile-time magic on a subroutine call, forcing it to use default runtime behaviour. periodt.

Now, if flags has the bit RV2CVOPCV_MARK_EARLY set, then the handling of a GV reference gets modified โœจ โ€” if a GV was examined and its CV slot was found to be empty, then the gv op has the OPpEARLY_CV flag set. And if the op isn't optimised away, and the CV slot is later populated with a subroutine that has a prototype, that flag eventually triggers the warning called too early to check prototype. you've been warned ๐Ÿ’€

If flags has the bit RV2CVOPCV_RETURN_NAME_GV set, then instead of returning a pointer to the subroutine, it returns a pointer to the GV giving the most appropriate name for the subroutine in this context. Normally that's just the CvGV of the subroutine โ€” but for an anonymous (CvANON) subroutine that's referenced through a GV, it'll be the referencing GV. The resulting GV* gets cast to CV* to be returned. And as usual, a null pointer comes back if there's no statically-determinable subroutine. ๐Ÿ™ˆ

CV *       rv2cv_op_cv(      OP *cvop, U32 flags)
CV *  Perl_rv2cv_op_cv(pTHX_ OP *cvop, U32 flags)

-

UNOP

XOP

Described in perlguts. Both of them. Genuinely just that. go read it ๐Ÿ‘‘


โœจ Pack and Unpack โœจ

packlist

The engine implementing the pack() Perl function. iconic honestly.

void       packlist(      SV *cat, const char *pat,
                          const char *patend, SV **beglist,
                          SV **endlist)
void  Perl_packlist(pTHX_ SV *cat, const char *pat,
                          const char *patend, SV **beglist,
                          SV **endlist)

-

unpackstring

The engine implementing the unpack() Perl function. ๐Ÿ’–

Using the template pat..patend, this function unpacks the string s..strend into a number of mortal SVs, which it pushes onto the perl argument (@_) stack โ€” so yes, you will need to issue a PUTBACK before and a SPAGAIN after the call. It returns the number of pushed elements. that's the receipt bestie ๐Ÿงพ

The strend and patend pointers should point to the byte following the last character of each string. Careful with that one, it's giving off-by-one traps.

Even though this function returns its values on the perl argument stack, it doesn't take any parameters from that stack โ€” and thus in particular there's no need to do a PUSHMARK before calling it, unlike call_pv for example. quirky but slay.

SSize_t       unpackstring(      const char *pat,
                                 const char *patend,
                                 const char *s,
                                 const char *strend, U32 flags)
SSize_t  Perl_unpackstring(pTHX_ const char *pat,
                                 const char *patend,
                                 const char *s,
                                 const char *strend, U32 flags)

๐Ÿซง Pad Data Structures ๐Ÿซง

CvPADLIST

NOTE: CvPADLIST is experimental and may change or be removed without notice. โš ๏ธ Do not get attached.

CV's can have CvPADLIST(cv) set to point to a PADLIST. This is the CV's scratchpad, which stores lexical variables and opcode temporary and per-thread values. it's the CV's room, basically, and everything lives in there.

For these purposes formats are a kind-of CV; eval""s are too โ€” except they're not callable at will and are always thrown away after the eval"" is done executing. Require'd files are simply evals without any outer lexical scope. casual.

XSUBs do not have a CvPADLIST. dXSTARG fetches values from PL_curpad, but that is really the caller's pad (a slot of which is allocated by every entersub). So: do not get or set CvPADLIST if a CV is an XSUB (as determined by CvISXSUB()) โ€” the CvPADLIST slot is reused for a different internal purpose in XSUBs. fr fr, hands off ๐Ÿ™…

The PADLIST has a C array where pads are stored.

The 0th entry of the PADLIST is a PADNAMELIST which represents the "names" or rather the "static type information" for lexicals. The individual elements of a PADNAMELIST are PADNAMEs. Future refactorings might stop the PADNAMELIST from being stored in the PADLIST's array, so don't rely on it, bestie. See PadlistNAMES.

The CvDEPTH'th entry of a PADLIST is a PAD (an AV) which is the stack frame at that depth of recursion into the CV. The 0th slot of a frame AV is an AV which is @_. And the other entries? Storage for variables and op targets. ๐ŸŽ€

Iterating over the PADNAMELIST iterates over all possible pad items. Pad slots for targets (SVs_PADTMP) and GVs end up having &PL_padname_undef "names", while slots for constants have &PL_padname_const "names" (see pad_alloc). The fact that &PL_padname_undef and &PL_padname_const are used is an implementation detail subject to change ๐Ÿ˜ญ so to test for them, use !PadnamePV(name) and PadnamePV(name) && !PadnameLEN(name), respectively. iykyk.

Only my/our variable slots get valid names. The rest are op targets/GVs/constants which are statically allocated or resolved at compile time. These don't have names by which they can be looked up from Perl code at run time through eval"" the way my/our variables can be. Since they can't be looked up by "name" but only by their index allocated at compile time (which is usually in PL_op->op_targ), wasting a name SV for them doesn't make sense. zero notes, correct behaviour, moving on.

The pad names in the PADNAMELIST have their PV holding the name of the variable. The COP_SEQ_RANGE_LOW and _HIGH fields form a range (low+1..high inclusive) of cop_seq numbers for which the name is valid. During compilation, these fields may hold the special value PERL_PADSEQ_INTRO to indicate various stages:

COP_SEQ_RANGE_LOW        _HIGH
-----------------        -----
PERL_PADSEQ_INTRO            0   variable not yet introduced:
                                 { my ($x
valid-seq#   PERL_PADSEQ_INTRO   variable in scope:
                                 { my ($x);
valid-seq#          valid-seq#   compilation of scope complete:
                                 { my ($x); .... }

So like, in words: ๐Ÿ’…

  • PERL_PADSEQ_INTRO / 0 โ€” the variable is not yet introduced: { my ($x
  • a valid seq# / PERL_PADSEQ_INTRO โ€” the variable is in scope: { my ($x);
  • a valid seq# / a valid seq# โ€” compilation of the scope is complete: { my ($x); .... }

When a lexical var hasn't yet been introduced, it already exists from the perspective of duplicate declarations, but not for variable lookups, e.g.

    my ($x, $x); # '"my" variable $x masks earlier declaration'
    my $x = $x;  # equal to my $x = $::x;

For typed lexicals, PadnameTYPE points at the type stash. For our lexicals, PadnameOURSTASH points at the stash of the associated global (so that duplicate our declarations in the same package can be detected โœจ). PadnameGEN is sometimes used to store the generation number during compilation.

If PadnameOUTER is set on the pad name, then that slot in the frame AV is a REFCNT'ed reference to a lexical from "outside". Such entries are sometimes referred to as 'fake'. ๐Ÿ’€ In this case, the name does not use 'low' and 'high' to store a cop_seq range, since it's in scope throughout. Instead, 'high' stores some flags containing info about the real lexical โ€” is it declared in an anon, and is it capable of being instantiated multiple times? โ€” and for fake ANONs, 'low' contains the index within the parent's pad where the lexical's value is stored, to make cloning quicker. slay, efficiency queen.

If the 'name' is &, the corresponding entry in the PAD is a CV representing a possible closure. ๐Ÿ‘‘

Note that formats are treated as anon subs, and are cloned each time write is called (if necessary).

The flag SVs_PADSTALE is cleared on lexicals each time the my() is executed, and set on scope exit. This allows the Variable $x is not available warning to be generated in evals, such as

    { my $x = 1; sub f { eval '$x'} } f();

and that's the vibe: the lexical goes stale, the warning fires, everything works exactly as advertised. ๐ŸŒธ

For state vars, SVs_PADSTALE is doing double duty โ€” it's overloaded to mean "not yet initialised" โ€” but bestie, that internal state actually lives in a separate pad entry, not where you'd expect. ๐Ÿ™ˆ

PADLIST *  CvPADLIST(CV *cv)

pad_new โœจ

Makes a brand-new padlist and updates the global variables for the currently-compiling padlist so they point at the new one. You can OR these flags together:

padnew_CLONE        this pad is for a cloned CV
padnew_SAVE         save old globals on the save stack
padnew_SAVESUB      also save extra stuff for start of sub
PADLIST *       pad_new(      int flags)
PADLIST *  Perl_pad_new(pTHX_ int flags)

PadARRAY ๐ŸŽ€

NOTE: PadARRAY is experimental and may change or get yeeted without notice.

It's the C array of pad entries, periodt.

SV **  PadARRAY(PAD * pad)

PadlistARRAY ๐Ÿฆ‹

NOTE: PadlistARRAY is experimental and may change or get yeeted without notice.

The C array of a padlist, holding the pads. Only subscript it with numbers >= 1, because the 0th entry is not guaranteed to stay usable. ๐Ÿ’€

PAD **  PadlistARRAY(PADLIST * padlist)

PadlistMAX ๐ŸŒธ

NOTE: PadlistMAX is experimental and may change or get yeeted without notice.

The index of the last allocated space in the padlist. But heads up bestie โ€” the last pad might actually be sitting in an earlier slot, and any entries after it will be NULL in that case.

SSize_t  PadlistMAX(PADLIST * padlist)

PadlistNAMES โœจ

NOTE: PadlistNAMES is experimental and may change or get yeeted without notice.

The names that go with the pad entries.

PADNAMELIST *  PadlistNAMES(PADLIST * padlist)

PadlistNAMESARRAY ๐Ÿ’–

NOTE: PadlistNAMESARRAY is experimental and may change or get yeeted without notice.

The C array of pad names.

PADNAME **  PadlistNAMESARRAY(PADLIST * padlist)

PadlistNAMESMAX ๐ŸŽ€

NOTE: PadlistNAMESMAX is experimental and may change or get yeeted without notice.

The index of the last pad name.

SSize_t  PadlistNAMESMAX(PADLIST * padlist)

PadlistREFCNT ๐Ÿซถ

NOTE: PadlistREFCNT is experimental and may change or get yeeted without notice.

The reference count of the padlist. Currently this is always 1. Slay.

U32  PadlistREFCNT(PADLIST * padlist)

PadMAX โญ

NOTE: PadMAX is experimental and may change or get yeeted without notice.

The index of the last pad entry.

SSize_t  PadMAX(PAD * pad)

PadnameLEN ๐ŸŒˆ

NOTE: PadnameLEN is experimental and may change or get yeeted without notice.

The length of the name.

STRLEN  PadnameLEN(PADNAME * pn)

PadnamelistARRAY ๐Ÿ’œ

NOTE: PadnamelistARRAY is experimental and may change or get yeeted without notice.

The C array of pad names.

PADNAME **  PadnamelistARRAY(PADNAMELIST * pnl)

PadnamelistMAX ๐Ÿงš

NOTE: PadnamelistMAX is experimental and may change or get yeeted without notice.

The index of the last pad name.

SSize_t  PadnamelistMAX(PADNAMELIST * pnl)

PadnamelistREFCNT ๐Ÿ“

NOTE: PadnamelistREFCNT is experimental and may change or get yeeted without notice.

The reference count of the pad name list.

SSize_t  PadnamelistREFCNT(PADNAMELIST * pnl)

PadnamelistREFCNT_dec ๐Ÿ’…

NOTE: PadnamelistREFCNT_dec is experimental and may change or get yeeted without notice.

Lowers the reference count of the pad name list. Bye bestie ๐Ÿ‘‹

void  PadnamelistREFCNT_dec(PADNAMELIST * pnl)

PadnamePV โœจ

NOTE: PadnamePV is experimental and may change or get yeeted without notice.

The name stored in the pad name struct. It hands back NULL for a target slot.

char *  PadnamePV(PADNAME * pn)

PadnameREFCNT ๐ŸŽ€

NOTE: PadnameREFCNT is experimental and may change or get yeeted without notice.

The reference count of the pad name.

SSize_t  PadnameREFCNT(PADNAME * pn)

PadnameREFCNT_dec ๐Ÿฆ‹

NOTE: PadnameREFCNT_dec is experimental and may change or get yeeted without notice.

Lowers the reference count of the pad name.

void  PadnameREFCNT_dec(PADNAME * pn)

PadnameREFCNT_inc ๐ŸŒธ

NOTE: PadnameREFCNT_inc is experimental and may change or get yeeted without notice.

Increases the reference count of the pad name, and returns the pad name itself. Iconic behavior tbh.

PADNAME *  PadnameREFCNT_inc(PADNAME * pn)

PadnameSV ๐Ÿซถ

NOTE: PadnameSV is experimental and may change or get yeeted without notice.

Returns the pad name as a mortal SV.

SV *  PadnameSV(PADNAME * pn)

PadnameUTF8 โญ

NOTE: PadnameUTF8 is experimental and may change or get yeeted without notice.

Whether PadnamePV is in UTF-8. Currently, this is always true.

bool  PadnameUTF8(PADNAME * pn)

PL_comppad ๐Ÿ’–

NOTE: PL_comppad is experimental and may change or get yeeted without notice.

During compilation, this points to the array holding the values part of the pad for the currently-compiling code. (At runtime a CV can have many such value arrays; at compile time just one gets constructed.) At runtime, it points to the array holding the currently-relevant values for the pad of the currently-executing code.

PL_comppad_name ๐ŸŒˆ

NOTE: PL_comppad_name is experimental and may change or get yeeted without notice.

During compilation, this points to the array holding the names part of the pad for the currently-compiling code.

PL_curpad ๐Ÿ’œ

NOTE: PL_curpad is experimental and may change or get yeeted without notice.

Points directly at the body of the PL_comppad array. (I.e., this is PadARRAY(PL_comppad).)

SVs_PADMY / SVs_PADTMP ๐Ÿ’€

DEPRECATED! It's planned to remove SVs_PADMY from a future release of Perl. Do not use it for new code; remove it from existing code. Fr fr, let it go.

Described in perlguts.


๐Ÿ“ Password and Group access ๐Ÿ“

GRPASSWD ๐Ÿ”

This symbol, if defined, tells your C program that struct group over in grp.h contains gr_passwd.

HAS_ENDGRENT ๐Ÿ‘‘

This symbol, if defined, means the getgrent routine is available for finalizing sequential access of the group database.

HAS_ENDGRENT_R โœจ

This symbol, if defined, means the endgrent_r routine is available to endgrent re-entrantly.

HAS_ENDPWENT ๐ŸŽ€

This symbol, if defined, means the endpwent routine is available for finalizing sequential access of the passwd database.

HAS_ENDPWENT_R ๐Ÿฆ‹

This symbol, if defined, means the endpwent_r routine is available to endpwent re-entrantly.

HAS_GETGRENT ๐ŸŒธ

This symbol, if defined, means the getgrent routine is available for sequential access of the group database.

HAS_GETGRENT_R ๐Ÿซถ

This symbol, if defined, means the getgrent_r routine is available to getgrent re-entrantly.

HAS_GETPWENT โญ

This symbol, if defined, means the getpwent routine is available for sequential access of the passwd database. And if it's not available, the older getpw() function might be hanging around instead.

HAS_GETPWENT_R ๐ŸŒˆ

This symbol, if defined, means the getpwent_r routine is available to getpwent re-entrantly.

HAS_SETGRENT ๐Ÿ’œ

This symbol, if defined, means the setgrent routine is available for initializing sequential access of the group database.

HAS_SETGRENT_R ๐Ÿงš

This symbol, if defined, means the setgrent_r routine is available to setgrent re-entrantly.

HAS_SETPWENT ๐Ÿ“

This symbol, if defined, means the setpwent routine is available for initializing sequential access of the passwd database.

HAS_SETPWENT_R ๐Ÿ’…

This symbol, if defined, means the setpwent_r routine is available to setpwent re-entrantly.

PWAGE ๐Ÿ”

This symbol, if defined, tells your C program that struct passwd contains pw_age.

PWCHANGE โœจ

This symbol, if defined, tells your C program that struct passwd contains pw_change.

PWCLASS ๐ŸŽ€

This symbol, if defined, tells your C program that struct passwd contains pw_class.

PWCOMMENT ๐Ÿฆ‹

This symbol, if defined, tells your C program that struct passwd contains pw_comment.

PWEXPIRE ๐ŸŒธ

This symbol, if defined, tells your C program that struct passwd contains pw_expire.

PWGECOS ๐Ÿซถ

This symbol, if defined, tells your C program that struct passwd contains pw_gecos.

PWPASSWD โญ

This symbol, if defined, tells your C program that struct passwd contains pw_passwd.

PWQUOTA ๐ŸŒˆ

This symbol, if defined, tells your C program that struct passwd contains pw_quota.


๐Ÿ’œ Paths to system commands ๐Ÿ’œ

CSH ๐Ÿš

This symbol, if defined, contains the full pathname of csh.

LOC_SED โœจ

This symbol holds the complete pathname to the sed program.

SH_PATH ๐ŸŽ€

This symbol holds the full pathname to the shell used on this system to execute Bourne shell scripts. Usually this'll be /bin/sh, though it's lowkey possible that some systems have /bin/ksh, /bin/pdksh, /bin/ash, /bin/bash, or even something like D:/bin/sh.exe. The range?? Wild. ๐Ÿ˜ญ


๐Ÿฆ‹ Prototype information ๐Ÿฆ‹

CRYPT_R_PROTO ๐Ÿ”

This symbol encodes the prototype of crypt_r. It's zero if d_crypt_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_crypt_r is defined.

CTERMID_R_PROTO โœจ

This symbol encodes the prototype of ctermid_r. It's zero if d_ctermid_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctermid_r is defined.

DRAND48_R_PROTO ๐ŸŽ€

This symbol encodes the prototype of drand48_r. It's zero if d_drand48_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_drand48_r is defined.

ENDGRENT_R_PROTO ๐ŸŒธ

This symbol encodes the prototype of endgrent_r. It's zero if d_endgrent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_endgrent_r is defined.

ENDHOSTENT_R_PROTO ๐Ÿซถ

This symbol encodes the prototype of endhostent_r. It's zero if d_endhostent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_endhostent_r is defined.

ENDNETENT_R_PROTO ๐Ÿงต

Okay so this one encodes the prototype of endnetent_r. It's zero if d_endnetent_r is undef, and if d_endnetent_r is defined it's one of the REENTRANT_PROTO_T_ABC macros from reentr.h. That's it, that's the whole vibe check. ๐Ÿ’…

ENDPROTOENT_R_PROTO ๐Ÿงต

Same energy bestie: this symbol encodes the prototype of endprotoent_r. Zero when d_endprotoent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h when d_endprotoent_r is defined. Iconic consistency. โœจ

ENDPWENT_R_PROTO ๐Ÿงต

Encodes the prototype of endpwent_r. It's zero if d_endpwent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_endpwent_r is defined. No notes. ๐Ÿ’–

ENDSERVENT_R_PROTO ๐Ÿงต

This symbol encodes the prototype of endservent_r. Zero if d_endservent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_endservent_r is defined. The pattern is pattern-ing. ๐Ÿฆ‹


GDBM_NDBM_H_USES_PROTOTYPES ๐ŸŽ€

If defined, this symbol indicates that <gdbm-ndbm.h> uses real ANSI C prototypes instead of K&R style function declarations without any parameter information. And heads up: while ANSI C prototypes are supported in C++, K&R style function declarations will yield errors. So likeโ€ฆ ๐Ÿ’€ don't.

GDBMNDBM_H_USES_PROTOTYPES ๐ŸŽ€

Same thing, different spelling (and yes, the missing underscore is not a typo, it's literally spelled that way): if defined, this symbol indicates that gdbm/ndbm.h uses real ANSI C prototypes instead of K&R style function declarations without any parameter information. While ANSI C prototypes are supported in C++, K&R style function declarations will yield errors. ๐Ÿซถ


GETGRENT_R_PROTO ๐Ÿงต

Encodes the prototype of getgrent_r. Zero if d_getgrent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrent_r is defined. Slay. โœจ

GETGRGID_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getgrgid_r. It's zero if d_getgrgid_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrgid_r is defined. ๐ŸŒธ

GETGRNAM_R_PROTO ๐Ÿงต

Encodes the prototype of getgrnam_r. Zero if d_getgrnam_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getgrnam_r is defined. Periodt. ๐Ÿ’…

GETHOSTBYADDR_R_PROTO ๐Ÿงต

This symbol encodes the prototype of gethostbyaddr_r. Zero if d_gethostbyaddr_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyaddr_r is defined. ๐Ÿ‘‘

GETHOSTBYNAME_R_PROTO ๐Ÿงต

Encodes the prototype of gethostbyname_r. It is zero if d_gethostbyname_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostbyname_r is defined. ๐ŸŒˆ

GETHOSTENT_R_PROTO ๐Ÿงต

This symbol encodes the prototype of gethostent_r. Zero if d_gethostent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_gethostent_r is defined. ๐Ÿฆ‹

GETLOGIN_R_PROTO ๐Ÿงต

Encodes the prototype of getlogin_r. Zero if d_getlogin_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getlogin_r is defined. Bestie said login, reentrantly. โœจ

GETNETBYADDR_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getnetbyaddr_r. It's zero if d_getnetbyaddr_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyaddr_r is defined. ๐Ÿ”ฅ

GETNETBYNAME_R_PROTO ๐Ÿงต

Encodes the prototype of getnetbyname_r. Zero if d_getnetbyname_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetbyname_r is defined. ๐Ÿงš

GETNETENT_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getnetent_r. Zero if d_getnetent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getnetent_r is defined. ๐Ÿ’œ

GETPROTOBYNAME_R_PROTO ๐Ÿงต

Encodes the prototype of getprotobyname_r. It is zero if d_getprotobyname_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobyname_r is defined. ๐Ÿ“

GETPROTOBYNUMBER_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getprotobynumber_r. Zero if d_getprotobynumber_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotobynumber_r is defined. โœจ

GETPROTOENT_R_PROTO ๐Ÿงต

Encodes the prototype of getprotoent_r. Zero if d_getprotoent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getprotoent_r is defined. ๐Ÿ’…

GETPWENT_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getpwent_r. It's zero if d_getpwent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwent_r is defined. ๐ŸŒธ

GETPWNAM_R_PROTO ๐Ÿงต

Encodes the prototype of getpwnam_r. Zero if d_getpwnam_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwnam_r is defined. ๐Ÿซถ

GETPWUID_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getpwuid_r. Zero if d_getpwuid_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getpwuid_r is defined. ๐Ÿ‘‘

GETSERVBYNAME_R_PROTO ๐Ÿงต

Encodes the prototype of getservbyname_r. It is zero if d_getservbyname_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyname_r is defined. ๐ŸŒˆ

GETSERVBYPORT_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getservbyport_r. Zero if d_getservbyport_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservbyport_r is defined. ๐Ÿฆ‹

GETSERVENT_R_PROTO ๐Ÿงต

Encodes the prototype of getservent_r. Zero if d_getservent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getservent_r is defined. โœจ

GETSPNAM_R_PROTO ๐Ÿงต

This symbol encodes the prototype of getspnam_r. Zero if d_getspnam_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_getspnam_r is defined. Shadow passwords but make it reentrant. ๐Ÿ™ˆ


HAS_DBMINIT_PROTO ๐ŸŽ€

If defined, this symbol says the system hands you a prototype for the dbminit() function. If it's not defined, supplying one is on the program. A good guess is:

extern int dbminit(char *);

HAS_DRAND48_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the drand48() function. Otherwise, it's up to the program to supply one. A good guess is:

extern double drand48(void);

HAS_FLOCK_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the flock() function. Otherwise, the program has to supply it. A good guess is:

extern int flock(int, int);

HAS_GETHOST_PROTOS ๐ŸŒ

If defined, this symbol means netdb.h includes prototypes for gethostent(), gethostbyname(), and gethostbyaddr(). Otherwise it's up to the program to guess them. For probing for the various Netdb_xxx_t types, see netdbtype.U (part of metaconfig). ๐Ÿ”

HAS_GETNET_PROTOS ๐ŸŒ

If defined, netdb.h includes prototypes for getnetent(), getnetbyname(), and getnetbyaddr(). Otherwise the program is out here guessing. See netdbtype.U (part of metaconfig) for probing for various Netdb_xxx_t types. ๐Ÿ”

HAS_GETPROTO_PROTOS ๐ŸŒ

If defined, netdb.h includes prototypes for getprotoent(), getprotobyname(), and getprotobyaddr(). Otherwise, up to the program to guess them. See netdbtype.U (part of metaconfig) for probing for various Netdb_xxx_t types. ๐Ÿซถ

HAS_GETSERV_PROTOS ๐ŸŒ

If defined, netdb.h includes prototypes for getservent(), getservbyname(), and getservbyaddr(). Otherwise, it's up to the program to guess them. See netdbtype.U (part of metaconfig) for probing for various Netdb_xxx_t types. โœจ

HAS_MODFL_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the modfl() function. Otherwise, it's up to the program to supply one. No sample guess given here, bestie โ€” the manpage just leaves you to it. ๐Ÿ’…

HAS_SBRK_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the sbrk() function. Otherwise the program has to supply one. Good guesses are:

extern void* sbrk(int);
extern void* sbrk(size_t);

HAS_SETRESGID_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the setresgid() function. Otherwise, it's up to the program to supply one. Good guesses are:

extern int setresgid(uid_t ruid, uid_t euid, uid_t suid);

HAS_SETRESUID_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the setresuid() function. Otherwise, the program supplies one. Good guesses are:

extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);

HAS_SHMAT_PROTOTYPE ๐ŸŽ€

If defined, this symbol indicates that sys/shm.h includes a prototype for shmat(). Otherwise, it's up to the program to guess one. Shmat_t shmat(int, Shmat_t, int) is a good guess, but not always right โ€” so it should only be emitted by the program when HAS_SHMAT_PROTOTYPE is not defined, to avoid conflicting defs. Lowkey the most important sentence here. ๐Ÿ˜ญ

HAS_SOCKATMARK_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the sockatmark() function. Otherwise, the program supplies one. A good guess is:

extern int sockatmark(int);

HAS_SYSCALL_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the syscall() function. Otherwise, it's on the program to supply one. Good guesses are:

extern int syscall(int,  ...);
extern int syscall(long, ...);

(yes, there really is a double space in syscall(int, ...) โ€” keeping it exactly as-is ๐Ÿ’€)

HAS_TELLDIR_PROTO ๐ŸŽ€

If defined, the system provides a prototype for the telldir() function. Otherwise, up to the program. A good guess is:

extern long telldir(DIR*);

NDBM_H_USES_PROTOTYPES ๐ŸŽ€

If defined, this symbol indicates that ndbm.h uses real ANSI C prototypes instead of K&R style function declarations without any parameter information. And again for the people in the back: while ANSI C prototypes are supported in C++, K&R style function declarations will yield errors. ๐Ÿซ 

RANDOM_R_PROTO ๐Ÿงต

This symbol encodes the prototype of random_r. It is zero if d_random_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_random_r is defined. RNG but make it reentrant, we love to see it. ๐ŸŽฒโœจ

๐Ÿฆ‹ READDIR_R_PROTO ๐Ÿฆ‹

So this symbol encodes the prototype of readdir_r, bestie. It's zero if d_readdir_r is undef โ€” and if d_readdir_r is defined, it's one of the REENTRANT_PROTO_T_ABC macros from reentr.h. that's it, that's the whole vibe ๐Ÿ’…

๐ŸŒธ SETGRENT_R_PROTO ๐ŸŒธ

This one encodes the prototype of setgrent_r. Zero if d_setgrent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_setgrent_r is defined. iconic โœจ

๐ŸŽ€ SETHOSTENT_R_PROTO ๐ŸŽ€

Encodes the prototype of sethostent_r. Zero when d_sethostent_r is undef; when d_sethostent_r is defined it's one of the REENTRANT_PROTO_T_ABC macros of reentr.h. slay ๐Ÿ’–

โญ SETLOCALE_R_PROTO โญ

This symbol encodes the prototype of setlocale_r. It's zero if d_setlocale_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_setlocale_r is defined. lowkey obsessed with how consistent these are ๐Ÿซถ

๐Ÿ’œ SETNETENT_R_PROTO ๐Ÿ’œ

Encodes the prototype of setnetent_r. Zero if d_setnetent_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_setnetent_r is defined. no cap ๐Ÿคž

๐ŸŒˆ SETPROTOENT_R_PROTO ๐ŸŒˆ

This symbol encodes the prototype of setprotoent_r. It's zero when d_setprotoent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h when d_setprotoent_r is defined. periodt ๐ŸŒŸ

๐Ÿ“ SETPWENT_R_PROTO ๐Ÿ“

Encodes the prototype of setpwent_r. Zero if d_setpwent_r is undef; otherwise it's one of the REENTRANT_PROTO_T_ABC macros of reentr.h (that's the d_setpwent_r is defined case, bestie). ๐Ÿ’…

๐Ÿงš SETSERVENT_R_PROTO ๐Ÿงš

This one encodes the prototype of setservent_r. It is zero if d_setservent_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_setservent_r is defined. ๐ŸŽ€

๐Ÿ”ฅ SRANDOM_R_PROTO ๐Ÿ”ฅ

Encodes the prototype of srandom_r. Zero if d_srandom_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_srandom_r is defined. so random. so iconic. ๐ŸŽฒ

๐Ÿ’– SRAND48_R_PROTO ๐Ÿ’–

This symbol encodes the prototype of srand48_r. It's zero if d_srand48_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_srand48_r is defined. ๐Ÿ’ซ

๐ŸŒธ STRERROR_R_PROTO ๐ŸŒธ

Encodes the prototype of strerror_r. Zero when d_strerror_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h when d_strerror_r is defined. ๐Ÿซถ

โญ TMPNAM_R_PROTO โญ

This symbol encodes the prototype of tmpnam_r. It is zero if d_tmpnam_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_tmpnam_r is defined. ๐Ÿ’…

๐Ÿฆ‹ TTYNAME_R_PROTO ๐Ÿฆ‹

Encodes the prototype of ttyname_r. Zero if d_ttyname_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_ttyname_r is defined. that's the last of these lil guys for now ๐ŸŽ€


๐Ÿ‘‘ Reference-counted stack manipulation ๐Ÿ‘‘

Okay so these are the functions for pushing and pulling items on the stack โ€” but specifically when the stack is reference counted, bestie. They're meant to be replacements for the old PUSHs, POPi, EXTEND etc pp macros inside your pp functions. glow-up era fr fr โœจ

๐Ÿ’œ rpp_context ๐Ÿ’œ

NOTE: rpp_context is experimental and may change or be removed without notice. don't get attached ๐Ÿ˜ญ

This one imposes void, scalar or list context on the stack. Here's the sequence, in order:

  1. First, pop extra items off the stack.
  2. Then, depending on what gimme is:
  • G_LIST โ€” return as-is. that's it, nothing to do ๐Ÿ’…
  • G_VOID โ€” pop everything back to mark.
  • G_SCALAR โ€” move the top stack item (or &PL_sv_undef if there isn't one) to mark+1, and free everything above it.
 void       rpp_context(      SV **mark, U8 gimme, SSize_t extra)
 void  Perl_rpp_context(pTHX_ SV **mark, U8 gimme, SSize_t extra)

๐ŸŽ€ rpp_extend ๐ŸŽ€

NOTE: rpp_extend is experimental and may change or be removed without notice. ๐Ÿ™ˆ

Ensures there's actually space on the stack to push n items, extending it if it needs to. manifesting room bestie ๐ŸŒฑ

 void       rpp_extend(      SSize_t n)
 void  Perl_rpp_extend(pTHX_ SSize_t n)

๐ŸŒˆ rpp_invoke_xs ๐ŸŒˆ

NOTE: rpp_invoke_xs is experimental and may change or be removed without notice. ๐Ÿ’€

Calls the XS function associated with cv. It wraps the call if necessary to handle XS functions that aren't aware of reference-counted stacks. generous queen, covering for the ones that didn't get the memo ๐Ÿซถ

 void       rpp_invoke_xs(      CV *cv)
 void  Perl_rpp_invoke_xs(pTHX_ CV *cv)

๐Ÿ“ rpp_is_lone ๐Ÿ“

NOTE: rpp_is_lone is experimental and may change or be removed without notice. ๐Ÿ˜ญ

Tells you whether the stacked SV sv (and yes, it's assumed not yet popped off the stack) is only kept alive because of a single reference from the argument stack and/or the temps stack.

What's this for, you ask? well bestie, it can be used for example to decide whether the copying of return values in rvalue context can be skipped, or whether it shouldn't be assigned to in lvalue context. iykyk ๐Ÿ’…

 bool       rpp_is_lone(      SV *sv)
 bool  Perl_rpp_is_lone(pTHX_ SV *sv)

๐Ÿ’– rpp_pop_1_norc ๐Ÿ’–

NOTE: rpp_pop_1_norc is experimental and may change or be removed without notice. โœจ

Pops and returns the top item off the argument stack, then updates PL_stack_sp. It's like rpp_popfree_1(), except โ€” plot twist โ€” it actually returns a value, and it doesn't decrement the SV's reference count. And on non-PERL_RC_STACK builds it actually increments the SV's reference count. the way it just flips the rule on you ๐Ÿ˜ญ

When is this the move? When the popped value gets immediately embedded somewhere, e.g. via av_store() โ€” this lets you skip decrementing and then immediately incrementing the reference count again (and risk prematurely freeing the SV if it had an RC of 1). On non-RC builds the reference count bookkeeping still works too, which is exactly why you should use this instead of a simple *PL_stack_sp--. use the function, bestie, it's there for a reason ๐Ÿ’…

 SV *       rpp_pop_1_norc()
 SV *  Perl_rpp_pop_1_norc(pTHX)

๐ŸŒธ rpp_popfree_to ๐ŸŒธ

NOTE: rpp_popfree_to is experimental and may change or be removed without notice. ๐Ÿ™ˆ

Pops and frees all items on the argument stack above sp. When it returns, PL_stack_sp will be equal to sp. clean sweep โœจ

 void       rpp_popfree_to(      SV **sp)
 void  Perl_rpp_popfree_to(pTHX_ SV **sp)

โญ rpp_popfree_to_NN โญ

NOTE: rpp_popfree_to_NN is experimental and may change or be removed without notice. ๐Ÿ’€

A variant of rpp_popfree_to() that assumes every pointer being popped off the stack is non-NULL. bold of it, honestly ๐Ÿ˜Œ

 void       rpp_popfree_to_NN(      SV **sp)
 void  Perl_rpp_popfree_to_NN(pTHX_ SV **sp)

๐ŸŽ€ rpp_popfree_1 ๐ŸŽ€

NOTE: rpp_popfree_1 is experimental and may change or be removed without notice. ๐Ÿ”ฅ

Pops and frees the top item on the argument stack and updates PL_stack_sp. bye bestie ๐Ÿ‘‹

 void       rpp_popfree_1()
 void  Perl_rpp_popfree_1(pTHX)

๐Ÿ’œ rpp_popfree_1_NN ๐Ÿ’œ

NOTE: rpp_popfree_1_NN is experimental and may change or be removed without notice. ๐ŸŒธ

A variant of rpp_popfree_1() that assumes the pointer being popped off the stack is non-NULL. trust fall ๐Ÿซถ

 void       rpp_popfree_1_NN()
 void  Perl_rpp_popfree_1_NN(pTHX)

๐ŸŒˆ rpp_popfree_2 ๐ŸŒˆ

NOTE: rpp_popfree_2 is experimental and may change or be removed without notice. ๐Ÿ˜ญ

Pops and frees the top two items on the argument stack and updates PL_stack_sp. two at once, she's efficient ๐Ÿ’…

 void       rpp_popfree_2()
 void  Perl_rpp_popfree_2(pTHX)

๐Ÿ“ rpp_popfree_2_NN ๐Ÿ“

NOTE: rpp_popfree_2_NN is experimental and may change or be removed without notice. ๐Ÿ™ˆ

A variant of rpp_popfree_2() that assumes the two pointers being popped off the stack are non-NULL. double the trust, double the fall โœจ

 void       rpp_popfree_2_NN()
 void  Perl_rpp_popfree_2_NN(pTHX)

๐Ÿ”ฅ rpp_push_1 / rpp_push_IMM / rpp_push_2 / rpp_xpush_1 / rpp_xpush_IMM / rpp_xpush_2 ๐Ÿ”ฅ

NOTE: all these forms are experimental and may change or be removed without notice. ๐Ÿ’€

Push one or two SVs onto the stack, incrementing their reference counts and updating PL_stack_sp. With the x variants, it extends the stack first. And the IMM variants assume the single argument is an immortal such as &PL_sv_undef โ€” so for efficiency they'll skip incrementing its reference count. immortals don't need that kind of upkeep, periodt ๐Ÿ‘‘

 void       rpp_push_1   (      SV *sv)
 void  Perl_rpp_push_1   (pTHX_ SV *sv)
 void       rpp_push_IMM (      SV *sv)
 void  Perl_rpp_push_IMM (pTHX_ SV *sv)
 void       rpp_push_2   (      SV *sv1, SV *sv2)
 void  Perl_rpp_push_2   (pTHX_ SV *sv1, SV *sv2)
 void       rpp_xpush_1  (      SV *sv)
 void  Perl_rpp_xpush_1  (pTHX_ SV *sv)
 void       rpp_xpush_IMM(      SV *sv)
 void  Perl_rpp_xpush_IMM(pTHX_ SV *sv)
 void       rpp_xpush_2  (      SV *sv1, SV *sv2)
 void  Perl_rpp_xpush_2  (pTHX_ SV *sv1, SV *sv2)

๐ŸŒธ rpp_push_1_norc ๐ŸŒธ

NOTE: rpp_push_1_norc is experimental and may change or be removed without notice. ๐Ÿ˜ญ

Pushes sv onto the stack without incrementing its reference count, and updates PL_stack_sp. And on non-PERL_RC_STACK builds, it mortalises too. ๐Ÿ’ซ

Peak use case: an SV that's just been created and already has a reference count of 1, but hasn't been anchored anywhere yet. fresh out the oven, not committed yet ๐Ÿฅ

 void       rpp_push_1_norc(      SV *sv)
 void  Perl_rpp_push_1_norc(pTHX_ SV *sv)

๐Ÿงš rpp_push_2* ๐Ÿงš

Described under rpp_push_1 โ€” go read that one bestie, it's all there ๐Ÿ’…

โญ rpp_replace_at โญ

NOTE: rpp_replace_at is experimental and may change or be removed without notice. ๐Ÿ™ˆ

Replaces the SV at address sp within the stack with sv, while suitably adjusting reference counts. Equivalent to *sp = sv, except it actually does the proper reference count handling. the responsible version ๐Ÿ˜Œ

 void       rpp_replace_at(      SV **sp, SV *sv)
 void  Perl_rpp_replace_at(pTHX_ SV **sp, SV *sv)

๐Ÿ’œ rpp_replace_at_NN ๐Ÿ’œ

NOTE: rpp_replace_at_NN is experimental and may change or be removed without notice. ๐ŸŽ€

A variant of rpp_replace_at() that assumes the SV pointer on the stack is non-NULL. again with the trust fall ๐Ÿซถ

 void       rpp_replace_at_NN(      SV **sp, SV *sv)
 void  Perl_rpp_replace_at_NN(pTHX_ SV **sp, SV *sv)

๐ŸŒˆ rpp_replace_at_norc ๐ŸŒˆ

NOTE: rpp_replace_at_norc is experimental and may change or be removed without notice. ๐Ÿ’€

Replaces the SV at address sp within the stack with sv, while suitably adjusting the reference count of the old SV. Equivalent to *sp = sv, except with proper reference count handling. ๐Ÿ’…

But here's the twist: sv's reference count doesn't get incremented. And on non-PERL_RC_STACK builds, it gets mortalised too. ๐Ÿ˜ญ

The move here is when an SV has just been created and already has a reference count of 1, but hasn't been anchored anywhere yet. brand new, unclaimed, main character energy โœจ

 void       rpp_replace_at_norc(      SV **sp, SV *sv)
 void  Perl_rpp_replace_at_norc(pTHX_ SV **sp, SV *sv)

rpp_replace_at_norc_NN

โš ๏ธ heads up bestie: rpp_replace_at_norc_NN is experimental and may change or be removed without notice.

It's a variant of rpp_replace_at_norc() that just casually assumes the SV pointer chilling on the stack is non-NULL. That's it. That's the whole personality. ๐ŸŒธ

 void       rpp_replace_at_norc_NN(      SV **sp, SV *sv)
 void  Perl_rpp_replace_at_norc_NN(pTHX_ SV **sp, SV *sv)

rpp_replace_1_1

rpp_replace_1_1_NN

rpp_replace_1_IMM_NN

โš ๏ธ okay so all of these forms are experimental and may change or be removed without notice. not a drill ๐Ÿ’€

These babies swap out the current top stack item for sv, and they do it while suitably adjusting reference counts. Functionally it's the same as rpp_popfree_1(); rpp_push_1(sv), but it's more efficient and it handles the case where both SVs are literally the same one. it's giving "same energy, better execution" โœจ

Now the variants, because of course there are variants:

  • The _NN variant assumes the pointer on the stack to the SV being freed is non-NULL. no null checks, we're speedrunning ๐Ÿƒโ€โ™€๏ธ
  • The IMM_NN variant is like the _NN variant, but on top of that it assumes the single argument is an immortal, like &PL_sv_undef, and โ€” purely for efficiency โ€” it skips incrementing its reference count. living forever, no refcount needed, main character energy ๐Ÿ‘‘
 void       rpp_replace_1_1     (      SV *sv)
 void  Perl_rpp_replace_1_1     (pTHX_ SV *sv)
 void       rpp_replace_1_1_NN  (      SV *sv)
 void  Perl_rpp_replace_1_1_NN  (pTHX_ SV *sv)
 void       rpp_replace_1_IMM_NN(      SV *sv)
 void  Perl_rpp_replace_1_IMM_NN(pTHX_ SV *sv)

rpp_replace_2_1

rpp_replace_2_1_NN

rpp_replace_2_IMM_NN

โš ๏ธ same warning, bestie: all these forms are experimental and may change or be removed without notice.

Replace the current top to stacks item with sv, while suitably adjusting reference counts. (yes we're going 2 โ†’ 1 here, iykyk ๐Ÿซถ) Equivalent to rpp_popfree_2(); rpp_push_1(sv), but it's more efficient, and it handles SVs being the same. obsessed with the efficiency honestly ๐Ÿ˜ญ

  • The _NN variant assumes that the pointers on the stack to the SVs being freed are non-NULL.
  • The IMM_NN variant is like the _NN variant, but in addition, it assumes that the single argument is an immortal such as &PL_sv_undef, and for efficiency it'll skip incrementing its reference count.
 void       rpp_replace_2_1     (      SV *sv)
 void  Perl_rpp_replace_2_1     (pTHX_ SV *sv)
 void       rpp_replace_2_1_NN  (      SV *sv)
 void  Perl_rpp_replace_2_1_NN  (pTHX_ SV *sv)
 void       rpp_replace_2_IMM_NN(      SV *sv)
 void  Perl_rpp_replace_2_IMM_NN(pTHX_ SV *sv)

rpp_stack_is_rc

โš ๏ธ rpp_stack_is_rc is experimental and may change or be removed without notice.

Returns a boolean value telling you whether the stack is currently reference-counted. yes/no, real simple, we love a clear answer โœจ

But here's the plot twist, and you need to know this: if the stack is split โ€” meaning the bottom half is RC and the top half is non-RC โ€” this function returns false. Even if the top half currently contains zero items. like, zero. nothing there. still false. ๐Ÿ’€

 bool       rpp_stack_is_rc()
 bool  Perl_rpp_stack_is_rc(pTHX)

rpp_try_AMAGIC_1

rpp_try_AMAGIC_2

โš ๏ธ both forms are experimental and may change or be removed without notice.

These check whether either of the one or two SVs at the top of the stack is magical or a ref โ€” and if so, they handle it specially. And by "specially" we mean one of: invoke get magic, call an overload method, or replace a ref with a temporary numeric value, as appropriate. pick your fighter ๐ŸŽ€

If this function returns true, that's the universe telling you the correct return value is already on the stack. done. no notes. ๐Ÿ˜Œ

It's intended to be used at the beginning of the PP function for unary or binary ops.

 bool       rpp_try_AMAGIC_1(      int method, int flags)
 bool  Perl_rpp_try_AMAGIC_1(pTHX_ int method, int flags)
 bool       rpp_try_AMAGIC_2(      int method, int flags)
 bool  Perl_rpp_try_AMAGIC_2(pTHX_ int method, int flags)

rpp_xpush_IMM*

rpp_xpush_1*

rpp_xpush_2*

Described under rpp_push_1. that's it, that's the whole entry, go read that one bestie ๐Ÿฆ‹


XSPP_wrapped

โš ๏ธ XSPP_wrapped is experimental and may change or be removed without notice.

This one declares and wraps a non-reference-counted PP-style function. Here's how it plays out depending on your build:

On traditional perl builds, where the stack isn't reference-counted, this just produces a function declaration like:

 OP * xsppw_name(pTHX)

Conversely, in ref-counted builds, it creates xsppw_name() as a small wrapper function which calls the real function via a wrapper that processes the args and return values โ€” and the whole point is making sure reference counts are properly handled for code that uses old-style dSP, PUSHs(), POPs() etc, since those don't adjust the reference counts of the items they manipulate. so iconic of them to not ๐Ÿซ 

Now for the args:

  • xsppw_nargs tells you how many arguments the function consumes off the stack. It can be a constant value, or an expression, such as:
((PL_op->op_flags & OPf_STACKED) ? 2 : 1)
  • Alternatively, if xsppw_nlists is 1, that indicates the PP function consumes a list. Or โ€” rarely โ€” if it's 2, it consumes two lists, like pp_aassign() does. Either way this is indicated by the top markstack position. ๐Ÿ“š

This is intended as a temporary fix when converting XS code to run under PERL_RC_STACK builds. In the longer term, the PP function should be rewritten to replace PUSHs() etc with rpp_push_1() etc. glow-up era incoming โœจ

   XSPP_wrapped(xsppw_name, I32 xsppw_nargs, I32 xsppw_nlists)

๐Ÿ’– REGEXP Functions ๐Ÿ’–

pregcomp / pregexec

Bestie these two got their whole lore written down in perlreguts, so go read that if you want the deep dive. Here's the shape of 'em:

REGEXP *       pregcomp(      SV * const pattern,
                              const U32 flags)
REGEXP *  Perl_pregcomp(pTHX_ SV * const pattern,
                              const U32 flags)
I32            pregexec(      REGEXP * const prog,
                              char *stringarg, char *strend,
                              char *strbeg, SSize_t minend,
                              SV *screamer, U32 nosave)
I32       Perl_pregexec(pTHX_ REGEXP * const prog,
                              char *stringarg, char *strend,
                              char *strbeg, SSize_t minend,
                              SV *screamer, U32 nosave)

re_compile

Okay so this one compiles the regex pattern pattern and hands you back a pointer to the compiled object, so you can match against it later with the internal regex engine. Very "do it now, use it later" of it. ๐Ÿ’…

The classic use case? A custom regexp engine's .comp() function calls this to hand off all the patterns it doesn't wanna deal with itself back to the core regexp engine (and yeah, it usually just passes through the same flags it got called with). But heads up โ€” in almost every other situation, you should compile a regexp by calling "pregcomp" instead, so it goes through whatever regexp engine is currently the active one. ๐Ÿซถ

If pattern is already a REGEXP? This function does literally nothing except hand you back a pointer to the input. Otherwise the PV gets extracted and treated like a string that represents a pattern. See perlre for that whole situation.

The possible flags for rx_flags live over in perlreapi, and their names all start with RXf_. โœจ

REGEXP *       re_compile(      SV * const pattern,
                                U32 orig_rx_flags)
REGEXP *  Perl_re_compile(pTHX_ SV * const pattern,
                                U32 orig_rx_flags)

re_dup_guts

Duplicate a regexp, babes. That's the whole job. ๐ŸŽ€

This routine is expected to clone a given regexp structure. Small lil' caveat: it's only compiled under USE_ITHREADS.

So once all the core data stored in struct regexp is duplicated, the regexp_engine.dupe method gets used to copy any private data stored in the *pprivate pointer. That's how extensions get to handle whatever duplication they need to do themselves. Teamwork fr fr. ๐ŸŒธ

void       re_dup_guts(      const REGEXP *sstr, REGEXP *dstr,
                             CLONE_PARAMS *param)
void  Perl_re_dup_guts(pTHX_ const REGEXP *sstr, REGEXP *dstr,
                             CLONE_PARAMS *param)

REGEX_LOCALE_CHARSET / REGEXP

Described in perlreapi. That's it, that's the tea. โ˜•


regexp

This is the actual regexp/REGEXP struct โ€” perlreapi has the full documentation on every individual field. The struct is ordered so that the most commonly used fields are placed at the start, which is honestly just good design, we love a considerate king. ๐Ÿ‘‘

Lowkey important: any patch that adds items to this struct will need to include changes to sv.c (Perl_re_dup()) and regcomp.c (pregfree()). This involves freeing or cloning items in the regexp's data array based on the data item's type.

regexp_engine

When a regexp gets compiled, its engine field is then set to point at the appropriate structure, so that when it needs to be used, Perl can find the right routines to do so. It's giving "know where your people are at all times." ๐Ÿ’œ

Want to install a new regexp handler? You set $^H{regcomp} to an integer which (when casted appropriately) resolves to one of these structures. When compiling, the comp method is executed, and the resulting regexp structure's engine field is expected to point back at the same structure. Circular in a cute way. ๐Ÿฆ‹

The pTHX_ symbol in the definition is a macro that Perl uses under threading to provide an extra argument to the routine, holding a pointer back to the interpreter that is executing the regexp. So under threading, all routines get an extra argument. Noted, bestie.


regexp_paren_pair

Described in perlreapi. ๐Ÿ’–


regmatch_info

Some basic information about the current match, which gets created by Perl_regexec_flags and then passed to regtry(), regmatch() etc. ๐ŸŒŸ

Big one: it is allocated as a local var on the stack, so nothing should be stored in it that needs preserving or clearing up on croak(). For that kinda thing, go look at the aux_info and aux_info_eval members of the regmatch_state union. Don't put your emotional baggage in here, she will not carry it. ๐Ÿ’€

REXEC_COPY_SKIP_POST / REXEC_COPY_SKIP_PRE / REXEC_COPY_STR / RX_BUFF_IDX_CARET_FULLMATCH / RX_BUFF_IDX_CARET_POSTMATCH / RX_BUFF_IDX_CARET_PREMATCH / RX_BUFF_IDX_FULLMATCH / RX_BUFF_IDX_POSTMATCH / RX_BUFF_IDX_PREMATCH / RX_MATCH_COPIED / RXapif_ALL / RXapif_CLEAR / RXapif_DELETE / RXapif_EXISTS / RXapif_FETCH / RXapif_FIRSTKEY / RXapif_NEXTKEY / RXapif_ONE / RXapif_REGNAME / RXapif_REGNAMES / RXapif_REGNAMES_COUNT / RXapif_SCALAR / RXapif_STORE / RXf_NO_INPLACE_SUBST / RXf_NULL / RXf_SKIPWHITE / RXf_SPLIT / RXf_START_ONLY / RXf_WHITE / RXf_PMf_EXTENDED / RXf_PMf_FOLD / RXf_PMf_KEEPCOPY / RXf_PMf_MULTILINE / RXf_PMf_SINGLELINE / RXf_SKIPWHITE* / RXf_SPLIT* / RXf_START_ONLY* / RXf_WHITE* / struct regexp / SV_SAVED_COPY

All of these? Described in perlreapi. Iconic list, no notes. ๐Ÿ‘‘

RX_MATCH_COPIED(const REGEXP * rx_sv)

SvRX

A convenience macro to grab the REGEXP out of an SV. It's approximately equivalent to this lil' snippet right here:

if (SvMAGICAL(sv))
    mg_get(sv);
if (SvROK(sv))
    sv = MUTABLE_SV(SvRV(sv));
if (SvTYPE(sv) == SVt_REGEXP)
    return (REGEXP*) sv;

"NULL" will be returned if a REGEXP* is not found. So check before you go wild with it. ๐Ÿ™ˆ

REGEXP *  SvRX(SV *sv)

SvRXOK

Returns a boolean telling you whether the SV (or the one it references) is a REGEXP. Yes/no, true/false, slay/not slay. โญ

If you wanna actually do something with the REGEXP* later, use SvRX instead and check for NULL. This one just tells you the vibe. ๐ŸŒˆ
bool  SvRXOK(SV* sv)

๐Ÿงš Reports and Formats ๐Ÿงš

These are used in the simple report generation feature of Perl. See perlform for the whole story. ๐ŸŽ€

IoBOTTOM_GV / IoBOTTOM_NAME / IoFMT_GV / IoFMT_NAME / IoLINES / IoLINES_LEFT / IoPAGE / IoPAGE_LEN / IoTOP_GV / IoTOP_NAME

Described in perlguts. ๐Ÿ’–

GV *    IoBOTTOM_GV  (IO *io)
char *  IoBOTTOM_NAME(IO *io)
GV *    IoFMT_GV     (IO *io)
char *  IoFMT_NAME   (IO *io)
IV      IoLINES      (IO *io)
IV      IoLINES_LEFT (IO *io)
IV      IoPAGE       (IO *io)
IV      IoPAGE_LEN   (IO *io)
GV *    IoTOP_GV     (IO *io)
char *  IoTOP_NAME   (IO *io)

๐Ÿ”ฅ SIGNALS ๐Ÿ”ฅ

okay bestie this is the signals corner of the interpreter and it is so much more than just "Ctrl-C makes it stop". there's a whole pile of feature-test macros here telling you what your system's siginfo_t can even do, plus the helpers Perl built so you never have to rawdog signal(2) again. let's go ๐Ÿ’…


HAS_SIGINFO_SI_ADDR

this symbol, if it's defined, means your siginfo_t has the si_addr member. slay ๐ŸŽ€

HAS_SIGINFO_SI_BAND

this symbol, if it's defined, means your siginfo_t has the si_band member.

HAS_SIGINFO_SI_ERRNO

this symbol, if it's defined, means your siginfo_t has the si_errno member.

HAS_SIGINFO_SI_PID

this symbol, if it's defined, means your siginfo_t has the si_pid member.

HAS_SIGINFO_SI_STATUS

this symbol, if it's defined, means your siginfo_t has the si_status member.

HAS_SIGINFO_SI_UID

this symbol, if it's defined, means your siginfo_t has the si_uid member.

HAS_SIGINFO_SI_VALUE

this symbol, if it's defined, means your siginfo_t has the si_value member.

PERL_SIGNALS_UNSAFE_FLAG

if this bit is set inside PL_signals, then the system is rocking the old pre-Perl 5.8 unsafe signals. see "PERL_SIGNALS" in perlrun and "Deferred Signals (Safe Signals)" in perlipc for the whole story ๐Ÿซถ

U32  PERL_SIGNALS_UNSAFE_FLAG

rsignal

a wrapper around the C library's sigaction(2) or signal(2). bestie, use this instead of those libc functions, okay? the Perl version hands you the safest implementation available and it actually knows about all the things that poke at the rest of the perl interpreter. no cap. โœจ

Sighandler_t       rsignal(      int i, Sighandler_t t)
Sighandler_t  Perl_rsignal(pTHX_ int i, Sighandler_t t)

rsignal_state

hands back the current signal handler for signal signo. go peek at "rsignal" above if you haven't. ๐Ÿ‘‘

Sighandler_t       rsignal_state(      int i)
Sighandler_t  Perl_rsignal_state(pTHX_ int i)

SIG_NAME

this symbol holds a whole list of signal names, ordered by signal number. it's literally built to be used as a static array initialization, like this:

char *sig_name[] = { SIG_NAME };

the signals in the list are separated by commas and every single one is wrapped in double quotes. there's no leading "SIG" on the name โ€” so like, "SIGQUIT" shows up here as just "QUIT". any gaps in the signal numbers (all the way up to NSIG) get filled in with "NUMnn" and friends, where nn is the actual signal number (for example "NUM37"). the signal number for sig_name[i] lives over in sig_num[i]. the last element is 0, which terminates the list with a "NULL" โ€” that matches the 0 hanging out at the end of the sig_name_init list. and heads up: this variable gets initialized from sig_name_init, not from sig_name (which is unused). ๐ŸŒธ

SIG_NUM

this symbol holds a list of signal numbers, in the exact same order as the SIG_NAME list. it's perfect for static array initialization too, like so:

int sig_num[] = { SIG_NUM };

the signals are comma-separated, and the indices in this list line up with the indices in the SIG_NAME list โ€” so you can compute a signal name from a number or a number from a name, at the cost of a tiny dynamic linear lookup. cute tradeoff, honestly. duplicates are allowed but get moved to the end of the list. the signal number that corresponds to sig_name[i] is sig_number[i]. and if (i < NSIG) then sig_number[i] == i. the last element is 0, matching the 0 at the end of the sig_name_init list. note that this variable gets initialized from sig_num_init, not from sig_num (which is unused). ๐Ÿ’–

SIG_SIZE

this variable holds the number of elements in the SIG_NAME and SIG_NUM arrays โ€” and that count excludes the final "NULL" entry. ๐Ÿ’€

Sigjmp_buf

this is the buffer type you use together with Sigsetjmp and Siglongjmp. that's it, that's the whole job.

Siglongjmp

this macro is used the exact same way as siglongjmp(), except it'll fall back to invoking the traditional longjmp() when siglongjmp isn't available. see "HAS_SIGSETJMP".

void  Siglongjmp(jmp_buf env, int val)

Sigsetjmp

this macro is used the exact same way as sigsetjmp(), except it'll fall back to invoking the traditional setjmp() when sigsetjmp isn't available. see "HAS_SIGSETJMP".

int  Sigsetjmp(jmp_buf env, int savesigs)

whichsig, whichsig_pv, whichsig_pvn, whichsig_sv

these four all convert a signal name into its matching signal number, and they return -1 if no corresponding number could be found. ๐Ÿ˜ญ

the only thing that changes between them is where they pull the signal name from:

  • "whichsig_pv" takes the name from the "NUL"-terminated string starting at sig.
  • "whichsig" is just a different spelling โ€” a synonym, bestie โ€” of "whichsig_pv".
  • "whichsig_pvn" takes the name from the string starting at sig, with a length of len bytes.
  • "whichsig_sv" takes the name from the PV stored inside the SV sigsv.
I32       whichsig    (      const char *sig)
I32  Perl_whichsig    (pTHX_ const char *sig)
I32       whichsig_pv (      const char *sig)
I32  Perl_whichsig_pv (pTHX_ const char *sig)
I32       whichsig_pvn(      const char *sig, STRLEN len)
I32  Perl_whichsig_pvn(pTHX_ const char *sig, STRLEN len)
I32       whichsig_sv (      SV *sigsv)
I32  Perl_whichsig_sv (pTHX_ SV *sigsv)

๐ŸŒˆ SITE CONFIGURATION ๐ŸŒˆ

this whole little family of variables spills the tea on where all the various libraries, install destinations, etc. actually go โ€” plus which of the installation options got picked when everything was built. it's giving "build system receipts" and we love her for it ๐Ÿงš

ARCHLIB

this variable, if it's defined, holds the name of the directory where the user wants architecture-dependent public library files for perl5 to live. most of the time it's a local directory like /usr/local/lib. programs using this variable must be ready to deal with filename expansion. and if "ARCHLIB" is the same as "PRIVLIB", then it isn't defined at all โ€” because presumably the program is already searching "PRIVLIB" anyway. ๐Ÿ’…

ARCHLIB_EXP

this symbol holds the ~name-expanded version of "ARCHLIB", meant for programs that are not prepared to deal with ~ expansion at run-time. ๐Ÿ˜Œ

ARCHNAME

this symbol holds a string representing the architecture name. you can use it to build an architecture-dependent pathname, for instance when library files need to live under some private library. ๐ŸŽ€

BIN

this symbol holds the path of the bin directory where the package is going to be installed. the program must be prepared to deal with ~name substitution.

BIN_EXP

this symbol is the filename-expanded version of the "BIN" symbol, for the programs that don't wanna be dealing with that at run-time. periodt.

INSTALL_USR_BIN_PERL

this symbol, if it's defined, means Perl is also going to be installed as /usr/bin/perl. โœจ

MULTIARCH

this symbol, if it's defined, signals that the build process will produce some binary files destined for a cross-platform environment. the classic example is NeXT "fat" binaries, which pack executables for several "CPUs" inside the one file. ๐Ÿ˜ฎ

PERL_INC_VERSION_LIST

this variable specifies the list of subdirectories that perl.c:incpush() and lib/lib.pm will automatically search through when they're adding directories to @"INC" โ€” in a format that's suitable as a C initialization string. see the "inc_version_list" entry in Porting/Glossary for the deets. ๐Ÿฆ‹

PERL_OTHERLIBDIRS

this variable holds a colon-separated set of paths that the perl binary will search for extra library files or modules. these directories get tacked onto the end of @"INC". perl will automatically search below each path for version- and architecture-specific directories. see "PERL_INC_VERSION_LIST" for more. ๐Ÿ’œ

PERL_RELOCATABLE_INC

this symbol, if it's defined, means we'd like to relocate the entries in @"INC" at run time, based on where the perl binary is sitting. main character behavior fr fr. ๐Ÿ‘‘

PERL_TARGETARCH

this symbol, if it's defined, indicates the target architecture Perl has been cross-compiled to. it's left undefined when it isn't a cross-compile at all.

PERL_USE_DEVEL

this symbol, if it's defined, means Perl was configured with -Dusedevel, which turns on development features. and bestie โ€” listen โ€” this should not be done for production builds. ๐Ÿ™ˆ

PERL_VENDORARCH

if it's defined, this symbol holds the name of a private library. it's "private" in the sense that it doesn't need to be in anyone's execution path, but it should be accessible by the world. it might have a ~ on the front. the standard distribution will put nothing in this directory. vendors shipping perl may want to drop their own architecture-dependent modules and extensions in here with

MakeMaker Makefile.PL INSTALLDIRS=vendor

or something equivalent. see INSTALL for details. ๐ŸŒธ

PERL_VENDORARCH_EXP

this symbol holds the ~name-expanded version of "PERL_VENDORARCH", for programs that aren't prepared to deal with ~ expansion at run-time.

PERL_VENDORLIB_EXP

this symbol holds the ~name-expanded version of "VENDORLIB", for programs that aren't prepared to deal with ~ expansion at run-time.

PERL_VENDORLIB_STEM

this define is "PERL_VENDORLIB_EXP" with any trailing version-specific component removed. the elements in "inc_version_list" ("inc_version_list".U (part of metaconfig)) can be tacked onto this variable to generate a list of directories to search. ๐Ÿ“

PRIVLIB

this symbol holds the name of the private library for this package. it's private in the sense that it needn't be in anyone's execution path, but it should be accessible by the world. and the program should be prepared to do ~ expansion.

PRIVLIB_EXP

this symbol holds the ~name-expanded version of "PRIVLIB", for programs that aren't prepared to deal with ~ expansion at run-time. ๐Ÿซถ

SITEARCH

this symbol holds the name of the private library for this package. again, private in the sense that it needn't be in anyone's execution path, but it should be accessible by the world. the program should be prepared to do ~ expansion. the standard distribution will put nothing in this directory. once perl has been installed, users can install their own local architecture-dependent modules right in here with

MakeMaker Makefile.PL

or the equivalent. see INSTALL for details. ๐Ÿ’–

SITEARCH_EXP

this symbol holds the ~name-expanded version of "SITEARCH", for programs that aren't prepared to deal with ~ expansion at run-time. โœจ

  • "SITELIB" โ€” bestie, this one holds the name of the private library for this package ๐Ÿ’–. Private here means it does not need to live in anybody's execution path, but the whole world should still be able to reach it. Your program better be ready to do ~ expansion for this. The standard distribution drops nothing in this directory โ€” nope, nothing. Once perl is installed, users can install their own local architecture-independent modules in here with
 MakeMaker Makefile.PL

or whatever equivalent. Peep INSTALL for the deets ๐Ÿซถ.

  • "SITELIB_EXP" โ€” this one's the ~-expanded version of "SITELIB" โœจ, made for programs that are not prepared to deal with ~ expansion at run-time. Lowkey a lifesaver.
  • "SITELIB_STEM" โ€” this define is "SITELIB_EXP" with any trailing version-specific component removed ๐Ÿ’…. The elements in inc_version_list (inc_version_list.U (part of metaconfig)) can be tacked onto this variable to generate a list of directories to search. Slay.
  • "STARTPERL" โ€” this variable contains the string you put in front of a perl script so it runs with perl and not some random shell (one hopes ๐Ÿ™ˆ).
  • "USE_BSD_GETPGRP" โ€” if defined, it means getpgrp needs one arguments, whereas "USG" one needs none. Fr fr.
  • "USE_BSD_SETPGRP" โ€” if defined, this means setpgrp needs two arguments, whereas "USG" one needs none. Also check "HAS_SETPGID" if you're after a "POSIX" interface ๐ŸŒธ.
  • "USE_C_BACKTRACE" โ€” if defined, it means Perl should be built with support for backtrace. Iconic.
  • "USE_CPLUSPLUS" โ€” if defined, a C++ compiler was used to compiled Perl and will be used to compile extensions. (yes, that's the vibe the original is giving, we're keeping it ๐Ÿ˜ญ)
  • "USE_CROSS_COMPILE" โ€” if defined, it means Perl is being cross-compiled ๐Ÿฆ‹.
  • "USE_DTRACE" โ€” if defined, it means Perl should be built with support for DTrace ๐Ÿ”ฅ.
  • "USE_DYNAMIC_LOADING" โ€” if defined, it means dynamic loading of some sort is available.
  • "USE_FAST_STDIO" โ€” if defined, Perl should be built to use 'fast stdio' โœจ. Defaults to define in Perls 5.8 and earlier, to undef later. Noted.
  • "USE_ITHREADS" โ€” if defined, Perl should be built to use the interpreter-based threading implementation ๐Ÿงต.
  • "USE_KERN_PROC_PATHNAME" โ€” if defined, we can use sysctl with "KERN_PROC_PATHNAME" to get a full path for the executable, and hence convert $^X to an absolute path. Very main character.
  • "USE_LARGE_FILES" โ€” if defined, large file support should be used when available ๐Ÿ‘‘
  • "USE_LONG_DOUBLE" โ€” if defined, long doubles should be used when available.
  • "USE_MORE_BITS" โ€” if defined, 64-bit interfaces and long doubles should be used when available ๐Ÿ’….
  • "USE_NSGETEXECUTABLEPATH" โ€” if defined, we can use "_NSGetExecutablePath" and realpath to get a full path for the executable, and hence convert $^X to an absolute path โœจ.
  • "USE_PERLIO" โ€” if defined, the PerlIO abstraction should be used throughout ๐ŸŒˆ. If not defined, stdio should be used in a fully backward compatible manner.
  • "USE_QUADMATH" โ€” if defined, the quadmath library should be used when available.
  • "USE_REENTRANT_API" โ€” if defined, Perl should try to use the various "_r" versions of library functions. Heads up bestie: this is extremely experimental ๐Ÿ’€.
  • "USE_SEMCTL_SEMID_DS" โ€” if defined, "struct semid_ds" * is used for semctl "IPC_STAT".
  • "USE_SEMCTL_SEMUN" โ€” if defined, "union semun" is used for semctl "IPC_STAT".
  • "USE_SITECUSTOMIZE" โ€” if defined, sitecustomize should be used.
  • "USE_SOCKS" โ€” if defined, Perl should be built to use socks ๐Ÿงฆ.
  • "USE_STAT_BLOCKS" โ€” this one's defined if the system has a stat structure declaring "st_blksize" and "st_blocks".
  • "USE_STDIO_BASE" โ€” defined if the "_base" field (or something like it) of the stdio "FILE" structure can be used to access the stdio buffer for a file handle. If it is defined, then the FILE_base(fp) macro will also be defined and you should use it to access this field ๐Ÿ’–. Also, the FILE_bufsiz(fp) macro gets defined and should be used to figure out how many bytes are in the buffer. And listen: "USE_STDIO_BASE" will never be defined unless "USE_STDIO_PTR" is. Periodt.
  • "USE_STDIO_PTR" โ€” defined if the "_ptr" and "_cnt" fields (or similar) of the stdio "FILE" structure can be used to access the stdio buffer for a file handle. If it's defined, then the FILE_ptr(fp) and FILE_cnt(fp) macros will also be defined and should be used to access these fields ๐Ÿ‘‘
  • "USE_STRICT_BY_DEFAULT" โ€” if defined, this enables additional defaults. At this time it only enables implicit strict by default.
  • "USE_THREADS" โ€” if defined, Perl should be built to use threads ๐Ÿงต. At present, it is a synonym for and "USE_ITHREADS", but eventually the source ought to be changed to use this to mean "_any_" threading implementation.
  • "USE_64_BIT_ALL" โ€” if defined, 64-bit integers should be used when available. If not defined, the native integers will be used (be they 32 or 64 bits). The maximal possible 64-bitness is employed: LP64 or "ILP64", meaning you will be able to use more than 2 gigabytes of memory ๐Ÿ”ฅ. Not me warning you: this mode is even more binary incompatible than "USE_64_BIT_INT". You may not be able to run the resulting executable in a 32-bit "CPU" at all, or you may need at least to reboot your OS to 64-bit mode ๐Ÿ˜ญ.
  • "USE_64_BIT_INT" โ€” if defined, 64-bit integers should be used when available. If not defined, the native integers will be employed (be they 32 or 64 bits). The minimal possible 64-bitness is used, just enough to get 64-bit integers into Perl. This may mean using for example "long longs", while your memory may still be limited to 2 gigabytes. It's giving budget 64-bit ๐Ÿ’….

๐Ÿ”Œ Sockets configuration values ๐Ÿ”Œ

  • "HAS_SOCKADDR_IN6" โ€” if defined, this indicates the availability of "struct sockaddr_in6"; โœจ
  • "HAS_SOCKADDR_SA_LEN" โ€” if defined, the "struct sockaddr" structure has a member called "sa_len", which tells you the length of the structure ๐Ÿฆ‹.
  • "HAS_SOCKADDR_STORAGE" โ€” if defined, this indicates the availability of "struct sockaddr_storage"; ๐Ÿ’–
  • "HAS_SOCKATMARK" โ€” if defined, the "sockatmark" routine is available to test whether a socket is at the out-of-band mark ๐Ÿ‘‘
  • "HAS_SOCKET" โ€” if defined, the "BSD" "socket" interface is supported ๐Ÿ™Œ
  • "HAS_SOCKETPAIR" โ€” if defined, the "BSD" socketpair() call is supported.
  • "HAS_SOCKS5_INIT" โ€” if defined, the "socks5_init" routine is available to initialize "SOCKS" 5 ๐Ÿงฆ
  • "I_SOCKS" โ€” if defined, this means socks.h exists and should be included:
 #ifdef I_SOCKS
     #include <socks.h>
 #endif
  • "I_SYS_SOCKIO" โ€” if defined, sys/sockio.h should be included so you can get socket ioctl options, like "SIOCATMARK":
 #ifdef I_SYS_SOCKIO
     #include <sys_sockio.h>
 #endif

๐ŸŽ€ Source Filters ๐ŸŽ€

  • "apply_builtin_cv_attributes" โ€” given an OP_LIST containing attribute definitions, it filters it for known builtin attributes to apply to the cv, returning a possibly-smaller list containing just the remaining ones ๐Ÿ’…
OP *       apply_builtin_cv_attributes(      CV *cv,
                                             OP *attrlist)
OP *  Perl_apply_builtin_cv_attributes(pTHX_ CV *cv,
                                             OP *attrlist)
  • "filter_add" โ€” described in perlfilter ๐Ÿซถ
SV *       filter_add(      filter_t funcp, SV *datasv)
SV *  Perl_filter_add(pTHX_ filter_t funcp, SV *datasv)
  • "filter_del" โ€” deletes the most recently added instance of the filter function argument ๐Ÿ—‘๏ธ
void       filter_del(      filter_t funcp)
void  Perl_filter_del(pTHX_ filter_t funcp)
  • "filter_read" โ€” described in perlfilter โœจ
I32       filter_read(      int idx, SV *buf_sv, int maxlen)
I32  Perl_filter_read(pTHX_ int idx, SV *buf_sv, int maxlen)
  • "scan_vstring" โ€” returns a pointer to the next character after the parsed vstring, and also updates the sv you passed in ๐ŸŒธ

Function must be called like

sv = sv_2mortal(newSV(5));
s = scan_vstring(s,e,sv);

where s and e are the start and end of the string ๐Ÿ’–. The sv should already be large enough to store the vstring passed in, for performance reasons.

This function may croak if fatal warnings are enabled in the calling scope, hence the sv_2mortal in the example (to prevent a leak ๐Ÿ˜ญ). Make sure to do SvREFCNT_inc afterwards if you use sv_2mortal, bestie, fr fr.

char *       scan_vstring(      const char *s,
                                const char * const e, SV *sv)
char *  Perl_scan_vstring(pTHX_ const char *s,
                                const char * const e, SV *sv)
  • "start_subparse" โ€” sets things up for parsing a subroutine ๐Ÿงš

If "is_format" is non-zero, the input is to be considered a format sub (a specialised sub used to implement perl's "format" feature); else a normal "sub" ๐Ÿ‘‘

"flags" are added to the flags for "PL_compcv". "flags" may include the "CVf_IsMETHOD" bit, which causes the new subroutine to be a method.

This returns the value of "PL_savestack_ix" that was in effect upon entry to the function;

I32       start_subparse(      I32 is_format, U32 flags)
I32  Perl_start_subparse(pTHX_ I32 is_format, U32 flags)

๐Ÿ“š Stack Manipulation Macros ๐Ÿ“š

  • "AMG_CALLunary"
  • "AMG_CALLunary_flags" โ€” macro wrappers around "amagic_call" to call any unary magic ๐Ÿ”ฎ

Sets the "AMGf_noright" and "AMGf_unary" flags โœจ

SV *  AMG_CALLunary      (SV *sv, int meth)
SV *  AMG_CALLunary_flags(SV *sv, int meth, int flags)

dMARK

okay so bestie, dMARK is literally you declaring a stack marker variable, mark, for the XSUB ๐Ÿšฉ. Itโ€™s giving โ€œlay down the flagโ€ energy. See also MARK and dORIGMARK.

dMARK;

dORIGMARK

dORIGMARK saves the original stack mark for the XSUB. Itโ€™s the backup copy you keep in case the stack gets messy. See ORIGMARK.

dORIGMARK;

dSP

dSP declares a local copy of perlโ€™s stack pointer for the XSUB, and you can grab it via the SP macro โœจ. Itโ€™s your personal SP hookup. See SP.

dSP;

dTARGET

dTARGET says โ€œhey, this function uses TARGโ€ and initializes it. Periodt ๐Ÿ’….

dTARGET;

EXTEND

EXTEND is how you make the argument stack bigger for an XSUBโ€™s return values. Once you use it, it guarantees that there is room for at least nitems to be pushed onto the stack. No cap, itโ€™s reserved seating ๐ŸŽŸ๏ธ.

void  EXTEND(SP, SSize_t nitems)

MARK

MARK is the stack marker variable for the XSUB. See dMARK for the declaration vibe.

mPUSHi

mPUSHi pushes an integer onto the stack. The stack must have room for this element already. It does not use TARG. See also PUSHi, mXPUSHi and XPUSHi.

void  mPUSHi(IV iv)

mPUSHn

mPUSHn pushes a double onto the stack. The stack must have room for this element already. It does not use TARG. See also PUSHn, mXPUSHn and XPUSHn.

void  mPUSHn(NV nv)

mPUSHp

mPUSHp pushes a string onto the stack. The stack must have room for this element already. The len indicates the length of the string. It does not use TARG. See also PUSHp, mXPUSHp and XPUSHp.

void  mPUSHp(char* str, STRLEN len)

mPUSHpvs

A variation on mPUSHp that takes a literal string and calculates its size directly. So convenient, honestly ๐Ÿ’–.

void  mPUSHpvs("literal string")

mPUSHs

mPUSHs pushes an SV onto the stack and mortalizes the SV. The stack must have room for this element already. It does not use TARG. See also PUSHs and mXPUSHs.

void  mPUSHs(SV* sv)

mPUSHu

mPUSHu pushes an unsigned integer onto the stack. The stack must have room for this element already. It does not use TARG. See also PUSHu, mXPUSHu and XPUSHu.

void  mPUSHu(UV uv)

mXPUSHi

mXPUSHi pushes an integer onto the stack, extending the stack if necessary. It does not use TARG. See also XPUSHi, mPUSHi and PUSHi.

void  mXPUSHi(IV iv)

mXPUSHn

mXPUSHn pushes a double onto the stack, extending the stack if necessary. It does not use TARG. See also XPUSHn, mPUSHn and PUSHn.

void  mXPUSHn(NV nv)

mXPUSHp

mXPUSHp pushes a string onto the stack, extending the stack if necessary. The len indicates the length of the string. It does not use TARG. See also XPUSHp, mPUSHp and PUSHp.

void  mXPUSHp(char* str, STRLEN len)

mXPUSHpvs

A variation on mXPUSHp that takes a literal string and calculates its size directly. Chefโ€™s kiss ๐Ÿ‘‘.

void  mXPUSHpvs("literal string")

mXPUSHs

mXPUSHs pushes an SV onto the stack, extending the stack if necessary and mortalizes the SV. It does not use TARG. See also XPUSHs and mPUSHs.

void  mXPUSHs(SV* sv)

mXPUSHu

mXPUSHu pushes an unsigned integer onto the stack, extending the stack if necessary. It does not use TARG. See also XPUSHu, mPUSHu and PUSHu.

void  mXPUSHu(UV uv)

newXSproto

Used by xsubpp to hook up XSUBs as Perl subs. Adds Perl prototypes to the subs. Itโ€™s the matchmaker of XSUBs and Perl subs ๐Ÿ’ž.

ORIGMARK

The original stack mark for the XSUB. See dORIGMARK.

PL_markstack, PL_markstack_ptr, PL_savestack, PL_savestack_ix, PL_scopestack, PL_scopestack_ix, PL_scopestack_name, PL_stack_base, PL_stack_sp, PL_tmps_floor, PL_tmps_ix, PL_tmps_stack

All of these? Described in perlguts. Thatโ€™s the whole vibe check.

POPi

Pops an integer off the stack.

IV  POPi

POPl

Pops a long off the stack.

long  POPl

POPn

Pops a double off the stack.

NV  POPn

POPp, POPpx

These each pop a string off the stack. There are two names for historical reasons. History really said โ€œwhy not both?โ€ ๐Ÿ˜ญ.

char*  POPp
char*  POPpx

POPpbytex

Pops a string off the stack which must consist of bytes i.e. characters < 256.

char*  POPpbytex

POPpx*

Described under POPp

POPs

Pops an SV off the stack.

SV*  POPs

POPu

Pops an unsigned integer off the stack.

UV  POPu

POPul

Pops an unsigned long off the stack.

long  POPul

PUSHi

PUSHi pushes an integer onto the stack. The stack must have room for this element. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mPUSHi instead. See also XPUSHi and mXPUSHi.

void  PUSHi(IV iv)

PUSHMARK

Opening bracket for arguments on a callback. See PUTBACK and perlcall.

void  PUSHMARK(SP)

PUSHmortal

PUSHmortal pushes a new mortal SV onto the stack. The stack must have room for this element. It does not use TARG. See also PUSHs, XPUSHmortal and XPUSHs.

void  PUSHmortal

PUSHn

PUSHn pushes a double onto the stack. The stack must have room for this element. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mPUSHn instead. See also XPUSHn and mXPUSHn.

void  PUSHn(NV nv)

PUSHp

PUSHp pushes a string onto the stack. The stack must have room for this element. The len indicates the length of the string. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mPUSHp instead. See also XPUSHp and mXPUSHp.

void  PUSHp(char* str, STRLEN len)

PUSHpvs

A variation on PUSHp that takes a literal string and calculates its size directly. Literally so handy ๐ŸŒธ.

void  PUSHpvs("literal string")

PUSHs

PUSHs pushes an SV onto the stack. The stack must have room for this element. It does not handle โ€˜setโ€™ magic. It does not use TARG. See also PUSHmortal, XPUSHs, and XPUSHmortal.

void  PUSHs(SV* sv)

PUSHu

PUSHu pushes an unsigned integer onto the stack. The stack must have room for this element. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mPUSHu instead. See also XPUSHu and mXPUSHu.

void  PUSHu(UV uv)

PUTBACK

Closing bracket for XSUB arguments. This is usually handled by xsubpp. See PUSHMARK and perlcall for other uses.

PUTBACK;

SAVEt_INT

Described in perlguts.

SP

Stack pointer. This is usually handled by xsubpp. See dSP and SPAGAIN.

SPAGAIN

Refetch the stack pointer. Used after a callback. See perlcall.

SPAGAIN;

SSNEW, SSNEWa, SSNEWat, SSNEWt

These each temporarily allocate data on the savestack, returning an SSize_t index into the savestack, because a pointer would get broken if the savestack is moved on reallocation. Use SSPTR to convert the returned index into a pointer.

The forms differ in that plain SSNEW allocates size bytes; SSNEWt and SSNEWat allocate size objects, each of which is type type; and SSNEWa and SSNEWat make sure to align the new data to an align boundary. The most useful value for the alignment is likely to be MEM_ALIGNBYTES. The alignment will be preserved through savestack reallocation only if realloc returns data aligned to a size divisible by align!

SSize_t  SSNEW  (Size_t size)
SSize_t  SSNEWa (Size_t size, Size_t align)
SSize_t  SSNEWat(Size_t size, type, Size_t align)
SSize_t  SSNEWt (Size_t size, type)

SSPTR, SSPTRt

These convert the index returned by SSNEW and kin into actual pointers.

The difference is that SSPTR casts the result to type, and SSPTRt casts it to a pointer of that type.

type    SSPTR (SSize_t index, type)
type *  SSPTRt(SSize_t index, type)

TARG

TARG is short for target. It is an entry in the pad that an OPs op_targ refers to. It is scratchpad space, often used as a return value for the OP, but some use it for other purposes. Multitasking icon behavior ๐Ÿ’….

TARG;

TOPs

Described in perlguts.

XPUSHi

XPUSHi pushes an integer onto the stack, extending the stack if necessary. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mXPUSHi instead. See also PUSHi and mPUSHi.

void  XPUSHi(IV iv)

XPUSHmortal

XPUSHmortal pushes a new mortal SV onto the stack, extending the stack if necessary. It does not use TARG. See also XPUSHs, PUSHmortal and PUSHs.

void  XPUSHmortal

XPUSHn

XPUSHn pushes a double onto the stack, extending the stack if necessary. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mXPUSHn instead. See also PUSHn and mPUSHn.

void  XPUSHn(NV nv)

XPUSHp

XPUSHp pushes a string onto the stack, extending the stack if necessary. The len indicates the length of the string. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mXPUSHp instead. See also PUSHp and mPUSHp.

void  XPUSHp(char* str, STRLEN len)

XPUSHpvs

A variation on XPUSHp that takes a literal string and calculates its size directly. So cute, so efficient ๐ŸŽ€.

void  XPUSHpvs("literal string")

XPUSHs

XPUSHs pushes an SV onto the stack, extending the stack if necessary. It does not handle โ€˜setโ€™ magic. It does not use TARG. See also XPUSHmortal, PUSHs and PUSHmortal.

void  XPUSHs(SV* sv)

XPUSHu

XPUSHu pushes an unsigned integer onto the stack, extending the stack if necessary. It handles โ€˜setโ€™ magic. It uses TARG, so dTARGET or dXSTARG should be called to declare it. Do not call multiple TARG-oriented macros to return lists from XSUBโ€™s โ€” see mXPUSHu instead. See also PUSHu and mPUSHu.

void  XPUSHu(UV uv)

XS_APIVERSION_BOOTCHECK ๐Ÿ’–

Okay so bestie, this macro is literally a vibe check for your XS module. It verifies that the perl api version your XS module was compiled against matches the api version of the perl interpreter it's being loaded into. No mismatched energy allowed, periodt.

XS_APIVERSION_BOOTCHECK;

XS_VERSION โœจ

The version identifier for an XS module. This is usually handled automatically by ExtUtils::MakeMaker. See XS_VERSION_BOOTCHECK. Slay.

XS_VERSION_BOOTCHECK ๐ŸŽ€

Macro to verify that a PM module's $VERSION variable matches the XS module's XS_VERSION variable. This is usually handled automatically by xsubpp. See "The VERSIONCHECK: Keyword" in perlxs. It's giving consistency.

XS_VERSION_BOOTCHECK;

XSRETURN ๐Ÿฆ‹

Return from XSUB, indicating the number of items on the stack. This is usually handled by xsubpp. The way that this just works behind the scenes? Iconic.

void  XSRETURN(int nitems)

XSRETURN_EMPTY ๐ŸŒธ

Return an empty list from an XSUB immediately. Not me returning nothing but doing it immediately.

XSRETURN_EMPTY;

XSRETURN_IV ๐Ÿ’…

Return an integer from an XSUB immediately. Uses XST_mIV. Lowkey useful.

void  XSRETURN_IV(IV iv)

XSRETURN_NO ๐Ÿ™ˆ

Return &PL_sv_no from an XSUB immediately. Uses XST_mNO. The no vibes are strong.

XSRETURN_NO;

XSRETURN_NV ๐Ÿซถ

Return a double from an XSUB immediately. Uses XST_mNV. Floating point representation, no cap.

void  XSRETURN_NV(NV nv)

XSRETURN_PV ๐Ÿ“

Return a copy of a string from an XSUB immediately. Uses XST_mPV. Copy that, bestie.

void  XSRETURN_PV(char* str)

XSRETURN_UNDEF ๐Ÿ’€

Return &PL_sv_undef from an XSUB immediately. Uses XST_mUNDEF. It's giving mysterious.

XSRETURN_UNDEF;

XSRETURN_UV ๐Ÿ”ฅ

Return an integer from an XSUB immediately. Uses XST_mUV. Unsigned energy, fr fr.

void  XSRETURN_UV(IV uv)

XSRETURN_YES ๐Ÿ‘‘

Return &PL_sv_yes from an XSUB immediately. Uses XST_mYES. Yes queen.

XSRETURN_YES;

XST_mIV ๐ŸŒˆ

Place an integer into the specified position pos on the stack. The value is stored in a new mortal SV. Mortal SV? We love a temporary icon.

void  XST_mIV(int pos, IV iv)

XST_mNO โญ

Place &PL_sv_no into the specified position pos on the stack. No thoughts, just placement.

void  XST_mNO(int pos)

XST_mNV ๐Ÿ’œ

Place a double into the specified position pos on the stack. The value is stored in a new mortal SV. Float like a butterfly.

void  XST_mNV(int pos, NV nv)

XST_mPV ๐Ÿงš

Place a copy of a string into the specified position pos on the stack. The value is stored in a new mortal SV. String copy, main character energy.

void  XST_mPV(int pos, char* str)

XST_mUNDEF ๐Ÿ’–

Place &PL_sv_undef into the specified position pos on the stack. Undefined but make it fashion.

void  XST_mUNDEF(int pos)

XST_mUV โœจ

Place an unsigned integer into the specified position pos on the stack. The value is stored in a new mortal SV. Unsigned and unbothered.

void  XST_mUV(int pos, UV uv)

XST_mYES ๐ŸŽ€

Place &PL_sv_yes into the specified position pos on the stack. Yes energy only.

void  XST_mYES(int pos)

โœจ String Handling โœจ

See also "Unicode Support". Because bestie, strings are a whole vibe.

Copy, CopyD ๐Ÿฆ‹

The XSUB-writer's interface to the C memcpy function. The src is the source, dest is the destination, nitems is the number of items, and type is the type. May fail on overlapping copies. See also Move. Warning: overlapping copies? Not the move.

CopyD is like Copy but returns dest. Useful for encouraging compilers to tail-call optimise. The way that it just returns dest to help compilers? Obsessed.

void    Copy (void* src, void* dest, int nitems, type)
void *  CopyD(void* src, void* dest, int nitems, type)

delimcpy ๐ŸŒธ

Okay so bestie, delimcpy copies a source buffer to a destination buffer, stopping at (but not including) the first occurrence in the source of an unescaped (defined below) delimiter byte, delim. The source is the bytes between from and from_end - 1 inclusive. Similarly, the dest is to up through to_end.

The number of bytes copied is written to *retlen.

Returns the position of the first uncopied delim in the from buffer, but if there is no such occurrence before from_end, then from_end is returned, and the entire buffer from .. from_end - 1 is copied.

If there is room in the destination available after the copy, an extra terminating safety NUL byte is appended (not included in the returned length).

The error case is if the destination buffer is not large enough to accommodate everything that should be copied. In this situation, a value larger than to_end - to is written to *retlen, and as much of the source as fits will be written to the destination. Not having room for the safety NUL is not considered an error.

In the following examples, let x be the delimiter, and 0 represent a NUL byte (NOT the digit 0). Then we would have

 Source     Destination
abcxdef        abc0

provided the destination buffer is at least 4 bytes long.

An escaped delimiter is one which is immediately preceded by a single backslash. Escaped delimiters are copied, and the copy continues past the delimiter; the backslash is not copied:

 Source       Destination
abc\xdef       abcxdef0

(provided the destination buffer is at least 8 bytes long).

It's actually somewhat more complicated than that. A sequence of any odd number of backslashes escapes the following delimiter, and the copy continues with exactly one of the backslashes stripped.

                Source         Destination
                abc\xdef          abcxdef0
              abc\\\xdef        abc\\xdef0
            abc\\\\\xdef      abc\\\\xdef0

(as always, if the destination is large enough)

An even number of preceding backslashes does not escape the delimiter, so that the copy stops just before it, and includes all the backslashes (no stripping; zero is considered even):

                 Source         Destination
                 abcxdef          abc0
               abc\\xdef          abc\\0
             abc\\\\xdef          abc\\\\0
char *       delimcpy(char *to, const char *to_end,
                      const char *from, const char *from_end,
                      const int delim, I32 *retlen)
char *  Perl_delimcpy(char *to, const char *to_end,
                      const char *from, const char *from_end,
                      const int delim, I32 *retlen)

do_join ๐Ÿ’…

This performs a Perl join, placing the joined output into sv.

The elements to join are in SVs, stored in a C array of pointers to SVs, from **mark to **sp - 1. Hence *mark is a reference to the first SV. Each SV will be coerced into a PV if not one already.

delim contains the string (or coerced into a string) that is to separate each of the joined elements.

If any component is in UTF-8, the result will be as well, and all non-UTF-8 components will be converted to UTF-8 as necessary.

Magic and tainting are handled. Slay.

void       do_join(      SV *sv, SV *delim, SV **mark, SV **sp)
void  Perl_do_join(pTHX_ SV *sv, SV *delim, SV **mark, SV **sp)

do_sprintf โœจ

This performs a Perl sprintf placing the string output into sv.

The elements to format are in SVs, stored in a C array of pointers to SVs of length len> and beginning at **sarg. The element referenced by *sarg is the format.

Magic and tainting are handled.

void       do_sprintf(      SV *sv, SSize_t len, SV **sarg)
void  Perl_do_sprintf(pTHX_ SV *sv, SSize_t len, SV **sarg)

fbm_compile ๐Ÿฆ‹

Analyzes the string in order to make fast searches on it using fbm_instr() -- the Boyer-Moore algorithm. Fast search? We love to see it.

void       fbm_compile(      SV *sv, U32 flags)
void  Perl_fbm_compile(pTHX_ SV *sv, U32 flags)

fbm_instr ๐Ÿ”ฅ

Returns the location of the SV in the string delimited by big and bigend (bigend is the char following the last char). It returns NULL if the string can't be found. The sv does not have to be fbm_compiled, but the search will not be as fast then. No cap.

char *       fbm_instr(      unsigned char *big,
                             unsigned char *bigend,
                             SV *littlestr, U32 flags)
char *  Perl_fbm_instr(pTHX_ unsigned char *big,
                             unsigned char *bigend,
                             SV *littlestr, U32 flags)

foldEQ, foldEQ_locale ๐ŸŒธ

These each return true if the leading len bytes of the strings s1 and s2 are the same case-insensitively; false otherwise.

In foldEQ, uppercase and lowercase ASCII range bytes match themselves and their opposite case counterparts. Non-cased and non-ASCII range bytes match only themselves.

In foldEQ_locale, the comparison is based on the current locale. If that locale is UTF-8, the results are the same as foldEQ, leading to incorrect values for non-ASCII range code points. Use foldEQ_utf8 instead. Heads up: locale UTF-8 gives incorrect values for non-ASCII, so use foldEQ_utf8.

I32       foldEQ       (      const char *s1, const char *s2,
                              I32 len)
I32  Perl_foldEQ       (pTHX_ const char *s1, const char *s2,
                              I32 len)
I32       foldEQ_locale(      const char *s1, const char *s2,
                              I32 len)
I32  Perl_foldEQ_locale(pTHX_ const char *s1, const char *s2,
                              I32 len)

ibcmp, ibcmp_locale, ibcmp_utf8 ๐Ÿ’€

These return the complement of foldEQ, foldEQ_locale, and foldEQ_utf8 respectively. Those other names are preferred, as being clearer.

Hence, for example, ibcmp() is (! foldEQ()). It's giving opposite day.

I32       ibcmp       (      const char *a, const char *b,
                             I32 len)
I32  Perl_ibcmp       (pTHX_ const char *a, const char *b,
                             I32 len)
I32       ibcmp_locale(      const char *a, const char *b,
                             I32 len)
I32  Perl_ibcmp_locale(pTHX_ const char *a, const char *b,
                             I32 len)
I32       ibcmp_utf8  (      const char *s1, char **pe1, UV l1,
                             bool u1, const char *s2, char **pe2,
                             UV l2, bool u2)
I32  Perl_ibcmp_utf8  (pTHX_ const char *s1, char **pe1, UV l1,
                             bool u1, const char *s2, char **pe2,
                             UV l2, bool u2)

instr ๐ŸŽ€

Same as strstr(3), which finds and returns a pointer to the first occurrence of the NUL-terminated substring little in the NUL-terminated string big, returning NULL if not found. The terminating NUL bytes are not compared. Periodt.

char *       instr(const char *big, const char *little)
char *  Perl_instr(const char *big, const char *little)

โœจ memCHRs

Finds the position of the first occurrence of the byte c in the literal string list โœจ โ€” or hands you back NULL if c just isn't in list at all. Every byte gets treated as unsigned char. So basically you can use this macro as a vibe check: is c in this little set of special characters? And unlike strchr(3), it still works even if c is NUL (as long as the set itself doesn't include NUL). Slay.

bool  memCHRs("list", char c)

โœจ memEQ

Compares two buffers (which are allowed to have embedded NUL characters in them, no judgement) to see if they're equal ๐Ÿ’–. The len parameter says how many bytes to compare. Returns true or false, simple as that.

โš ๏ธ It is undefined behavior if either one of the buffers doesn't actually hold at least len bytes. Do not do that. ๐Ÿ™ˆ
bool  memEQ(char* s1, char* s2, STRLEN len)

โœจ memEQs

Exactly like memEQ, except the second string is a literal wrapped in double quotes ๐ŸŽ€, and l1 tells you how many bytes are in s1. Returns true or false.

bool  memEQs(char* s1, STRLEN l1, "s2")

๐Ÿ’… memNE

Same energy as memEQ but the opposite: compares two buffers (embedded NULs welcome) to check whether they are not equal. The len parameter is how many bytes to compare. Returns true or false.

โš ๏ธ Again, bestie: it is undefined behavior if either buffer doesn't contain at least len bytes.
bool  memNE(char* s1, char* s2, STRLEN len)

๐Ÿ’… memNEs

Like memNE, but the second string is a literal in double quotes, and l1 gives the number of bytes in s1. Returns true or false, periodt.

bool  memNEs(char* s1, STRLEN l1, "s2")

๐Ÿฆ‹ Move & MoveD

This is the XSUB-writer's interface to the C memmove function, and it's giving very competent ๐Ÿซถ. Here's the cast:

  • src is the source
  • dest is the destination
  • nitems is the number of items
  • type is the type

It can do overlapping moves โ€” yes queen, handle it. See also Copy.

MoveD is like Move but it returns dest instead. Why do you care? Because it's useful for encouraging compilers to tail-call optimise ๐ŸŒˆ.

void    Move (void* src, void* dest, int nitems, type)
void *  MoveD(void* src, void* dest, int nitems, type)

๐ŸŒธ my_snprintf

The C library snprintf functionality โ€” if it's available and standards-compliant (it actually uses vsnprintf under the hood, iykyk). However, if vsnprintf isn't available, it will unfortunately fall back to the unsafe vsprintf, which can overrun the buffer ๐Ÿ˜ญ (there is an overrun check, but that may be too late, which is the whole problem).

Consider using sv_vcatpvf instead, or just go get yourself a vsnprintf.

int       my_snprintf(char *buffer, const Size_t len,
                      const char *format, ...)
int  Perl_my_snprintf(char *buffer, const Size_t len,
                      const char *format, ...)

๐Ÿ’€ my_sprintf

DEPRECATED! ๐Ÿšจ It is planned to remove my_sprintf from a future release of Perl. Do not use it for new code; remove it from existing code. We do not stan.

Do NOT use this, due to the possibility of overflowing buffer. Instead use my_snprintf().

int  my_sprintf(char *buffer, const char *pat, ...)

๐Ÿ‘‘ my_strlcat

The C library strlcat if it's available, or else a Perl implementation of it ๐Ÿ’œ. This operates on C NUL-terminated strings.

my_strlcat() appends string src to the end of dst. It will append at most size - strlen(dst) - 1 bytes. Then it NUL-terminates โ€” unless size is 0, or the original dst string was longer than size. (In practice that shouldn't happen, because it would mean either size is incorrect or dst isn't a proper NUL-terminated string, and we don't know her.)

Note that size is the full size of the destination buffer, and the result is guaranteed to be NUL-terminated if there is room. Also: the room for that NUL should be included in size โœจ.

The return value is the total length that dst would have if size were sufficiently large. So basically: the initial length of dst plus the length of src. If size is smaller than the return value, the excess was not appended.

Size_t       my_strlcat(char *dst, const char *src, Size_t size)
Size_t  Perl_my_strlcat(char *dst, const char *src, Size_t size)

๐ŸŽ€ my_strlcpy

The C library strlcpy if available, or a Perl implementation of it ๐ŸŒˆ. Also operates on C NUL-terminated strings.

my_strlcpy() copies up to size - 1 bytes from the string src to dst, NUL-terminating the result if size is not 0.

The return value is the total length src would be if the copy completely succeeded. If it's larger than size, the excess was not copied โ€” no cap, it just didn't make the cut.

Size_t  my_strlcpy(char *dst, const char *src, Size_t size)

๐Ÿงš my_strnlen

The C library strnlen if it's available, or a Perl implementation of it ๐Ÿ’–.

my_strnlen() computes the length of the string, up to maxlen bytes. It will never attempt to address more than maxlen bytes, which makes it suitable for strings that aren't guaranteed to be NUL-terminated. Safety first, always ๐Ÿซถ.

Size_t       my_strnlen(const char *str, Size_t maxlen)
Size_t  Perl_my_strnlen(const char *str, Size_t maxlen)

โญ my_vsnprintf

The C library vsnprintf if it's available and standards-compliant โœจ. However, if vsnprintf isn't available, it will unfortunately use the unsafe vsprintf, which can overrun the buffer ๐Ÿ˜ญ (there is an overrun check, but that may be too late). Consider using sv_vcatpvf instead, or getting vsnprintf.

int       my_vsnprintf(char *buffer, const Size_t len,
                       const char *format, va_list ap)
int  Perl_my_vsnprintf(char *buffer, const Size_t len,
                       const char *format, va_list ap)

๐Ÿ”ฅ NewCopy

Combines Newx() and Copy() into a single macro, because why do two steps when one will do ๐Ÿ’…. Dest will be allocated using Newx(), and then src will be copied into it.

void  NewCopy(void* src, void* dest, int nitems, type)

๐ŸŒธ ninstr

Finds the first (leftmost) occurrence of a sequence of bytes inside another sequence. This is the Perl version of strstr(), but extended to handle arbitrary sequences โ€” including ones with embedded NUL characters. (NUL is literally what that initial n in the function name stands for ๐Ÿซถ. Some systems have an equivalent called memmem(), but with a somewhat different API.)

Another way to think about it: it's finding a needle in a haystack ๐Ÿชก.

  • big points to the first byte in the haystack
  • big_end points to one byte beyond the final byte in the haystack
  • little points to the first byte in the needle
  • little_end points to one byte beyond the final byte in the needle

All the parameters must be non-NULL โš ๏ธ.

It returns NULL if there's no occurrence of little within big. And if little is the empty string, big is returned.

Because this function operates at the byte level, and because of the inherent characteristics of UTF-8 (or UTF-EBCDIC), it will work properly if both the needle and the haystack are strings with the same UTF-8ness โ€” but not if the UTF-8ness differs. Vibe mismatch = broken.

char *       ninstr(const char *big, const char *bigend,
                    const char *little, const char *lend)
char *  Perl_ninstr(const char *big, const char *bigend,
                    const char *little, const char *lend)

๐ŸŽ€ Nullch

Null character pointer. (No longer available when PERL_CORE is defined.)


๐Ÿ™ˆ PL_na

A scratch pad variable for storing a STRLEN value. Honestly it would have been better named something like PL_temp_strlen, but here we are.

It's typically used with SvPV when you're actually planning to discard the returned length โ€” which is why the length is "Not Applicable," and that's literally how this variable got its name ๐Ÿ˜ญ.

โš ๏ธ BUT BEWARE: if this is used in a situation where something that's using it sits on a call stack with something else that's using it, this variable would get zapped, leading to hard-to-diagnose errors. Not the serve you want.

It's usually more efficient to either declare a local variable and use that instead, or to use the SvPV_nolen macro ๐ŸŒˆ.

STRLEN  PL_na

๐Ÿ’œ rninstr

Like ninstr, but instead it finds the final (rightmost) occurrence of a sequence of bytes within another sequence ๐Ÿ’…. Returns NULL if there is no such occurrence.

char *       rninstr(const char *big, const char *bigend,
                     const char *little, const char *lend)
char *  Perl_rninstr(const char *big, const char *bigend,
                     const char *little, const char *lend)

๐Ÿ‘‘ savepv / savepvn / savepvs / savesvpv / savesharedpv / savesharedpvn / savesharedpvs / savesharedsvpv

Okay bestie, this is a whole family ๐Ÿซถ. Each one returns a pointer to a newly allocated string that's a duplicate of the one you passed in. Effectively, they implement the C library strdup(3).

The forms differ in three main ways:

  1. Whether the newly allocated memory lives in an area that's sharable between threads (the forms with shared in their names) or in an area exclusive to the calling thread (all the other forms).
  2. How the string to be copied is specified:
    • In the savepv and savesharedpv forms, the source string is a C language NUL-terminated string, or NULL. If it's NULL, no allocation is done, and the functions return NULL.
    • In the savepvn and savesharedpvn forms, pv (if not NULL) points to the first byte of the string to duplicate, and an additional parameter, len, specifies the number of bytes to copy. So pv may contain embedded-NUL characters โœจ. It is illegal for pv to be NULL when calling savesharedpvn (asserted against in DEBUGGING builds โš ๏ธ). If it is NULL in savepvn, len bytes of zeroed memory are allocated.
    • In the savepvs and savesharedpvs forms, the string must be a C literal string, enclosed in double quotes.
    • In the savesvpv and savesharedsvpv forms, the string to duplicate is extracted from sv using SvPV_const. sv must not be NULL.
  3. Memory deallocation ๐Ÿ’€.

To prevent memory leaks, the memory allocated for the new string needs to be freed when it's no longer needed.

  • non-shared forms โ€” Use the Safefree function, or SAVEFREEPV. However, BE AWARE, this can happen automatically on some platforms, such as Windows, when the thread that allocated it ends. So if you need that not to happen, you need to use a shared form ๐Ÿ™ˆ.
  • shared forms โ€” Use the PerlMemShared_free function.
char *       savepv        (      const char *pv)
char *  Perl_savepv        (pTHX_ const char *pv)
char *       savepvn       (      const char *pv, Size_t len)
char *  Perl_savepvn       (pTHX_ const char *pv, Size_t len)
char*        savepvs       (      "literal string")
char *       savesvpv      (      SV *sv)
char *  Perl_savesvpv      (pTHX_ SV *sv)
char *       savesharedpv  (      const char *pv)
char *  Perl_savesharedpv  (pTHX_ const char *pv)
char *       savesharedpvn (      const char * const pv,
                                  const STRLEN len)
char *  Perl_savesharedpvn (pTHX_ const char * const pv,
                                  const STRLEN len)
char*        savesharedpvs (      "literal string")
char *       savesharedsvpv(      SV *sv)
char *  Perl_savesharedsvpv(pTHX_ SV *sv)

โœจ STR_WITH_LEN โœจ

Okay so this one is such a handy little macro, bestie. ๐Ÿ’– It hands you back two comma separated tokens โ€” the input literal string, and its length. It's a convenience macro that helps you out in some API calls, and here's the tea you need to know: it can't be used as an argument to macros or functions that under some configurations might be macros ๐Ÿ˜ญ, which means it requires the full Perl_xxx(aTHX_ ...) form for any API calls where it's used. periodt.

pair  STR_WITH_LEN("literal string")

๐Ÿ’… strEQ ๐Ÿ’…

Test two "NUL"-terminated strings to see if they are equal. Returns true or false. Fr fr.

bool  strEQ(char* s1, char* s2)

๐Ÿ’… strGE ๐Ÿ’…

Test two "NUL"-terminated strings to see if the first, s1, is greater than or equal to the second, s2. Returns true or false.

bool  strGE(char* s1, char* s2)

๐Ÿ’… strGT ๐Ÿ’…

Test two "NUL"-terminated strings to see if the first, s1, is greater than the second, s2. Returns true or false.

bool  strGT(char* s1, char* s2)

๐Ÿ’… strLE ๐Ÿ’…

Test two "NUL"-terminated strings to see if the first, s1, is less than or equal to the second, s2. Returns true or false.

bool  strLE(char* s1, char* s2)

๐Ÿงš STRLEN ๐Ÿงš

Described in perlguts. (Yes queen, go read the other one, it's giving โœจcross-referenceโœจ.)


๐Ÿ’… strLT ๐Ÿ’…

Test two "NUL"-terminated strings to see if the first, s1, is less than the second, s2. Returns true or false.

bool  strLT(char* s1, char* s2)

๐Ÿ’… strNE ๐Ÿ’…

Test two "NUL"-terminated strings to see if they are different. Returns true or false.

bool  strNE(char* s1, char* s2)

๐Ÿ’… strnEQ ๐Ÿ’…

Test two "NUL"-terminated strings to see if they are equal. The len parameter indicates the number of bytes to compare. Returns true or false. (A wrapper for strncmp, iykyk.)

bool  strnEQ(char* s1, char* s2, STRLEN len)

๐Ÿ’… strnNE ๐Ÿ’…

Test two "NUL"-terminated strings to see if they are different. The len parameter indicates the number of bytes to compare. Returns true or false. (A wrapper for strncmp.)

bool  strnNE(char* s1, char* s2, STRLEN len)

๐ŸŽ€ Zero, ZeroD ๐ŸŽ€

The XSUB-writer's interface to the C memzero function. The dest is the destination, nitems is the number of items, and type is the type. Slay.

ZeroD is like Zero but returns dest. It's lowkey useful for encouraging compilers to tail-call optimise. ๐Ÿ‘‘

void    Zero (void* dest, int nitems, type)
void *  ZeroD(void* dest, int nitems, type)

โœจ SV Flags โœจ

SVt_IV, SVt_NULL, SVt_NV, SVt_PV

Type flag for scalars. See "svtype".

SVt_PVAV

Type flag for arrays. See "svtype".

SVt_PVCV

Type flag for subroutines. See "svtype".

SVt_PVFM

Type flag for formats. See "svtype".

SVt_PVGV

Type flag for typeglobs. See "svtype".

SVt_PVHV

Type flag for hashes. See "svtype".

SVt_PVIO

Type flag for I/O objects. See "svtype".

SVt_PVIV, SVt_PVLV, SVt_PVMG, SVt_PVNV

Type flag for scalars. See "svtype".

SVt_PVOBJ

NOTE: SVt_PVOBJ is experimental and may change or be removed without notice. ๐Ÿ˜ฑ Not a drill, bestie.

Type flag for object instances. See "svtype".

SVt_REGEXP

Type flag for regular expressions. See "svtype".


๐ŸŒˆ svtype ๐ŸŒˆ

An enum of flags for Perl types. These are found in the file sv.h in the svtype enum. Test these flags with the SvTYPE macro. ๐Ÿ’…

The types are:

SVt_NULL
SVt_IV
SVt_NV
SVt_RV
SVt_PV
SVt_PVIV
SVt_PVNV
SVt_PVMG
SVt_INVLIST
SVt_REGEXP
SVt_PVGV
SVt_PVLV
SVt_PVAV
SVt_PVHV
SVt_PVCV
SVt_PVFM
SVt_PVIO
SVt_PVOBJ

These are most easily explained from the bottom up. ๐Ÿซถ

SVt_PVOBJ is for object instances of the new use feature 'class' kind. SVt_PVIO is for I/O objects, SVt_PVFM for formats, SVt_PVCV for subroutines, SVt_PVHV for hashes and SVt_PVAV for arrays.

All the others are scalar types, that is, things that can be bound to a $ variable. For these, the internal types are mostly orthogonal to types in the Perl language.

Hence, checking SvTYPE(sv) < SVt_PVAV is the best way to see whether something is a scalar. ๐Ÿ”ฅ

SVt_PVGV represents a typeglob. If !SvFAKE(sv), then it is a real, incoercible typeglob. If SvFAKE(sv), then it is a scalar to which a typeglob has been assigned. Assigning to it again will stop it from being a typeglob. SVt_PVLV represents a scalar that delegates to another scalar behind the scenes. It is used, e.g., for the return value of substr and for tied hash and array elements. It can hold any scalar value, including a typeglob. SVt_REGEXP is for regular expressions. SVt_INVLIST is for Perl core internal use only.

SVt_PVMG represents a "normal" scalar (not a typeglob, regular expression, or delegate). Since most scalars do not need all the internal fields of a PVMG, we save memory by allocating smaller structs when possible. All the other types are just simpler forms of SVt_PVMG, with fewer internal fields. SVt_NULL can only hold undef. SVt_IV can hold undef, an integer, or a reference. (SVt_RV is an alias for SVt_IV, which exists for backward compatibility.) SVt_NV can hold undef or a double. (In builds that support headless NVs, these could also hold a reference via a suitable offset, in the same way that SVt_IV does, but this is not currently supported and seems to be a rare use case.) SVt_PV can hold undef, a string, or a reference. SVt_PVIV is a superset of SVt_PV and SVt_IV. SVt_PVNV is a superset of SVt_PV and SVt_NV. SVt_PVMG can hold anything SVt_PVNV can hold, but it may also be blessed or magical. โœจ


๐ŸŒธ SV Handling ๐ŸŒธ

AV_FROM_REF, CV_FROM_REF, GV_FROM_REF, HV_FROM_REF

The *V_FROM_REF macros extract the SvRV() from a given reference SV and return a suitably-cast to pointer to the referenced SV. When running under -DDEBUGGING, assertions are also applied that check that ref is definitely a reference SV that refers to an SV of the right type. ๐Ÿ‘‘

AV *  AV_FROM_REF(SV * ref)
CV *  CV_FROM_REF(SV * ref)
GV *  GV_FROM_REF(SV * ref)
HV *  HV_FROM_REF(SV * ref)

BOOL_INTERNALS_sv_isbool

Checks if a SvBoolFlagsOK() sv is a bool. Note that it is the caller's responsibility to ensure that the sv is SvBoolFlagsOK() before calling this. This is only useful in specialized logic like serialization code where performance is critical and the flags have already been checked to be correct. Almost always you should be using sv_isbool(sv) instead. ๐Ÿ’–

bool  BOOL_INTERNALS_sv_isbool(SV* sv)

BOOL_INTERNALS_sv_isbool_false

Checks if a SvBoolFlagsOK() sv is a false bool. Note that it is the caller's responsibility to ensure that the sv is SvBoolFlagsOK() before calling this. This is only useful in specialized logic like serialization code where performance is critical and the flags have already been checked to be correct. This is NOT what you should use to check if an SV is "false", for that you should be using !SvTRUE(sv) instead. ๐Ÿ™ˆ

bool  BOOL_INTERNALS_sv_isbool_false(SV* sv)

BOOL_INTERNALS_sv_isbool_true

Checks if a SvBoolFlagsOK() sv is a true bool. Note that it is the caller's responsibility to ensure that the sv is SvBoolFlagsOK() before calling this. This is only useful in specialized logic like serialization code where performance is critical and the flags have already been checked to be correct. This is NOT what you should use to check if an SV is "true", for that you should be using SvTRUE(sv) instead. ๐Ÿ™ˆ

bool  BOOL_INTERNALS_sv_isbool_true(SV* sv)

๐Ÿ“ boolSV ๐Ÿ“

Returns a true SV if b is a true value, or a false SV if b is 0.

See also "PL_sv_yes" and "PL_sv_no".

SV *  boolSV(bool b)

๐Ÿ’€ croak_xs_usage ๐Ÿ’€

A specialised variant of croak() for emitting the usage message for xsubs

croak_xs_usage(cv, "eee_yow");

works out the package name and subroutine name from cv, and then calls croak(). Hence if cv is &ouch::awk, it would call croak as:

croak("Usage: %" SVf "::%" SVf "(%s)", "ouch", "awk",
                                                    "eee_yow");
void       croak_xs_usage(const CV * const cv,
                          const char * const params)
void  Perl_croak_xs_usage(const CV * const cv,
                          const char * const params)

CV_FROM_REF*

Described under "AV_FROM_REF"


๐Ÿ‘‘ DEFSV ๐Ÿ‘‘

Returns the SV associated with $_

SV *  DEFSV

๐ŸŽ€ DEFSV_set ๐ŸŽ€

Associate sv with $_

void  DEFSV_set(SV * sv)

โญ get_sv โญ

Returns the SV of the specified Perl scalar. flags are passed to "gv_fetchpv". If GV_ADD is set and the Perl variable does not exist then it will be created. If flags is zero and the variable does not exist then NULL is returned.

NOTE: the perl_get_sv() form is deprecated. ๐Ÿ’€ Don't do it, bestie.
SV *       get_sv(      const char *name, I32 flags)
SV *  Perl_get_sv(pTHX_ const char *name, I32 flags)

GV_FROM_REF*, HV_FROM_REF*

Described under "AV_FROM_REF"


๐Ÿฆ‹ isGV_with_GP ๐Ÿฆ‹

Returns a boolean as to whether or not sv is a GV with a pointer to a GP (glob pointer).

bool  isGV_with_GP(SV * sv)

โœจ looks_like_number โœจ

Okay bestie, this one tests if the content of an SV looks like a number (or straight up is one). And here's the tea: Inf and Infinity are treated as numbers (so they will NOT throw a non-numeric warning), even if your atof() genuinely has no idea what they are. Also, get-magic is ignored, so don't come for her.

I32       looks_like_number(      SV * const sv)
I32  Perl_looks_like_number(pTHX_ SV * const sv)

๐Ÿฆ‹ MUTABLE_AV ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_CV ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_GV ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_HV ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_IO ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_PTR ๐Ÿฆ‹

๐Ÿฆ‹ MUTABLE_SV ๐Ÿฆ‹

So these MUTABLE_*() macros cast pointers to the types shown, in such a way (compiler permitting, so it's giving maybe) that casting away const-ness will give you a warning. Like, iykyk:

const SV *sv = ...;
AV *av1 = (AV*)sv;        <== BAD:  the const has been silently
                                    cast away
AV *av2 = MUTABLE_AV(sv); <== GOOD: it may warn

MUTABLE_PTR is the base macro used to derive new casts. The other already-built-in ones just return pointers to what their names indicate. Periodt.

AV *    MUTABLE_AV (AV * p)
CV *    MUTABLE_CV (CV * p)
GV *    MUTABLE_GV (GV * p)
HV *    MUTABLE_HV (HV * p)
IO *    MUTABLE_IO (IO * p)
void *  MUTABLE_PTR(void * p)
SV *    MUTABLE_SV (SV * p)

๐ŸŒธ newRV ๐ŸŒธ

๐ŸŒธ newRV_inc ๐ŸŒธ

These two are literally identical, no cap. They create an RV wrapper for an SV, and the reference count for the original SV gets incremented. ๐Ÿ’–

SV *       newRV    (      SV * const sv)
SV *  Perl_newRV    (pTHX_ SV * const sv)
SV *       newRV_inc(      SV * const sv)

๐ŸŽ€ newRV_noinc ๐ŸŽ€

Creates an RV wrapper for an SV, but this time the reference count for the original SV is not incremented. Different vibe, same wrapper energy.

SV *       newRV_noinc(      SV * const tmpRef)
SV *  Perl_newRV_noinc(pTHX_ SV * const tmpRef)

โœจ newSV โœจ

Creates a new SV, iconic behavior honestly. A non-zero len parameter tells you how many bytes of preallocated string space the SV should have. An extra byte for a trailing NUL is also reserved. Important bestie note: (SvPOK is not set for the SV even if string space is allocated). The reference count for the new SV is set to 1.

So back in 5.9.3 (ancient history), newSV() replaced the older NEWSV() API, and dropped the first parameter, x, which was a debug aid that let callers identify themselves. That little aid has been superseded by a new build option, PERL_MEM_LOG (see PERL_MEM_LOG in perlhacktips). The older API is still there for use in XS modules supporting older perls, so she's retired but not gone. ๐Ÿ‘‘

SV *       newSV(      const STRLEN len)
SV *  Perl_newSV(pTHX_ const STRLEN len)

๐Ÿซถ newSV_false ๐Ÿซถ

Creates a new SV that is a boolean false. That's it, that's the whole mood. ๐Ÿ™ˆ

SV *       newSV_false()
SV *  Perl_newSV_false(pTHX)

๐Ÿ’œ newSV_true ๐Ÿ’œ

Creates a new SV that is a boolean true. Main character energy fr fr.

SV *       newSV_true()
SV *  Perl_newSV_true(pTHX)

๐Ÿ”ฅ newSV_type ๐Ÿ”ฅ

Creates a new SV, of the type specified. The reference count for the new SV is set to 1.

SV *       newSV_type(      const svtype type)
SV *  Perl_newSV_type(pTHX_ const svtype type)

๐ŸŒˆ newSV_type_mortal ๐ŸŒˆ

Creates a new mortal SV, of the type specified. The reference count for the new SV is set to 1.

This one is equivalent to

SV* sv = sv_2mortal(newSV_type(<some type>)) and
SV* sv = sv_newmortal();
sv_upgrade(sv, <some_type>)

but it should be more efficient than both of them. (Unless sv_2mortal is inlined at some point in the future, in which case all bets are off lol.)

SV *       newSV_type_mortal(      const svtype type)
SV *  Perl_newSV_type_mortal(pTHX_ const svtype type)

๐Ÿ“ newSVbool ๐Ÿ“

Creates a new SV boolean.

SV *       newSVbool(      const bool bool_val)
SV *  Perl_newSVbool(pTHX_ const bool bool_val)

๐Ÿฆ‹ newSVhek ๐Ÿฆ‹

Creates a new SV from the hash key structure. It will generate scalars that point to the shared string table where possible. And if hek is NULL, it returns a new (undefined) SV. Simple as.

SV *       newSVhek(      const HEK * const hek)
SV *  Perl_newSVhek(pTHX_ const HEK * const hek)

โœจ newSVhek_mortal โœจ

Creates a new mortal SV from the hash key structure. It will generate scalars that point to the shared string table where possible. Returns a new (undefined) SV if hek is NULL.

And the tea is this is more efficient than using sv_2mortal(newSVhek( ... )). Slay.

SV *       newSVhek_mortal(      const HEK * const hek)
SV *  Perl_newSVhek_mortal(pTHX_ const HEK * const hek)

๐Ÿ’– newSViv ๐Ÿ’–

Creates a new SV and copies an integer into it. The reference count for the SV is set to 1.

SV *       newSViv(      const IV i)
SV *  Perl_newSViv(pTHX_ const IV i)

๐ŸŒธ newSVnv ๐ŸŒธ

Creates a new SV and copies a floating point value into it. The reference count for the SV is set to 1.

SV *       newSVnv(      const NV n)
SV *  Perl_newSVnv(pTHX_ const NV n)

๐Ÿ’€ newSVpadname ๐Ÿ’€

โš ๏ธ NOTE: newSVpadname is experimental and may change or be removed without notice. So like, don't get attached, bestie.

Creates a new SV containing the pad name.

SV*  newSVpadname(PADNAME *pn)

๐ŸŽ€ newSVpv ๐ŸŽ€

Creates a new SV and copies a string (which may contain NUL (\0) characters) into it. The reference count for the SV is set to 1. If len is zero, Perl will compute the length using strlen(), (which means if you use this option, that s can't have embedded NUL characters and has to have a terminating NUL byte).

Okay this is the part where I gotta be real with you: this function can cause reliability issues if you are likely to pass in empty strings that are not NUL terminated, because it will run strlen on the string and potentially run past valid memory. ๐Ÿ˜ญ So like, be careful.

Using newSVpvn is a safer alternative for non NUL terminated strings. For string literals, use newSVpvs instead. This function will work fine for NUL terminated strings, but if you want to avoid the if statement on whether to call strlen, use newSVpvn instead (calling strlen yourself).

SV *       newSVpv(      const char * const s, const STRLEN len)
SV *  Perl_newSVpv(pTHX_ const char * const s, const STRLEN len)

โญ newSVpv_share โญ

Like newSVpvn_share, but takes a NUL-terminated string instead of a string/length pair.

SV *       newSVpv_share(      const char *s, U32 hash)
SV *  Perl_newSVpv_share(pTHX_ const char *s, U32 hash)

๐ŸŒˆ newSVpvf ๐ŸŒˆ

๐ŸŒˆ newSVpvf_nocontext ๐ŸŒˆ

๐ŸŒˆ vnewSVpvf ๐ŸŒˆ

These each create a new SV and initialize it with the string formatted like sv_catpvf.

The tea on the differences: newSVpvf and newSVpvf_nocontext behave identically when called from outside the perl core, unless PERL_WANT_VARARGS has been explicitly #defined. When it has been, or when called from inside the core, they differ only in that newSVpvf requires the thread context (aTHX) to be available.

The arguments to vnewSVpvf are specified as a va_list. The arguments to the remaining forms are specified as a sprintf-style list of arguments.

SV *       newSVpvf          (      const char * const pat, ...)
SV *  Perl_newSVpvf          (pTHX_ const char * const pat, ...)
SV *       newSVpvf_nocontext(      const char * const pat, ...)
SV *  Perl_newSVpvf_nocontext(      const char * const pat, ...)
SV *       vnewSVpvf         (      const char * const pat,
                                    va_list * const args)
SV *  Perl_vnewSVpvf         (pTHX_ const char * const pat,
                                    va_list * const args)

๐Ÿซถ newSVpvn ๐Ÿซถ

Creates a new SV and copies a string into it, which may contain NUL characters (\0) and other binary data. The reference count for the SV is set to 1. Note that if len is zero, Perl will create a zero length (Perl) string. And listen, you are responsible for ensuring that the source buffer is at least len bytes long. If the buffer argument is NULL, the new SV will be undefined.

SV *       newSVpvn(      const char * const s, const STRLEN len)
SV *  Perl_newSVpvn(pTHX_ const char * const s, const STRLEN len)

โœจ newSVpvn_flags โœจ

Creates a new SV and copies a string (which may contain NUL (\0) characters) into it. The reference count for the SV is set to 1. Note that if len is zero, Perl will create a zero length string. You are responsible for ensuring that the source string is at least len bytes long. If the s argument is NULL the new SV will be undefined.

Currently, the only flag bits accepted are SVf_UTF8 and SVs_TEMP. If SVs_TEMP is set, then sv_2mortal() is called on the result before returning. If SVf_UTF8 is set, s is considered to be in UTF-8 and the SVf_UTF8 flag will be set on the new SV.

Oh and newSVpvn_utf8() is a convenience wrapper for this function, defined as:

#define newSVpvn_utf8(s, len, u)                    \
    newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
SV *       newSVpvn_flags(      const char * const s,
                                const STRLEN len,
                                const U32 flags)
SV *  Perl_newSVpvn_flags(pTHX_ const char * const s,
                                const STRLEN len,
                                const U32 flags)

๐Ÿ’œ newSVpvn_share ๐Ÿ’œ

Creates a new SV with its SvPVX_const pointing to a shared string in the string table. If the string does not already exist in the table, it is created first. Turns on the SvIsCOW flag (or READONLY and FAKE in 5.16 and earlier โ€” vintage bestie behavior).

If the hash parameter is non-zero, that value is used; otherwise the hash is computed. The string's hash can later be retrieved from the SV with the SvSHARED_HASH macro. The whole idea here is that as the string table is used for shared hash keys, these strings will have SvPVX_const == HeKEY and hash lookup will avoid string compare. Obsessed with the efficiency ngl. ๐Ÿ”ฅ

SV *       newSVpvn_share(      const char *s, I32 len, U32 hash)
SV *  Perl_newSVpvn_share(pTHX_ const char *s, I32 len, U32 hash)

๐Ÿ“ newSVpvn_utf8 ๐Ÿ“

Creates a new SV and copies a string (which may contain NUL (\0) characters) into it. If utf8 is true, calls SvUTF8_on on the new SV. Implemented as a wrapper around newSVpvn_flags. She's giving โœจconvenientโœจ.

SV*  newSVpvn_utf8(const char* s, STRLEN len, U32 utf8)

๐ŸŒŸ newSVpvs ๐ŸŒŸ

Like newSVpvn, but takes a literal string instead of a string/length pair.

SV*  newSVpvs("literal string")

โญ newSVpvs_flags โญ

Like newSVpvn_flags, but takes a literal string instead of a string/length pair.

SV*  newSVpvs_flags("literal string", U32 flags)
  • newSVpvs_share โ€” it's literally newSVpvn_share but it takes a literal string instead of a string/length pair, and it skips the hash param entirely. ๐Ÿ’ซ
SV*  newSVpvs_share("literal string")
  • newSVpvz โ€” bestie, this one makes a brand new SV initialized with an empty string, just like newSVpvs(""), except it comes with enough room to hold a string of len bytes (plus a trailing NUL) with zero growing needed. The glow-up vs newSV? The string is actually defined and initialized, not just vibing as undef. โœจ

The reference count for the new SV is set to 1.

SV *       newSVpvz(      const STRLEN len)
SV *  Perl_newSVpvz(pTHX_ const STRLEN len)
  • newSVrv โ€” creates a new SV for the existing RV, rv, to point to. If rv isn't an RV, it gets upgraded into one (no choice, it's getting the makeover ๐Ÿ’…). If classname is non-null, then the new SV gets blessed into that package. The new SV comes back to you and its reference count is 1. That refcount 1 is owned by rv. Also peep newRV_inc() and newRV_noinc() if you wanna create a new RV the proper way. ๐ŸŽ€
SV *       newSVrv(      SV * const rv,
                         const char * const classname)
SV *  Perl_newSVrv(pTHX_ SV * const rv,
                         const char * const classname)
  • newSVsv
  • newSVsv_flags
  • newSVsv_nomg โ€” these make a new SV that's an exact duplicate of the original SV (using newSVsv_flags_NN). Iconic copy-paste energy, no notes. ๐Ÿฆ‹

The only diff between them: newSVsv performs 'get' magic; newSVsv_nomg skips any magic entirely; and newSVsv_flags lets you explicitly set a flags parameter.

SV *       newSVsv      (      SV * const old)
SV *  Perl_newSVsv      (pTHX_ SV * const old)
SV *       newSVsv_flags(      SV * const old, I32 flags)
SV *  Perl_newSVsv_flags(pTHX_ SV * const old, I32 flags)
SV *       newSVsv_nomg (      SV * const old)
SV *  Perl_newSVsv_nomg (pTHX_ SV * const old)
  • newSVsv_flags_NN โ€” makes a new SV holding the values of the original SV. ๐ŸŒธ

It does the bulk of the work for newSVsv_flags and sv_mortalcopy_flags. The less common cases get handed off to sv_setsv_flags.

This function accepts the same flags as sv_setsv_flags, with the single addition of SVs_TEMP, which toggles how a freed source SV is treated:

  • Not present: emulate newSVsv_flags by emitting a warning and returning NULL.
  • Present: emulate sv_mortalcopy_flags behaviour: croak().
SV *       newSVsv_flags_NN(      SV * const old, I32 flags)
SV *  Perl_newSVsv_flags_NN(pTHX_ SV * const old, I32 flags)
  • newSVsv_nomg* โ€” described under newSVsv ๐Ÿ‘† (go look, it's right up there).
  • newSVuv โ€” creates a new SV and copies an unsigned integer into it. The reference count for the SV is set to 1. ๐Ÿ’–
SV *       newSVuv(      const UV u)
SV *  Perl_newSVuv(pTHX_ const UV u)
  • Nullsv โ€” a Null SV pointer. (No longer available when PERL_CORE is defined โ€” RIP, she's retired. ๐Ÿ’€)
  • PL_sv_no โ€” this is the false SV. It is readonly. See PL_sv_yes. Always refer to this as &PL_sv_no. ๐Ÿซถ
SV  PL_sv_no
  • PL_sv_undef โ€” this is the undef SV. It is readonly. Always refer to this as &PL_sv_undef.
SV  PL_sv_undef
  • PL_sv_yes โ€” this is the true SV. It is readonly. See PL_sv_no. Always refer to this as &PL_sv_yes. โœจ
SV  PL_sv_yes
  • PL_sv_zero โ€” this readonly SV has a zero numeric value and a "0" string value. It's similar to PL_sv_no except for its string value. Can be used as a cheap alternative to mXPUSHi(0), for example. Always refer to this as &PL_sv_zero. Introduced in 5.28. ๐Ÿ‘‘
SV  PL_sv_zero
  • SAVE_DEFSV โ€” localize $_. See "Localizing changes" in perlguts.
void  SAVE_DEFSV
  • sortsv
  • sortsv_flags โ€” these functions are currently identical. They perform an in-place mergesort of an array of SV pointers base (length nmemb) with the given comparison routine, cmp, which should be declared as SVCOMPARE_t. It gets called like this:
ret = cmp(aTHX_ sv_a, sv_b)
if (ret < 0) {
   // sv_a is first
}
else if (ret > 0) {
   // sv_b is first
}
else {
   // they compare equal
}

flags is currently ignored in sortsv_flags. (Yeah bestie, she's just there for the aesthetic. ๐Ÿ™ˆ)

void       sortsv      (      SV **array, size_t num_elts,
                              SVCOMPARE_t cmp)
void  Perl_sortsv      (pTHX_ SV **array, size_t num_elts,
                              SVCOMPARE_t cmp)
void       sortsv_flags(      SV **array, size_t num_elts,
                              SVCOMPARE_t cmp, U32 flags)
void  Perl_sortsv_flags(pTHX_ SV **array, size_t num_elts,
                              SVCOMPARE_t cmp, U32 flags)
  • SV โ€” described in perlguts. (Go read it, it's giving main character energy. ๐ŸŒˆ)
  • sv_backoff โ€” remove any string offset. You should normally use the SvOOK_off macro wrapper instead. ๐Ÿ’ซ
void       sv_backoff(SV * const sv)
void  Perl_sv_backoff(SV * const sv)
  • sv_bless โ€” blesses an SV into a specified package. The SV must be an RV. The package must be designated by its stash (see gv_stashpv). The reference count of the SV is unaffected. ๐ŸŽ€
SV *       sv_bless(      SV * const sv,
                          NOCHECK HV * const stash)
SV *  Perl_sv_bless(pTHX_ SV * const sv,
                          NOCHECK HV * const stash)
  • sv_catpv
  • sv_catpv_flags
  • sv_catpv_mg
  • sv_catpv_nomg
  • sv_catpvn
  • sv_catpvn_flags
  • sv_catpvn_mg
  • sv_catpvn_nomg
  • sv_catpvn_nomg_maybeutf8
  • sv_catpvs
  • sv_catpvs_flags
  • sv_catpvs_mg
  • sv_catpvs_nomg โ€” every single one of these concatenates a string onto the end of the string that's in dsv. ๐Ÿ’– They differ in how the catenated string is specified and in how they handle magic and UTF-8ness.

In the pvs forms, the catenated string is a C language string literal, enclosed in double quotes.

In the pvn forms, sstr points to the first byte of the string to concatenate, and an extra parameter, len, specifies how many bytes to copy. So sstr may contain embedded-NUL characters. The caller must make sure sstr contains at least len bytes. (No cap, that's on you. ๐Ÿซถ)

In the plain pv forms, the catenated string is a C language NUL-terminated string.

The _mg forms perform both 'get' and 'set' magic on dsv.

The _nomg forms skip all magic.

The other forms perform only 'get' magic.

The _flags forms have an extra parameter, flags, which lets you also override the UTF-8 handling. By supplying the SV_CATBYTES flag, the appended string is interpreted as plain bytes; by supplying instead the SV_CATUTF8 flag, it will be interpreted as UTF-8, and dsv will be upgraded to UTF-8 if necessary.

sv_catpvn_nomg_maybeutf8 has an extra boolean parameter, is_utf8, which if true indicates that sstr is encoded in UTF-8; otherwise not.

For all other forms, the string appended is assumed to be valid UTF-8 if and only if the dsv has the UTF-8 status set. โœจ

void       sv_catpv                (      SV * const dsv,
                                          const char *sstr)
void  Perl_sv_catpv                (pTHX_ SV * const dsv,
                                          const char *sstr)
void       sv_catpv_flags          (      SV * const dsv,
                                          const char *sstr,
                                          const I32 flags)
void  Perl_sv_catpv_flags          (pTHX_ SV * const dsv,
                                          const char *sstr,
                                          const I32 flags)
void       sv_catpv_mg             (     SV * const dsv,
                                         const char * const sstr)
void  Perl_sv_catpv_mg             (pTHX_ SV * const dsv,
                                         const char * const sstr)
void       sv_catpv_nomg           (      SV * const dsv,
                                          const char * sstr
)
void       sv_catpvn               (      SV * const dsv,
                                          const char *sstr,
                                          STRLEN len)
void  Perl_sv_catpvn               (pTHX_ SV * const dsv,
                                          const char *sstr,
                                          STRLEN len)
void       sv_catpvn_flags         (      SV * const dsv,
                                          const char *sstr,
                                          const STRLEN len,
                                          const I32 flags)
void  Perl_sv_catpvn_flags         (pTHX_ SV * const dsv,
                                          const char *sstr,
                                          const STRLEN len,
                                          const I32 flags)
void       sv_catpvn_mg            (      SV * const dsv,
                                          const char *sstr,
                                          STRLEN len)
void  Perl_sv_catpvn_mg            (pTHX_ SV * const dsv,
                                          const char *sstr,
                                          STRLEN len)
void       sv_catpvn_nomg          (      SV * const dsv,
                                          const char * sstr,
                                          const STRLEN len
)
void       sv_catpvn_nomg_maybeutf8(      SV * const dsv,
                                          const char *sstr,
                                          const STRLEN len,
                                          const I32 flags
)
void       sv_catpvs               (      SV * const dsv,
                                          "literal string")
void       sv_catpvs_flags         (      SV * const dsv,
                                          "literal string",
                                          I32 flags)
void       sv_catpvs_mg            (      SV * const dsv,
                                          "literal string")
void       sv_catpvs_nomg          (      SV * const dsv,
                                          "literal string")

โœจ sv_catpvf, sv_catpvf_nocontext, sv_catpvf_mg, sv_catpvf_mg_nocontext, sv_vcatpvf, sv_vcatpvf_mg, sv_vcatpvfn, sv_vcatpvfn_flags โœจ

Okay bestie so these ones all append to sv whatever you get when you format their arguments using pat as the sprintf-like pattern ๐Ÿ’–. They assume pat has the same UTF8ness as sv โ€” and like, that's on you, the caller, to make sure it's true. No pressure or anything ๐Ÿ˜ญ.

If the destination sv isn't already in UTF-8 but the data you're appending contains "wide" characters, then sv gets converted to be UTF-8 ๐Ÿฆ‹. The classic example is the %c format with the code point > 255 (which is a lil glow-up compared to what libc sprintf would do in that situation โœจ). There's more examples further down, keep reading ๐Ÿ‘€.

These forms differ in two things: how their arguments are specified, and how they handle magic ๐Ÿ”ฎ.

sv_vcatpvfn_flags is the most general one, and literally every other form is implemented by eventually calling it. Main character energy, honestly ๐Ÿ‘‘.

It has two sets of argument lists, and only one of them is used in any given call:

  • The first set, args, is a pointer to a va_list of pointers to C strings.
  • If that's NULL, the other list gets used instead โ€” svargs, which is an array of pointers to SV's. And sv_count tells you how many there are in the list.

Check sprintf(3) for the deets on how the formatting actually goes down ๐Ÿ“–. Some platforms support extensions to the standard C99 definition of this function โ€” none of those are supported by Perl, sorry babe ๐Ÿ’€. For example, neither ' (for digit grouping) nor I (for alternate digits) are supported. Period.

Also, argument reordering (you know, format specifiers like %2$d or %*2$d) is only supported when you're using the svargs array of SVs. If arg is not NULL and pat contains the $ reordering specifier, an exception gets raised ๐Ÿšจ.

* maybe_tainted is supposed to be set when running with taint checks enabled, if the results are untrustworthy (usually because of locales or whatever). BUT โ€” and this is so annoying โ€” it's not currently implemented. That argument is not used. Iconic of it to just sit there ๐Ÿ”ฅ.

patlen gives the length in bytes of pat. Currently though, the pattern has to be NUL-terminated anyway. So yeah, do that ๐ŸŒธ.

flags is what you use to specify which magic to handle or to skip, by setting or clearing the SV_GMAGIC and/or SV_SMAGIC flags ๐Ÿ’….

Plain sv_vcatpvfn just calls sv_vcatpvfn_flags while setting both the SV_GMAGIC and SV_SMAGIC flags, so it always handles both set and get magic โœจ.

All the remaining forms handle 'get' magic โ€” and the ones whose name contains _mg additionally handle 'set' magic ๐Ÿช„.

When you're using the svargs array: if any of the SVs in it have their UTF-8 flag set, sv will be converted to be UTF-8 too, as necessary ๐Ÿ’ซ.

None of the remaining forms use the svargs array, which means argument reordering is not possible with them, no cap ๐Ÿ™ˆ. The arguments are generally considered to be the same UTF8ness as the destination sv, though certain Perl extensions to the standard set of %formats can override this (go peek at "Formatted Printing of Strings" in perlguts and the adjacent sections ๐Ÿ‘€).

sv_catpvf and sv_catpvf_nocontext behave identically when called from outside the perl core โ€” unless PERL_WANT_VARARGS has been explicitly #defined. When it has, or when called from inside the core, they differ in exactly one way: sv_catpvf requires the thread context (aTHX) to be available ๐Ÿ˜ค.

sv_catpvf_mg and sv_catpvf_mg_nocontext behave identically when called from outside the perl core โ€” again, unless PERL_WANT_VARARGS has been explicitly #defined. When it has, or when called from inside the core, they differ only in that sv_catpvf_mg requires the thread context (aTHX) to be available ๐Ÿซถ.

The forms whose name contains vcat use a va_list; the other forms use sprintf-style arguments ๐ŸŒˆ.

There are no other differences between the forms. That's it, that's the tea โ˜•.

 void       sv_catpvf             (      SV * const sv,
                                         const char * const pat,
                                         ...)
 void  Perl_sv_catpvf             (pTHX_ SV * const sv,
                                         const char * const pat,
                                         ...)
 void       sv_catpvf_nocontext   (      SV * const sv,
                                         const char * const pat,
                                         ...)
 void  Perl_sv_catpvf_nocontext   (      SV * const sv,
                                         const char * const pat,
                                         ...)
 void       sv_catpvf_mg          (      SV * const sv,
                                         const char * const pat,
                                         ...)
 void  Perl_sv_catpvf_mg          (pTHX_ SV * const sv,
                                         const char * const pat,
                                         ...)
 void       sv_catpvf_mg_nocontext(      SV * const sv,
                                         const char * const pat,
                                         ...)
 void  Perl_sv_catpvf_mg_nocontext(      SV * const sv,
                                         const char * const pat,
                                         ...)
 void       sv_vcatpvf            (      SV * const sv,
                                         const char * const pat,
                                         va_list * const args)
 void  Perl_sv_vcatpvf            (pTHX_ SV * const sv,
                                         const char * const pat,
                                         va_list * const args)
 void       sv_vcatpvf_mg         (      SV * const sv,
                                         const char * const pat,
                                         va_list * const args)
 void  Perl_sv_vcatpvf_mg         (pTHX_ SV * const sv,
                                         const char * const pat,
                                         va_list * const args)
 void       sv_vcatpvfn           (    SV * const sv,
                                       const char * const pat,
                                       const STRLEN patlen,
                                       va_list * const args,
                                       SV ** const svargs,
                                       const Size_t sv_count,
                                       bool * const maybe_tainted)
 void  Perl_sv_vcatpvfn           (pTHX_ SV * const sv,
                                       const char * const pat,
                                       const STRLEN patlen,
                                       va_list * const args,
                                       SV ** const svargs,
                                       const Size_t sv_count,
                                       bool * const maybe_tainted)
 void       sv_vcatpvfn_flags     (    SV * const sv,
                                       const char * const pat,
                                       const STRLEN patlen,
                                       va_list * const args,
                                       SV ** const svargs,
                                       const Size_t sv_count,
                                       bool * const maybe_tainted,
                                       const U32 flags)
 void  Perl_sv_vcatpvfn_flags     (pTHX_ SV * const sv,
                                       const char * const pat,
                                       const STRLEN patlen,
                                       va_list * const args,
                                       SV ** const svargs,
                                       const Size_t sv_count,
                                       bool * const maybe_tainted,
                                       const U32 flags)

๐ŸŒธ sv_catpvn*, sv_catpvn_flags*, sv_catpvn_mg*, sv_catpvn_nomg*, sv_catpvn_nomg_maybeutf8*, sv_catpvs*, sv_catpvs_flags*, sv_catpvs_mg*, sv_catpvs_nomg* ๐ŸŒธ

Described under sv_catpv ๐Ÿ’– (go scroll, bestie).


๐Ÿฆ‹ sv_catsv, sv_catsv_flags, sv_catsv_mg, sv_catsv_nomg ๐Ÿฆ‹

These concatenate the string from SV sstr onto the end of the string in SV dsv โœจ. If sstr is null, these are total no-ops; otherwise, only dsv gets modified. Only one of them changes, promise ๐Ÿซถ.

They differ only in what magic they perform:

  • sv_catsv_mg performs 'get' magic on both SVs before the copy, and 'set' magic on dsv afterwards ๐Ÿ’…
  • sv_catsv performs just 'get' magic, on both SVs ๐ŸŒŸ
  • sv_catsv_nomg skips all magic entirely, unbothered, moisturized, in its lane ๐Ÿ˜Œ
  • sv_catsv_flags has an extra flags parameter which lets you use SV_GMAGIC and/or SV_SMAGIC to specify any combination of magic handling โ€” though it's either both or neither SV that gets 'get' magic applied to it, so pick your fighter wisely ๐ŸŽ€

sv_catsv, sv_catsv_mg, and sv_catsv_nomg are all implemented in terms of sv_catsv_flags ๐Ÿ‘‘

 void       sv_catsv      (      SV * const dsv, SV * const sstr)
 void  Perl_sv_catsv      (pTHX_ SV * const dsv, SV * const sstr)
 void       sv_catsv_flags(      SV * const dsv, SV * const sstr,
                                 const I32 flags)
 void  Perl_sv_catsv_flags(pTHX_ SV * const dsv, SV * const sstr,
                                 const I32 flags)
 void       sv_catsv_mg   (      SV * const dsv, SV * const sstr)
 void  Perl_sv_catsv_mg   (pTHX_ SV * const dsv, SV * const sstr)
 void       sv_catsv_nomg (      SV * const dsv, SV * const sstr)

๐Ÿ’œ SV_CHECK_THINKFIRST ๐Ÿ’œ

This one removes any encumbrances from sv that need to be dealt with before it becomes modifiable ๐Ÿ”ง. Like, for example, if it's Copy on Write (COW), now is the time to actually make that copy ๐Ÿ„.

But โ€” listen โ€” if you already know you're about to change the PV value of sv, use "SV_CHECK_THINKFIRST_COW_DROP" instead, so you avoid the write that would just get immediately written again. Don't waste the effort, bestie ๐Ÿ’….

 void  SV_CHECK_THINKFIRST(SV * sv)

๐ŸŒŸ SV_CHECK_THINKFIRST_COW_DROP ๐ŸŒŸ

Call this one when you're about to replace the PV value in sv, which is potentially copy-on-write ๐Ÿ‘€. It stops any sharing with other SVs, so that no Copy on Write (COW) actually happens. That COW would be completely useless anyway, since it would immediately get changed to something else. Wasted effort, we don't do that here ๐Ÿ™….

This function also removes any other encumbrances that would be problematic when changing sv โœจ. Two birds, one function ๐Ÿฆ‹.

 void  SV_CHECK_THINKFIRST_COW_DROP(SV * sv)

โœจ sv_chop

Ok so this one is the ~efficient~ way to yeet characters off the beginning of a string buffer ๐Ÿ’…. SvPOK(sv), or at least SvPOKp(sv), has to be true, and ptr must point to somewhere inside the string buffer. After the call, ptr becomes the first character of the adjusted string. It uses the OOK hack, bestie. On return, only SvPOK(sv) and SvPOKp(sv) among the OK flags will be true.

โš ๏ธ Beware fr fr: after this function returns, ptr and SvPVX_const(sv) may no longer refer to the same chunk of data. ๐Ÿ˜ญ

The unfortunate similarity of this function's name to that of Perl's chop operator is strictly coincidental. This function works from the left; chop works from the right. Two different queens, two different directions ๐Ÿ‘‘

 void       sv_chop(      SV * const sv, const char * const ptr)
 void  Perl_sv_chop(pTHX_ SV * const sv, const char * const ptr)

โœจ sv_clear

Clears an SV: calls any destructors, frees up any memory used by the body, and frees the body itself ๐Ÿงนโœจ. The SV's head is not freed, although its type is set to all 1's so that it won't inadvertently be assumed to be live during global destruction etc. Only call this when REFCNT is zero, okay? Most of the time you'll want to call SvREFCNT_dec instead. Like, respectfully, use the right tool ๐Ÿ’€

 void       sv_clear(      SV * const orig_sv)
 void  Perl_sv_clear(pTHX_ SV * const orig_sv)

โœจ sv_cmp and sv_cmp_flags

Both of these compare the strings in two SVs and return -1, 0, or 1 โ€” telling you whether the string in sv1 is less than, equal to, or greater than the string in sv2 ๐Ÿซถ. They're UTF-8 and 'use bytes' aware, and will coerce their arguments to strings if necessary. So dramatic of them but okay.

sv_cmp always handles 'get' magic. sv_cmp_flags only does so if flags contains SV_GMAGIC. Otherwise, the two forms behave identically. Two peas, one pod ๐Ÿ’–

See also sv_cmp_locale.

 I32       sv_cmp      (      SV * const sv1, SV * const sv2)
 I32  Perl_sv_cmp      (pTHX_ SV * const sv1, SV * const sv2)
 I32       sv_cmp_flags(      SV * const sv1, SV * const sv2,
                              const U32 flags)
 I32  Perl_sv_cmp_flags(pTHX_ SV * const sv1, SV * const sv2,
                              const U32 flags)

โœจ sv_cmp_locale and sv_cmp_locale_flags

Same energy as the last ones but make it locale-aware ๐ŸŒโœจ. Each compares the strings in two SVs in a locale-aware manner, returning -1, 0, or 1 depending on whether the string in sv1 is less than, equal to, or greater than the string in sv2.

They're UTF-8 and 'use bytes' aware, and will coerce their args to strings if necessary, no cap.

sv_cmp_locale always handles 'get' magic. sv_cmp_locale_flags only does so if flags contains SV_GMAGIC. Otherwise the two forms behave identically. Same rule as always, bestie ๐Ÿ’…

See also sv_cmp.

 I32       sv_cmp_locale      (      SV * const sv1,
                                     SV * const sv2)
 I32  Perl_sv_cmp_locale      (pTHX_ SV * const sv1,
                                     SV * const sv2)
 I32       sv_cmp_locale_flags(      SV * const sv1,
                                     SV * const sv2,
                                     const U32 flags)
 I32  Perl_sv_cmp_locale_flags(pTHX_ SV * const sv1,
                                     SV * const sv2,
                                     const U32 flags)

โœจ sv_collxfrm and sv_collxfrm_flags

These each add Collate Transform magic to an SV if it doesn't already have it ๐Ÿ”ฎโœจ.

Any scalar variable may carry PERL_MAGIC_collxfrm magic that contains the scalar data of the variable, but transformed to such a format that a normal memory comparison can be used to compare the data according to the locale settings. It's giving "glow up your scalars so memcmp can vibe with locale rules" ๐Ÿ’…

sv_collxfrm always handles 'get' magic. sv_collxfrm_flags only does so if flags contains SV_GMAGIC. Otherwise, the two forms behave identically. You know the drill by now ๐ŸŽ€

 char *       sv_collxfrm      (      SV * const sv,
                                      STRLEN * const nxp)
 char *  Perl_sv_collxfrm      (pTHX_ SV * const sv,
                                      STRLEN * const nxp)
 char *       sv_collxfrm_flags(      SV * const sv,
                                      STRLEN * const nxp,
                                      I32 const flags)
 char *  Perl_sv_collxfrm_flags(pTHX_ SV * const sv,
                                      STRLEN * const nxp,
                                      I32 const flags)

โœจ sv_copypv, sv_copypv_flags, and sv_copypv_nomg

These copy a stringified representation of the source SV into the destination SV ๐Ÿ“‹โœจ. They automatically perform coercion of numeric values into strings, so no manual labor required. Guaranteed to preserve the UTF8 flag even from overloaded objects โ€” iconic behavior honestly ๐Ÿ‘‘

Similar in nature to sv_2pv[_flags] but they operate directly on an SV instead of just the string. Mostly they use "sv_2pv_flags" to do the work, except when that would lose the UTF-8'ness of the PV. Can't be losing the UTF-8'ness, that's a crime ๐Ÿ˜ค

The three forms differ only in whether or not they perform 'get magic' on sv:

  • sv_copypv_nomg skips 'get magic'
  • sv_copypv performs it
  • sv_copypv_flags either performs it (if the SV_GMAGIC bit is set in flags) or doesn't (if that bit is cleared)
 void       sv_copypv      (      SV * const dsv, SV * const ssv)
 void  Perl_sv_copypv      (pTHX_ SV * const dsv, SV * const ssv)
 void       sv_copypv_flags(      SV * const dsv, SV * const ssv,
                                  const I32 flags)
 void  Perl_sv_copypv_flags(pTHX_ SV * const dsv, SV * const ssv,
                                  const I32 flags)
 void       sv_copypv_nomg (      SV * const dsv, SV * const ssv)
 void  Perl_sv_copypv_nomg (pTHX_ SV * const dsv, SV * const ssv)

โœจ sv_dec and sv_dec_nomg

These auto-decrement the value in the SV, doing string to numeric conversion if necessary ๐Ÿ“‰. They both handle operator overloading, so your fancy overloaded objects don't get left out ๐Ÿซถ

They differ only in that:

  • sv_dec handles 'get' magic
  • sv_dec_nomg skips 'get' magic
 void       sv_dec     (      SV * const sv)
 void  Perl_sv_dec     (pTHX_ SV * const sv)
 void       sv_dec_nomg(      SV * const sv)
 void  Perl_sv_dec_nomg(pTHX_ SV * const sv)

โœจ sv_derived_from, sv_derived_from_hv, sv_derived_from_pv, sv_derived_from_pvn, sv_derived_from_sv

These each return a boolean indicating whether sv is derived from the specified class at the C level ๐Ÿ’…. To check derivation at the Perl level, just call isa() as a normal Perl method. C level vs Perl level, two different arenas bestie.

The differences between the forms is how the class is specified, and the UTF-8ness of its name. Let's break it down:

  • In sv_derived_from_sv, the class name is extracted from namesv using some version of "SvPV". This is the preferred form ๐Ÿ‘‘. The class name is considered to be in UTF-8 iff namesv is marked as such, hence flags is effectively currently ignored.
  • In sv_derived_from_hv, the class name is HvNAME(hv) (which would presumably represent a stash). Its UTF8ness is HvNAMEUTF8(hv).
  • In the remaining forms, the class name is specified by the name parameter. In sv_derived_from and sv_derived_from_pv, it is a NUL-terminated C string. In sv_derived_from_pvn, name points to the first byte of the string specifying the class, and an additional parameter, len, specifies its length in bytes. Hence, name may contain embedded-NUL characters ๐Ÿ‘€.

name is never considered to be encoded as UTF-8 in sv_derived_from. The remaining forms have a flags parameter. If the SVf_UTF8 is set in it, the class name is encoded as UTF-8; otherwise not. No other flags are currently meaningful, so don't get creative.

 bool       sv_derived_from    (      SV *sv,
                                      const char * const name)
 bool  Perl_sv_derived_from    (pTHX_ SV *sv,
                                      const char * const name)
 bool       sv_derived_from_hv (      SV *sv, HV *hv)
 bool  Perl_sv_derived_from_hv (pTHX_ SV *sv, HV *hv)
 bool       sv_derived_from_pv (      SV *sv,
                                      const char * const name,
                                      U32 flags)
 bool  Perl_sv_derived_from_pv (pTHX_ SV *sv,
                                      const char * const name,
                                      U32 flags)
 bool       sv_derived_from_pvn(      SV *sv,
                                      const char * const name,
                                      const STRLEN len, U32 flags)
 bool  Perl_sv_derived_from_pvn(pTHX_ SV *sv,
                                      const char * const name,
                                      const STRLEN len, U32 flags)
 bool       sv_derived_from_sv (      SV *sv, SV *namesv,
                                      U32 flags)
 bool  Perl_sv_derived_from_sv (pTHX_ SV *sv, SV *namesv,
                                      U32 flags)

โœจ sv_does, sv_does_pv, sv_does_pvn, sv_does_sv

These each return a boolean indicating whether sv performs a specific, named role ๐ŸŽญโœจ. So like, not what class it is, but what part it plays. Main character energy check.

sv can be a Perl object or the name of a Perl class.

The forms differ in how the role is specified:

  • In sv_does and sv_does_pv, the role is in name, which is a NUL-terminated string, which means that it may not contain embedded NUL characters ๐Ÿšซ
  • In sv_does_pvn, the role is in name whose length is given by len. Hence it may contain embedded NUL characters โœจ
  • In sv_does_sv, the role is extracted from namesv. Its flags argument is currently ignored.

You can pass SVf_UTF8 to the other functions that have a flags argument to indicate that name is encoded as UTF-8. sv_does does not have a flags argument, so its role is never considered to be UTF-8. Sorry to that one function ๐Ÿ˜ญ

 bool       sv_does    (      SV *sv, const char * const name)
 bool  Perl_sv_does    (pTHX_ SV *sv, const char * const name)
 bool       sv_does_pv (      SV *sv, const char * const name,
                              U32 flags)
 bool  Perl_sv_does_pv (pTHX_ SV *sv, const char * const name,
                              U32 flags)
 bool       sv_does_pvn(      SV *sv, const char * const name,
                              const STRLEN len, U32 flags)
 bool  Perl_sv_does_pvn(pTHX_ SV *sv, const char * const name,
                              const STRLEN len, U32 flags)
 bool       sv_does_sv (      SV *sv, SV *namesv, U32 flags)
 bool  Perl_sv_does_sv (pTHX_ SV *sv, SV *namesv, U32 flags)

sv_eq, sv_eq_flags, sv_streq, sv_streq_flags ๐Ÿ’–

Okay so these four besties all return a boolean that says whether the strings inside two SVs are equal, and they'll coerce the SV args to strings if they gotta. If use bytes is active, the comparison is byte-by-byte; otherwise it's character-by-character. Slay.

sv_eq and sv_streq always do 'get' magic; they're basically living the Perl code $sv1 eq $sv2 life. The other two only do 'get' magic when the flags parameter has the SV_GMAGIC bit set. Periodt.

Now the differences between the streq forms and the plain eq forms? Let's get into it:

  • Overloading โ€” The plain eq forms do not handle overloading. The streq forms check for and handle eq overloading, unless you're calling sv_streq_flags with the SV_SKIP_OVERLOAD bit set in flags. If that overloading doesn't exist or the flag is set, then regular string comparison happens instead, just like the plain eq forms. No cap.
  • Treatment of a NULL SV parameter โ€” The plain eq forms treat each NULL SV parameter as a zero length string; the streq forms treat them as undef. ๐Ÿ’€

Then the signatures, exactly:

I32        sv_eq         (      SV *sv1, SV *sv2)
I32   Perl_sv_eq         (pTHX_ SV *sv1, SV *sv2)
I32        sv_eq_flags   (      SV *sv1, SV *sv2,
                                const U32 flags)
I32   Perl_sv_eq_flags   (pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_streq      (      SV *sv1, SV *sv2)
bool  Perl_sv_streq      (pTHX_ SV *sv1, SV *sv2)
bool       sv_streq_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_streq_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)

sv_force_normal, sv_force_normal_flags ๐Ÿฆ‹

These two undo various types of fakery on an SV, where "fakery" means it's "more than" just a string. It's giving cleanup era. Here's what they handle:

  • If the PV is a shared string โ†’ make a private copy.
  • If we're a ref โ†’ stop refing. This is done by calling sv_unref_flags. In sv_force_normal_flags, the flags parameter gets passed to that function.
  • If we're a glob โ†’ downgrade to an xpvmg.
  • If we're a copy-on-write scalar โ†’ this is the on-write time when we do the copy, and is also used locally.
  • If this is a vstring โ†’ drop the vstring magic.
  • In sv_force_normal_flags, if SV_COW_DROP_PV is set in flags โ†’ a copy-on-write scalar drops its PV buffer (if any) and becomes SvPOK_off rather than making a copy. (Used where this scalar is about to be set to some other value.) ๐Ÿ‘‘

Other than what was mentioned above, the two forms behave identically. That's because sv_force_normal merely calls sv_force_normal_flags with flags set to 0. So iconic.

Signatures:

void       sv_force_normal      (      SV *sv)
void  Perl_sv_force_normal      (pTHX_ SV *sv)
void       sv_force_normal_flags(      SV * const sv,
                                       const U32 flags)
void  Perl_sv_force_normal_flags(pTHX_ SV * const sv,
                                       const U32 flags)

sv_free ๐Ÿ’…

This one decrements an SV's reference count. If it drops to zero, it calls sv_clear to invoke destructors and free up any memory used by the body; finally, it deallocates the SV's head itself. Normally you'd call it via the wrapper macro SvREFCNT_dec. It's giving self-care but for memory.

Signatures:

void       sv_free(      SV * const sv)
void  Perl_sv_free(pTHX_ SV * const sv)

sv_get_backrefs ๐ŸŽ€

NOTE: sv_get_backrefs is experimental and may change or be removed without notice. So don't get too attached, bestie. ๐Ÿ™ˆ

If sv is the target of a weak reference, then it returns the back references structure associated with the sv; otherwise it returns NULL.

When returning a non-null result, the type of the return is relevant. If it's an AV, then the elements of the AV are the weak reference RVs which point at this item. If it's any other type, then the item itself is the weak reference.

See also Perl_sv_add_backref(), Perl_sv_del_backref(), Perl_sv_kill_backrefs().

Signatures:

SV *       sv_get_backrefs(SV * const sv)
SV *  Perl_sv_get_backrefs(SV * const sv)

sv_gets ๐ŸŒธ

Get a line from the filehandle and store it into the SV, optionally appending to the currently-stored string. If append is not 0, the line is appended to the SV instead of overwriting it. append should be set to the byte offset that the appended string should start at in the SV (typically, SvCUR(sv) is a suitable choice). Slay.

Signatures:

char *       sv_gets(      SV * const sv, PerlIO * const fp,
                           SSize_t append)
char *  Perl_sv_gets(pTHX_ SV * const sv, PerlIO * const fp,
                           SSize_t append)

sv_inc, sv_inc_nomg โœจ

These auto-increment the value in the SV, doing string to numeric conversion if necessary. They both handle operator overloading. Iconic.

They differ only in that sv_inc performs 'get' magic; sv_inc_nomg skips any magic. Lowkey the same but highkey different.

Signatures:

void       sv_inc     (      SV * const sv)
void  Perl_sv_inc     (pTHX_ SV * const sv)
void       sv_inc_nomg(      SV * const sv)
void  Perl_sv_inc_nomg(pTHX_ SV * const sv)

sv_insert, sv_insert_flags ๐Ÿ’œ

These insert and/or replace a string at the specified offset/length within the SV. Similar to the Perl substr() function, with littlelen bytes starting at little replacing len bytes of the string in bigstr starting at offset. They handle get magic.

sv_insert_flags is identical to plain sv_insert, but the extra flags are passed to the SvPV_force_flags operation that is internally applied to bigstr.

Signatures:

void       sv_insert      (      SV * const bigstr,
                                 const STRLEN offset,
                                 const STRLEN len,
                                 const char * const little,
                                 const STRLEN littlelen)
void  Perl_sv_insert      (pTHX_ SV * const bigstr,
                                 const STRLEN offset,
                                 const STRLEN len,
                                 const char * const little,
                                 const STRLEN littlelen)
void       sv_insert_flags(      SV * const bigstr,
                                 const STRLEN offset,
                                 const STRLEN len,
                                 const char *little,
                                 const STRLEN littlelen,
                                 const U32 flags)
void  Perl_sv_insert_flags(pTHX_ SV * const bigstr,
                                 const STRLEN offset,
                                 const STRLEN len,
                                 const char *little,
                                 const STRLEN littlelen,
                                 const U32 flags)

sv_isa ๐Ÿฆ‹

Returns a boolean indicating whether the SV is blessed into the specified class.

This does not check for subtypes or method overloading. Use sv_isa_sv to verify an inheritance relationship in the same way as the isa operator by respecting any isa() method overloading; or sv_derived_from_sv to test directly on the actual object type. So don't get it twisted.

Signatures:

int       sv_isa(      SV *sv, const char * const name)
int  Perl_sv_isa(pTHX_ SV *sv, const char * const name)

sv_isa_sv ๐Ÿ‘‘

Returns a boolean indicating whether the SV is an object reference and is derived from the specified class, respecting any isa() method overloading it may have. Returns false if sv is not a reference to an object, or is not derived from the specified class.

This is the function used to implement the behaviour of the isa operator. Main character energy.

Does not invoke magic on sv.

Not to be confused with the older sv_isa function, which does not use an overloaded isa() method, nor will check subclassing. They're different, bestie.

Signatures:

bool       sv_isa_sv(      SV *sv, SV *namesv)
bool  Perl_sv_isa_sv(pTHX_ SV *sv, SV *namesv)

sv_isobject ๐Ÿ’–

Returns a boolean indicating whether the SV is an RV pointing to a blessed object. If the SV is not an RV, or if the object is not blessed, then this will return false. Simple as that.

Signatures:

int       sv_isobject(      SV *sv)
int  Perl_sv_isobject(pTHX_ SV *sv)

sv_len โœจ

Returns the length of the string in the SV. Handles magic and type coercion and sets the UTF8 flag appropriately. See also SvCUR, which gives raw access to the xpv_cur slot. It's giving precise.

Signatures:

STRLEN       sv_len(      SV * const sv)
STRLEN  Perl_sv_len(pTHX_ SV * const sv)

sv_len_utf8, sv_len_utf8_nomg ๐ŸŒˆ

These return the number of characters in the string in an SV, counting wide UTF-8 bytes as a single character. Both handle type coercion. They differ only in that sv_len_utf8 performs 'get' magic; sv_len_utf8_nomg skips any magic. So if you're feeling magical, pick the first one.

Signatures:

STRLEN       sv_len_utf8     (      SV * const sv)
STRLEN  Perl_sv_len_utf8     (pTHX_ SV * const sv)
STRLEN       sv_len_utf8_nomg(      SV * const sv)
STRLEN  Perl_sv_len_utf8_nomg(pTHX_ SV * const sv)

sv_magic ๐ŸŽ€

Adds magic to an SV. First upgrades sv to type SVt_PVMG if necessary, then adds a new magic item of type how to the head of the magic list. It's giving wizardry.

See sv_magicext (which sv_magic now calls) for a description of the handling of the name and namlen arguments.

You need to use sv_magicext to add magic to SvREADONLY SVs and also to add more than one instance of the same how. So know the difference.

Signatures:

void       sv_magic(      SV * const sv, SV * const obj,
                          const int how, const char * const name,
                          const I32 namlen)
void  Perl_sv_magic(pTHX_ SV * const sv, SV * const obj,
                          const int how, const char * const name,
                          const I32 namlen)

sv_magicext ๐Ÿ’œ

Adds magic to an SV, upgrading it if necessary. Applies the supplied vtable and returns a pointer to the magic added. Obsessed.

Note that sv_magicext will allow things that sv_magic will not. In particular, you can add magic to SvREADONLY SVs, and add more than one instance of the same how. So it's the more flexible one.

okay so if namlen is bigger than zero bestie, then a whole savepvn copy of name gets stored โ€” like, a real duplicate, no shortcuts. But if namlen is zero? Then name is just stored as-is, no copy, we're keeping the vibe. And here's the โœจspecial caseโœจ โ€” if (name && namlen == HEf_SVKEY) then name is assumed to contain an SV* and gets stored as-is too, except its REFCNT gets incremented. Gotta keep that refcount fed fr fr.

(This is now used as a subroutine by sv_magic.)
MAGIC *       sv_magicext(      SV * const sv, SV * const obj,
                                const int how,
                                const MGVTBL * const vtbl,
                                const char * const name,
                                const I32 namlen)
MAGIC *  Perl_sv_magicext(pTHX_ SV * const sv, SV * const obj,
                                const int how,
                                const MGVTBL * const vtbl,
                                const char * const name,
                                const I32 namlen)

๐ŸŒธ sv_mortalcopy ๐ŸŒธ

๐Ÿฆ‹ sv_mortalcopy_flags ๐Ÿฆ‹

Both of these make a brand new SV that's a copy of the original one โ€” using newSVsv_flags_NN, no cap. That new SV gets marked as mortal, which honestly is giving tragic-inevitable. It's gonna get destroyed "soon" ๐Ÿ˜ญ โ€” either because somebody explicitly called FREETMPS, or because an implicit call happened at some place like a statement boundary. sv_newmortal and sv_2mortal are also out here doing the same energy, go look at them too.

The two forms are literally identical, EXCEPT sv_mortalcopy_flags has an extra flags parameter, and whatever's in it just gets passed along to sv_setsv_flags. That's it, that's the whole difference. ๐Ÿ’…

SV *       sv_mortalcopy      (      SV * const oldsv)
SV *  Perl_sv_mortalcopy      (pTHX_ SV * const oldsv)
SV *       sv_mortalcopy_flags(      SV * const oldsv, U32 flags)
SV *  Perl_sv_mortalcopy_flags(pTHX_ SV * const oldsv, U32 flags)

๐Ÿ‘‘ sv_newmortal ๐Ÿ‘‘

Creates a fresh new null SV that is mortal. The reference count of the SV gets set to 1. And yup, you guessed it โ€” it will be destroyed "soon" as well, either by an explicit FREETMPS call or by an implicit one at places like statement boundaries. Same deal as always. See also sv_mortalcopy and sv_2mortal, they're all in this together fr.

SV *       sv_newmortal()
SV *  Perl_sv_newmortal(pTHX)

โญ sv_numcmp โญ

๐Ÿ’ซ sv_numcmp_flags ๐Ÿ’ซ

This one hands you back an integer telling you the ordering of the two SV arguments, coercing them to numbers if it has to โ€” basically it's behaving like the Perl code "$sv1 <=" $sv2 >. Yeah.

A NULL SV is treated as undef, periodt.

You're gonna get back one of these:

  • 1 โ€” sv2 is numerically greater than sv1
  • 0 โ€” sv1 and sv2 are numerically equal
  • -1 โ€” sv2 is numerically less than sv1
  • 2 โ€” sv1 and sv2 are not numerically comparable, probably because one of them is NaN, though overloads can extend that whole situation

sv_numcmp always performs 'get' magic, always.

sv_numcmp_flags accepts these flags:

  • SV_GMAGIC โ€” Perform 'get' magic on both sv1 amd sv2 if this flag is set, otherwise 'get' magic is ignored.
  • SV_SKIP_OVERLOAD โ€” If this is set, any <=> or numeric overloading implemented for this type is ignored. โš ๏ธ Be aware that for overloaded values this will compare the addresses of the references, exactly like the usual numeric comparison of non-overloaded references does.
  • SV_FORCE_OVERLOAD โ€” Force overloading on, even in the context of no overloading;.

If neither overload flag is set, overloading is honored โ€” unless no overloading; has disabled it. Simple as that bestie.

I32       sv_numcmp      (      SV *sv1, SV *sv2)
I32  Perl_sv_numcmp      (pTHX_ SV *sv1, SV *sv2)
I32       sv_numcmp_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
I32  Perl_sv_numcmp_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)

๐ŸŒˆ sv_numeq ๐ŸŒˆ

๐ŸŒˆ sv_numeq_flags ๐ŸŒˆ

๐ŸŒˆ sv_numne ๐ŸŒˆ

๐ŸŒˆ sv_numne_flags ๐ŸŒˆ

๐ŸŒˆ sv_numge ๐ŸŒˆ

๐ŸŒˆ sv_numge_flags ๐ŸŒˆ

๐ŸŒˆ sv_numgt ๐ŸŒˆ

๐ŸŒˆ sv_numgt_flags ๐ŸŒˆ

๐ŸŒˆ sv_numle ๐ŸŒˆ

๐ŸŒˆ sv_numle_flags ๐ŸŒˆ

๐ŸŒˆ sv_numlt ๐ŸŒˆ

๐ŸŒˆ sv_numlt_flags ๐ŸŒˆ

Okay so these all return a boolean that's the result of the matching numeric comparison. Let me break it down for you:

  • sv_numeq, sv_numeq_flags โ€” numeric equality, literally the same as $sv1 == $sv2.
  • sv_numne, sv_numne_flags โ€” numeric inequality, same as $sv1 != $sv2.
  • sv_numle, sv_numle_flags โ€” numeric less than or equal, same as $sv1 <= $sv2.
  • sv_numlt, sv_numlt_flags โ€” numeric less than, same as $sv1 < $sv2.
  • sv_numge, sv_numge_flags โ€” numeric greater than or equal, same as $sv1 >= $sv2.
  • sv_numgt, sv_numgt_flags โ€” numeric greater than, same as $sv1 > $sv2.
๐Ÿšจ Beware that when overloading is in the picture, the comparisons might not have their normal properties. Like, sv_numeq(sv1, sv2) might come out different from !sv_numne(sv1, sv2). Yeah. That's just how it is. ๐Ÿ˜ญ

The versions of these functions without the _flags suffix always perform get magic and handle the appropriate type of overloading. Peep overload for the details. And be aware that, just like the builtin operators, no overloading; will disable overloading.

Each of these returns a boolean saying whether the numbers in the two SV arguments satisfy the given relationship, coercing them to numbers if necessary โ€” basically behaving like the Perl code. ๐Ÿ’…

A NULL SV is treated as undef.

The _flags variants of these functions accept these flags:

  • SV_GMAGIC โ€” Perform 'get' magic on both sv1 amd sv2 if this flag is set, otherwise 'get' magic is ignored.
  • SV_SKIP_OVERLOAD โ€” Skip any operator or numeric overloading implemented for this type and operator. โš ๏ธ Be aware that for overloaded values this will compare the addresses of the references, exactly like the usual numeric comparison of non-overloaded references.
  • SV_FORCE_OVERLOAD โ€” Force overloading on even in the context of no overloading;.

If neither overload flag is set, overloading is honored unless no overloading; has disabled it. Same rules as before, no surprises. โœจ

bool       sv_numeq      (      SV *sv1, SV *sv2)
bool  Perl_sv_numeq      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numeq_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numeq_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_numne      (      SV *sv1, SV *sv2)
bool  Perl_sv_numne      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numne_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numne_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_numge      (      SV *sv1, SV *sv2)
bool  Perl_sv_numge      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numge_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numge_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_numgt      (      SV *sv1, SV *sv2)
bool  Perl_sv_numgt      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numgt_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numgt_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_numle      (      SV *sv1, SV *sv2)
bool  Perl_sv_numle      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numle_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numle_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)
bool       sv_numlt      (      SV *sv1, SV *sv2)
bool  Perl_sv_numlt      (pTHX_ SV *sv1, SV *sv2)
bool       sv_numlt_flags(      SV *sv1, SV *sv2,
                                const U32 flags)
bool  Perl_sv_numlt_flags(pTHX_ SV *sv1, SV *sv2,
                                const U32 flags)

๐ŸŽ€ sv_pos_b2u ๐ŸŽ€

๐ŸŽ€ sv_pos_b2u_flags ๐ŸŽ€

These two each count the number of UTF-8 encoded characters in the PV of sv. And no, they don't necessarily look at the entire PV โ€” just the first so-many bytes. The byte count is given by *offsetp in sv_pos_b2u, and by offset in sv_pos_b2u_flags.

โš ๏ธ The caller must ensure that the PV contains at least as many bytes as the count that got passed in. Don't be out here under-feeding it bestie.

sv_pos_b2u returns void โ€” instead it updates *offsetp to the character count. sv_pos_b2u_flags just returns the character count directly.

โœจ sv_pos_b2u_flags is preferred, because offsetp is a *I32, which caps how big a thing it can handle at 2Gb. Iconic limitation honestly.

Both of them handle type coercion.

sv_pos_b2u always handles 'get' magic. sv_pos_b2u_flags only handles 'get' magic when flags contains SV_GMAGIC.

And actually, sv_pos_b2u_flags passes flags to SvPV_flags, and flags usually should be SV_GMAGIC|SV_CONST_RETURN. Meanwhile sv_pos_b2u automatically causes SV_CONST_RETURN to get passed to SvPV_flags for you. ๐Ÿซถ

Both functions use and update PERL_MAGIC_utf8.

void         sv_pos_b2u      (      SV * const sv,
                                    I32 * const offsetp)
void    Perl_sv_pos_b2u      (pTHX_ SV * const sv,
                                    I32 * const offsetp)
STRLEN       sv_pos_b2u_flags(      SV * const sv,
                                    STRLEN const offset,
                                    U32 flags)
STRLEN  Perl_sv_pos_b2u_flags(pTHX_ SV * const sv,
                                    STRLEN const offset,
                                    U32 flags)

๐ŸŒธ sv_pos_u2b ๐ŸŒธ

๐ŸŒธ sv_pos_u2b_flags ๐ŸŒธ

These each figure out how many bytes are occupied by the first so-many UTF-8-encoded characters in the PV of sv. The character count gets passed by *offsetp in sv_pos_u2b, and by uoffset in sv_pos_u2b_flags.

Optionally, they also count how many bytes are in the next so-many UTF-8-encoded characters. You opt into that in both functions by passing a non-NULL lenp to them, and setting *lenp to the character count you want. Then the functions update *lenp with the byte count. Cute, right? ๐ŸŽ€

sv_pos_u2b returns void, and instead updates *offsetp to the byte count. sv_pos_u2b_flags returns the byte count.

โœจ sv_pos_u2b_flags is preferred, because offsetp is a *I32, which limits the size it can handle to 2Gb. Again. Same 2Gb ceiling, same drama.

Both handle type coercion.

sv_pos_u2b always handles 'get' magic. sv_pos_u2b_flags only handles 'get' magic when flags contains SV_GMAGIC.

sv_pos_u2b_flags is literally passing flags straight through to SvPV_flags, and bestie, flags should usually be SV_GMAGIC|SV_CONST_RETURN. Meanwhile sv_pos_u2b just auto-slaps SV_CONST_RETURN into SvPV_flags for you, no asking. ๐Ÿซถ

Both of these functions use and update PERL_MAGIC_utf8. That's not a side quest, that's canon.

 void         sv_pos_u2b      (      SV * const sv,
                                     I32 * const offsetp,
                                     I32 * const lenp)
 void    Perl_sv_pos_u2b      (pTHX_ SV * const sv,
                                     I32 * const offsetp,
                                     I32 * const lenp)
 STRLEN       sv_pos_u2b_flags(      SV * const sv,
                                     STRLEN uoffset,
                                     STRLEN * const lenp,
                                     U32 flags)
 STRLEN  Perl_sv_pos_u2b_flags(pTHX_ SV * const sv,
                                     STRLEN uoffset,
                                     STRLEN * const lenp,
                                     U32 flags)

โœจ sv_pvn_force_flags โœจ

Okay so the goal here is to get a sensible string out of the SV somehow โ€” no matter how feral that SV is being. ๐Ÿ’…

If flags has the SV_GMAGIC bit set, it will mg_get on sv if that's appropriate; otherwise it won't, simple as that.

sv_pvn_force and sv_pvn_force_nomg are implemented in terms of this function. But ngl, you normally want the various wrapper macros instead: go look at SvPV_force and SvPV_force_nomg.

 char *       sv_pvn_force_flags(      SV * const sv,
                                       STRLEN * const lp,
                                       const U32 flags)
 char *  Perl_sv_pvn_force_flags(pTHX_ SV * const sv,
                                       STRLEN * const lp,
                                       const U32 flags)

๐ŸŒธ sv_ref ๐ŸŒธ

Returns an SV describing what the SV you passed in is a reference to. Iconic little descriptor-maker. ๐Ÿ‘‘

dst can be an SV that gets set to the description, or NULL โ€” and in that case a mortal SV is returned. ๐Ÿชฆโœจ

If ob is true and the SV is blessed, the description is the class name. Otherwise it's the type of the SV: SCALAR, ARRAY, etc.

 SV *       sv_ref(      SV *dst, const SV * const sv,
                         const int ob)
 SV *  Perl_sv_ref(pTHX_ SV *dst, const SV * const sv,
                         const int ob)

๐Ÿฆ‹ sv_reftype ๐Ÿฆ‹

Returns a string describing what the SV is a reference to. Same energy as sv_ref but it hands you a string instead of an SV. โœจ

If ob is true and the SV is blessed, the string is the class name, otherwise it's the type of the SV, SCALAR, ARRAY, etc.

 const char *       sv_reftype(      const SV * const sv,
                                     const int ob)
 const char *  Perl_sv_reftype(pTHX_ const SV * const sv,
                                     const int ob)

๐ŸŽ€ sv_replace ๐ŸŽ€

Make the first argument a copy of the second, then delete the original. Body-snatching behavior, fr fr. ๐Ÿ’€

The target SV physically takes over ownership of the body of the source SV and inherits its flags โ€” however, the target keeps any magic it owns, and any magic in the source is discarded. Bye magic, you were cute. ๐Ÿซถ

Note that this is a rather specialist SV copying operation. Most of the time you'll want to use sv_setsv or one of its many macro front-ends.
 void       sv_replace(      SV * const sv, SV * const nsv)
 void  Perl_sv_replace(pTHX_ SV * const sv, SV * const nsv)

โญ sv_report_used โญ

Dump the contents of all SVs not yet freed. It's a debugging aid, bestie โ€” a little census of everything still hanging around. ๐Ÿ•ต๏ธโ€โ™€๏ธ

 void       sv_report_used()
 void  Perl_sv_report_used(pTHX)

๐Ÿ’œ sv_reset ๐Ÿ’œ

Underlying implementation for the reset Perl function. And oop โ€” note that the perl-level function is vaguely deprecated. ๐Ÿ‘€ You've been warned, gorgeous.

 void       sv_reset(      const char *s, HV * const stash)
 void  Perl_sv_reset(pTHX_ const char *s, HV * const stash)

๐ŸŒˆ sv_rvunweaken ๐ŸŒˆ

Unweaken a reference โ€” the un-doing, the healing arc. ๐Ÿ’– Here's exactly what happens:

  • Clear the SvWEAKREF flag on this RV
  • Remove the backreference to this RV from the array of backreferences associated with the target SV
  • Increment the refcount of the target

It silently ignores undef and warns on non-weak references. Rude of them, honestly.

 SV *       sv_rvunweaken(      SV * const sv)
 SV *  Perl_sv_rvunweaken(pTHX_ SV * const sv)

๐Ÿ“ sv_rvweaken ๐Ÿ“

Weaken a reference โ€” the other direction, the soft-launch of a reference:

  • Set the SvWEAKREF flag on this RV
  • Give the referred-to SV PERL_MAGIC_backref magic if it hasn't already got it
  • Push a back-reference to this RV onto the array of backreferences associated with that magic

If the RV is magical, set magic will be called after the RV is cleared. It silently ignores undef and warns on already-weak references.

 SV *       sv_rvweaken(      SV * const sv)
 SV *  Perl_sv_rvweaken(pTHX_ SV * const sv)

๐Ÿ’… sv_set_bool ๐Ÿ’…

Equivalent to sv_setsv(sv, bool_val ? &Pl_sv_yes : &PL_sv_no), but it may be made more efficient in the future. Doesn't handle set magic, so know that going in.

The perl equivalent is:

$sv = !!$expr;

Introduced in perl 5.35.11. ๐ŸŽ‰

 void       sv_set_bool(      SV *sv, const bool bool_val)
 void  Perl_sv_set_bool(pTHX_ SV *sv, const bool bool_val)

๐Ÿ™ˆ sv_set_false ๐Ÿ™ˆ

Equivalent to sv_setsv(sv, &PL_sv_no), but may be made more efficient in the future. Doesn't handle set magic.

The perl equivalent is:

$sv = !1;

Introduced in perl 5.35.11.

 void       sv_set_false(      SV *sv)
 void  Perl_sv_set_false(pTHX_ SV *sv)

โœจ sv_set_true โœจ

Equivalent to sv_setsv(sv, &PL_sv_yes), but may be made more efficient in the future. Doesn't handle set magic.

The perl equivalent is:

$sv = !0;

Introduced in perl 5.35.11.

 void       sv_set_true(      SV *sv)
 void  Perl_sv_set_true(pTHX_ SV *sv)

๐Ÿงš sv_set_undef ๐Ÿงš

Equivalent to sv_setsv(sv, &PL_sv_undef), but more efficient. Doesn't handle set magic.

The perl equivalent is:

$sv = undef;
Note that it doesn't free any string buffer, unlike undef $sv. So like, don't assume the memory got yeeted. ๐Ÿ˜ญ

Introduced in perl 5.25.12.

 void       sv_set_undef(      SV *sv)
 void  Perl_sv_set_undef(pTHX_ SV *sv)

๐ŸŒธ sv_setbool, sv_setbool_mg ๐ŸŒธ

These set an SV to a true or false boolean value, upgrading first if necessary.

They differ only in that sv_setbool_mg handles 'set' magic; sv_setbool does not. That's the whole difference, no cap.

 void  sv_setbool   (SV *sv, bool b)
 void  sv_setbool_mg(SV *sv, bool b)

๐Ÿฆ‹ sv_setiv, sv_setiv_mg ๐Ÿฆ‹

These copy an integer into the given SV, upgrading first if necessary.

They differ only in that sv_setiv_mg handles 'set' magic; sv_setiv does not.

 void       sv_setiv   (      SV * const sv, const IV num)
 void  Perl_sv_setiv   (pTHX_ SV * const sv, const IV num)
 void       sv_setiv_mg(      SV * const sv, const IV i)
 void  Perl_sv_setiv_mg(pTHX_ SV * const sv, const IV i)

โญ sv_setnv, sv_setnv_mg โญ

These copy a double into the given SV, upgrading first if necessary.

They differ only in that sv_setnv_mg handles 'set' magic; sv_setnv does not.

 void       sv_setnv   (      SV * const sv, const NV num)
 void  Perl_sv_setnv   (pTHX_ SV * const sv, const NV num)
 void       sv_setnv_mg(      SV * const sv, const NV num)
 void  Perl_sv_setnv_mg(pTHX_ SV * const sv, const NV num)

๐Ÿ’– sv_setpv, sv_setpv_mg, sv_setpvn, sv_setpvn_fresh, sv_setpvn_mg, sv_setpvs, sv_setpvs_mg ๐Ÿ’–

A whole girl group of functions. ๐ŸŽค These copy a string into the SV sv, making sure it is SvPOK_only.

Breaking down the family drama:

  • In the pvs forms, the string must be a C literal string, enclosed in double quotes.
  • In the pvn forms, the first byte of the string is pointed to by ptr, and len indicates the number of bytes to be copied, potentially including embedded NUL characters.
  • In the plain pv forms, ptr points to a NUL-terminated C string. That is, it points to the first byte of the string, and the copy proceeds up through the first encountered NUL byte.

In the forms that take a ptr argument, if it is NULL, the SV will become undefined.

The UTF-8 flag is not changed by these functions.

A terminating NUL byte is guaranteed in the result. Periodt. โœจ

The _mg forms handle 'set' magic; the other forms skip all magic.

sv_setpvn_fresh is a cut-down alternative to sv_setpvn, intended ONLY to be used with a fresh sv that has been upgraded to a SVt_PV, SVt_PVIV, SVt_PVNV, or SVt_PVMG. ONLY, bestie, don't get cute with it. ๐Ÿšจ

 void       sv_setpv       (      SV * const sv,
                                  const char * const ptr)
 void  Perl_sv_setpv       (pTHX_ SV * const sv,
                                  const char * const ptr)
 void       sv_setpv_mg    (      SV * const sv,
                                  const char * const ptr)
 void  Perl_sv_setpv_mg    (pTHX_ SV * const sv,
                                  const char * const ptr)
 void       sv_setpvn      (      SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void  Perl_sv_setpvn      (pTHX_ SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void       sv_setpvn_fresh(      SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void  Perl_sv_setpvn_fresh(pTHX_ SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void       sv_setpvn_mg   (      SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void  Perl_sv_setpvn_mg   (pTHX_ SV * const sv,
                                  const char * const ptr,
                                  const STRLEN len)
 void       sv_setpvs      (      SV *const sv, "literal string")
 void       sv_setpvs_mg   (      SV *const sv, "literal string")

๐ŸŽ€ sv_setpv_bufsize ๐ŸŽ€

Sets the SV to be a string of cur bytes length, with at least len bytes available. Ensures that there is a null byte at SvEND.

Returns a char * pointer to the SvPV buffer.

The caller must set the first cur bytes of sv before the first use of its contents. Like, that's on you, girlie. ๐Ÿ‘‘

This means that if cur is zero, the SV is immediately fully formed and ready to use, just like any other SV containing an empty string. Gorgeous, no notes. ๐Ÿ’…

"sv_setpv_bufsize"

char  *       sv_setpv_bufsize(      SV * const sv,
                                     const STRLEN cur,
                                     const STRLEN len)
char  *  Perl_sv_setpv_bufsize(pTHX_ SV * const sv,
                                     const STRLEN cur,
                                     const STRLEN len)

"sv_setpv_mg*"

okay so bestie, this whole lil squad is Described under "sv_setpv" ๐Ÿ’– go read that one, they're literally the same vibe.


"sv_setpvf", "sv_setpvf_mg", "sv_setpvf_mg_nocontext", "sv_setpvf_nocontext", "sv_vsetpvf", "sv_vsetpvf_mg", "sv_vsetpvfn"

so these each set sv to the result of formatting their arguments using pat as the sprintf-like pattern โœจ and they assume that pat has the same UTF8ness as sv. that's not their job to figure out bestie, it's the caller's responsibility to make sure that's true. no cap ๐Ÿ™ˆ

the forms differ in how their arguments are specified and in how they handle magic. slay.

sv_vsetpvfn is the most general one, and every other form gets implemented by eventually calling it ๐Ÿ‘‘ it does not handle magic; the forms with _mg in the name additionally handle 'set' magic after calling it.

it has two sets of argument lists, and only one of them gets used in any given call:

  • the first set, args, is a pointer to a va_list of pointers to C strings.
  • if args is NULL, the other list, svargs, is used โ€” it's an array of pointers to SV's. sv_count tells you how many there are in the list.

see sprintf(3) for details on how the formatting is done ๐Ÿ“– some platforms support extensions to the standard C99 definition of this function. None of those are supported by Perl. for example, neither ' (to get digit grouping), nor I (to get alternate digits) are supported. nope, not today ๐Ÿ’…

also, argument reordering (using format specifiers like %2$d or %*2$d) is supported only when using the svargs array of SVs; an exception is raised if arg is not NULL and pat contains the $ reordering specifier. ๐Ÿšจ

* maybe_tainted is supposed to be set when running with taint checks enabled if the results are untrustworthy (often due to the use of locales). However, this is not currently implemented. This argument is not used. ๐Ÿ’€ iconic honestly

patlen gives the length in bytes of pat. currently, the pattern must be NUL-terminated anyway. ok.

when using the svargs array, if any of the SVs in it have their UTF-8 flag set, sv will be converted to be so too, as necessary ๐Ÿฆ‹

none of the remaining forms use the svargs array, meaning argument reordering is not possible with them. the arguments are generally considered to be the same UTF8ness as the destination sv, though certain Perl extensions to the standard set of %formats can override this (see "Formatted Printing of Strings" in perlguts and adjacent sections). ๐ŸŒˆ

sv_setpvf and sv_setpvf_nocontext behave identically when called from outside the perl core unless PERL_WANT_VARARGS has been explicitly #defined. when it has, or when called from inside the core, they differ only in that sv_setpvf requires the thread context (aTHX) to be available.

sv_setpvf_mg and sv_setpvf_mg_nocontext behave identically when called from outside the perl core unless PERL_WANT_VARARGS has been explicitly #defined. when it has, or when called from inside the core, they differ only in that sv_setpvf_mg requires the thread context (aTHX) to be available.

the forms with vset in the name use a va_list, the other forms use sprintf-style arguments ๐Ÿ’ซ

and bestie โ€” There are no other differences between the forms. periodt.

void       sv_setpvf             (      SV * const sv,
                                        const char * const pat,
                                        ...)
void  Perl_sv_setpvf             (pTHX_ SV * const sv,
                                        const char * const pat,
                                        ...)
void       sv_setpvf_mg          (      SV * const sv,
                                        const char * const pat,
                                        ...)
void  Perl_sv_setpvf_mg          (pTHX_ SV * const sv,
                                        const char * const pat,
                                        ...)
void       sv_setpvf_mg_nocontext(      SV * const sv,
                                        const char * const pat,
                                        ...)
void  Perl_sv_setpvf_mg_nocontext(      SV * const sv,
                                        const char * const pat,
                                        ...)
void       sv_setpvf_nocontext   (      SV * const sv,
                                        const char * const pat,
                                        ...)
void  Perl_sv_setpvf_nocontext   (      SV * const sv,
                                        const char * const pat,
                                        ...)
void       sv_vsetpvf            (      SV * const sv,
                                        const char * const pat,
                                        va_list * const args)
void  Perl_sv_vsetpvf            (pTHX_ SV * const sv,
                                        const char * const pat,
                                        va_list * const args)
void       sv_vsetpvf_mg         (      SV * const sv,
                                        const char * const pat,
                                        va_list * const args)
void  Perl_sv_vsetpvf_mg         (pTHX_ SV * const sv,
                                        const char * const pat,
                                        va_list * const args)
void       sv_vsetpvfn           (    SV * const sv,
                                      const char * const pat,
                                      const STRLEN patlen,
                                      va_list * const args,
                                      SV ** const svargs,
                                      const Size_t sv_count,
                                      bool * const maybe_tainted)
void  Perl_sv_vsetpvfn           (pTHX_ SV * const sv,
                                      const char * const pat,
                                      const STRLEN patlen,
                                      va_list * const args,
                                      SV ** const svargs,
                                      const Size_t sv_count,
                                      bool * const maybe_tainted)

"sv_setpvn*", "sv_setpvn_fresh*", "sv_setpvn_mg*", "sv_setpvs*", "sv_setpvs_mg*"

yep, all of these too โ€” Described under "sv_setpv" ๐Ÿซถ go check it out, it's all there.


"sv_setref_iv"

copies an integer into a new SV, optionally blessing the SV โœจ the rv argument will be upgraded to an RV. that RV will be modified to point to the new SV. the classname argument tells you which package to bless into. set classname to NULL to skip the blessing entirely. the new SV will have a reference count of 1, and the RV will be returned ๐Ÿ’–

SV *       sv_setref_iv(      SV * const rv,
                              const char * const classname,
                              const IV iv)
SV *  Perl_sv_setref_iv(pTHX_ SV * const rv,
                              const char * const classname,
                              const IV iv)

"sv_setref_nv"

copies a double into a new SV, optionally blessing the SV ๐ŸŒธ the rv argument will be upgraded to an RV. that RV will be modified to point to the new SV. the classname argument indicates the package for the blessing. set classname to NULL to avoid the blessing. the new SV will have a reference count of 1, and the RV will be returned ๐Ÿ’…

SV *       sv_setref_nv(      SV * const rv,
                              const char * const classname,
                              const NV nv)
SV *  Perl_sv_setref_nv(pTHX_ SV * const rv,
                              const char * const classname,
                              const NV nv)

"sv_setref_pv"

copies a pointer into a new SV, optionally blessing the SV ๐Ÿ‘‘ the rv argument will be upgraded to an RV. that RV will be modified to point to the new SV. if the pv argument is NULL, then PL_sv_undef will be placed into the SV. the classname argument indicates the package for the blessing. set classname to NULL to avoid the blessing. the new SV will have a reference count of 1, and the RV will be returned โœจ

Do not use with other Perl types such as HV, AV, SV, CV, because those objects will become corrupted by the pointer copy process. ๐Ÿ’€ like actually don't, that's not a vibe, that's data loss bestie.

note that sv_setref_pvn copies the string while this copies the pointer ๐Ÿ™ˆ

SV *       sv_setref_pv(      SV * const rv,
                              const char * const classname,
                              void * const pv)
SV *  Perl_sv_setref_pv(pTHX_ SV * const rv,
                              const char * const classname,
                              void * const pv)

"sv_setref_pvn" and "sv_setref_pvs"

these each copy a string into a new SV, optionally blessing the SV ๐ŸŽ€ the rv argument will be upgraded to an RV. that RV will be modified to point to the new SV. the classname argument indicates the package for the blessing. set classname to NULL to avoid the blessing. the new SV will have a reference count of 1, and the RV will be returned ๐Ÿ’–

the forms differ only in how the source string is specified ๐Ÿฆ‹

  • sv_setref_pvs takes a C string literal enclosed in double quotes.
  • in sv_setref_pvn, n is the length of the string parameter pv in bytes. hence the latter may contain embedded NUL characters ๐Ÿ‘€

note that sv_setref_pv copies the pointer while these copy the string ๐Ÿ’…

SV *       sv_setref_pvn(      SV * const rv,
                               const char * const classname,
                               const char * const pv,
                               const STRLEN n)
SV *  Perl_sv_setref_pvn(pTHX_ SV * const rv,
                               const char * const classname,
                               const char * const pv,
                               const STRLEN n)
SV *       sv_setref_pvs(      SV *const rv,
                               const char *const classname,
                               "literal string")

sv_setref_uv ๐Ÿ’œ

So this one copies an unsigned integer into a brand-new SV, and bestie, you can bless it if you want. The rv argument gets upgraded to an RV (glow-up era โœจ). That RV then gets pointed at the fresh SV. The classname argument tells it which package to bless into. Set classname to NULL if you're not about that blessing life. The new SV comes out with a reference count of 1, and you get the RV back. ๐Ÿซถ

SV *       sv_setref_uv(      SV * const rv,
                              const char * const classname,
                              const UV uv)
SV *  Perl_sv_setref_uv(pTHX_ SV * const rv,
                              const char * const classname,
                              const UV uv)

sv_setrv_inc โœจ

sv_setrv_inc_mg โœจ

Basically sv_setrv_noinc's twin, except it does increment the reference count of ref. Periodt.

And the tea on the magic: sv_setrv_inc_mg will invoke 'set' magic on the SV; sv_setrv_inc will not. ๐Ÿ’…

void       sv_setrv_inc   (      SV * const sv, SV * const ref)
void  Perl_sv_setrv_inc   (pTHX_ SV * const sv, SV * const ref)
void       sv_setrv_inc_mg(      SV * const sv, SV * const ref)
void  Perl_sv_setrv_inc_mg(pTHX_ SV * const sv, SV * const ref)

sv_setrv_noinc ๐Ÿฆ‹

sv_setrv_noinc_mg ๐Ÿฆ‹

This one copies an SV pointer into the given SV as an SV reference, upgrading it if it needs it. After that, SvRV(sv) equals ref. Lowkey important: this does not adjust the reference count of ref. And the ref you pass must not be NULL. ๐Ÿšซ

sv_setrv_noinc_mg will invoke 'set' magic on the SV; sv_setrv_noinc will not.

void       sv_setrv_noinc   (      SV * const sv, SV * const ref)
void  Perl_sv_setrv_noinc   (pTHX_ SV * const sv, SV * const ref)
void       sv_setrv_noinc_mg(      SV * const sv, SV * const ref)
void  Perl_sv_setrv_noinc_mg(pTHX_ SV * const sv, SV * const ref)

sv_setsv ๐Ÿ’–

sv_setsv_flags ๐Ÿ’–

sv_setsv_mg ๐Ÿ’–

sv_setsv_nomg ๐Ÿ’–

These copy the contents of the source SV ssv into the destination SV dsv. Okay so heads up bestie โ€” ssv may be destroyed if it's mortal, so like, do NOT use these functions if your source SV needs to live another day. ๐Ÿ˜ญ Loosely speaking, they do a copy-by-value and just obliterate whatever was chillin' in the destination before.

The way they differ is literally just:

  • sv_setsv calls 'get' magic on ssv, but skips 'set' magic on dsv.
  • sv_setsv_mg calls both 'get' magic on ssv and 'set' magic on dsv. โœจ
  • sv_setsv_nomg skips all magic. No magic, no drama.
  • sv_setsv_flags has a flags parameter so you can specify any combo of magic handling, and you can also pass SV_NOSTEAL so the buffers of temps don't get stolen. ๐Ÿšซ

Honestly though? You probably want to use one of the cute little wrappers instead: SvSetSV, SvSetSV_nosteal, SvSetMagicSV, and SvSetMagicSV_nosteal. ๐Ÿ‘‘

sv_setsv_flags is THE main character function for copying scalars โ€” most other copy-ish functions and macros run through it underneath. ๐ŸŒˆ

void       sv_setsv      (      SV *dsv, SV *ssv)
void  Perl_sv_setsv      (pTHX_ SV *dsv, SV *ssv)
void       sv_setsv_flags(      SV *dsv, SV *ssv,
                                const I32 flags)
void  Perl_sv_setsv_flags(pTHX_ SV *dsv, SV *ssv,
                                const I32 flags)
void       sv_setsv_mg   (      SV * const dsv, SV * const ssv)
void  Perl_sv_setsv_mg   (pTHX_ SV * const dsv, SV * const ssv)
void       sv_setsv_nomg (      SV *dsv, SV *ssv)

sv_setuv ๐ŸŒธ

sv_setuv_mg ๐ŸŒธ

These copy an unsigned integer into the given SV, upgrading first if it needs the glow-up.

The only difference: sv_setuv_mg handles 'set' magic; sv_setuv does not.

void       sv_setuv   (      SV * const sv, const UV num)
void  Perl_sv_setuv   (pTHX_ SV * const sv, const UV num)
void       sv_setuv_mg(      SV * const sv, const UV u)
void  Perl_sv_setuv_mg(pTHX_ SV * const sv, const UV u)

sv_streq* ๐ŸŽ€

sv_streq_flags* ๐ŸŽ€

Bestie, these are described over in sv_eq โ€” go check that one out. ๐Ÿ‘€


sv_unmagic ๐Ÿ’…

Removes all magic of type type from an SV. Poof, gone. โœจ

int       sv_unmagic(      SV * const sv, const int type)
int  Perl_sv_unmagic(pTHX_ SV * const sv, const int type)

sv_unmagicext ๐Ÿ’…

Removes all magic of type type that has the specified vtbl from an SV. Very specific, very selective, we love a targeted cleanse. ๐Ÿงผ

int       sv_unmagicext(      SV * const sv, const int type,
                              const MGVTBL *vtbl)
int  Perl_sv_unmagicext(pTHX_ SV * const sv, const int type,
                              const MGVTBL *vtbl)

sv_unref ๐Ÿ”ฅ

sv_unref_flags ๐Ÿ”ฅ

Each of these unsets the RV status of the SV, and decrements the reference count of whatever that RV was pointing at. You can basically think of it as the reverse of newSVrv. Undo button energy. โ†ฉ๏ธ

sv_unref_flags has an extra parameter, flags, which can contain the SV_IMMEDIATE_UNREF bit to force the reference count to go down no matter what.

When that bit isn't set โ€” or with plain sv_unref, always โ€” the reference count will not be immediately decremented if the count is 1. Instead, it gets scheduled to be freed at a time of perl's choosing. Perl said "I'll deal with it later bestie." ๐Ÿ˜Œ

Other than the ability to force immediate action, the two forms behave identically.

Check SvROK_off for more.

void       sv_unref      (      SV *sv)
void  Perl_sv_unref      (pTHX_ SV *sv)
void       sv_unref_flags(      SV * const ref, const U32 flags)
void  Perl_sv_unref_flags(pTHX_ SV * const ref, const U32 flags)

sv_upgrade ๐Ÿฆ‹

This upgrades an SV to a more complex form. Generally it adds a new body type to the SV, then copies as much info across as possible from the old body. ๐Ÿงฌ

Heads up: it croaks if the SV is already in a more complex form than the one you requested. ๐Ÿ˜ญ

You generally want to reach for the SvUPGRADE macro wrapper instead โ€” it checks the type before calling sv_upgrade, so it doesn't croak. See also svtype.

void       sv_upgrade(      SV * const sv, svtype new_type)
void  Perl_sv_upgrade(pTHX_ SV * const sv, svtype new_type)

sv_usepvn ๐Ÿซถ

sv_usepvn_flags ๐Ÿซถ

sv_usepvn_mg ๐Ÿซถ

These tell an SV to use ptr for its string value. Normally SVs keep their string stored inside the SV itself, but these say "nah, use this external string instead." External storage era. ๐ŸŽ€

Now listen, ptr should point to memory that was allocated by Newx. It must be the start of a Newx-ed block of memory โ€” NOT a pointer into the middle of it (beware of OOK and copy-on-write), and NOT from a non-Newx memory allocator like malloc. You also have to supply the string length, len. ๐Ÿšจ

By default this function will Renew (i.e. realloc, move) the memory pointed to by ptr, so the pointer should not be freed or used by the programmer after handing it over to sv_usepvn. And neither should any pointers from "behind" that pointer (e.g., ptr + 1) be used. Fr fr, just give it up and let go. ๐Ÿ™ˆ

In the sv_usepvn_flags form: if flags & SV_SMAGIC is true, SvSETMAGIC gets called before returning. And if flags & SV_HAS_TRAILING_NUL is true, then ptr[len] must be NUL, and the realloc will be skipped (i.e., the buffer is actually at least 1 byte longer than len, and already meets the requirements for storing in SvPVX). โœจ

  • sv_usepvn is just sv_usepvn_flags with flags set to 0, so 'set' magic is skipped.
  • sv_usepvn_mg is just sv_usepvn_flags with flags set to SV_SMAGIC, so 'set' magic is performed. ๐Ÿ’…
void       sv_usepvn      (      SV *sv, char *ptr, STRLEN len)
void  Perl_sv_usepvn      (pTHX_ SV *sv, char *ptr, STRLEN len)
void       sv_usepvn_flags(      SV * const sv, char *ptr,
                                 const STRLEN len,
                                 const U32 flags)
void  Perl_sv_usepvn_flags(pTHX_ SV * const sv, char *ptr,
                                 const STRLEN len,
                                 const U32 flags)
void       sv_usepvn_mg   (      SV *sv, char *ptr, STRLEN len)
void  Perl_sv_usepvn_mg   (pTHX_ SV *sv, char *ptr, STRLEN len)

sv_utf8_decode ๐ŸŒˆ

If the PV of the SV is an octet sequence in Perl's extended UTF-8 and contains a multiple-byte character, the SvUTF8 flag gets turned on so it looks like a character. If the PV contains only single-byte characters, the SvUTF8 flag stays off. It scans the PV for validity and returns FALSE if the PV is invalid UTF-8. ๐Ÿ‘‘

bool       sv_utf8_decode(      SV * const sv)
bool  Perl_sv_utf8_decode(pTHX_ SV * const sv)

sv_utf8_downgrade ๐Ÿ’œ

sv_utf8_downgrade_flags ๐Ÿ’œ

sv_utf8_downgrade_nomg ๐Ÿ’œ

These attempt to convert the PV of an SV from characters to bytes. If the PV contains a character that cannot fit in a byte, the conversion fails โ€” in that case, FALSE is returned if fail_ok is true; otherwise they croak. ๐Ÿ˜ญ

Real talk: these are NOT a general purpose Unicode-to-byte encoding interface. Use the Encode extension for that. ๐Ÿšซ

The way they differ:

  • sv_utf8_downgrade processes 'get' magic on sv.
  • sv_utf8_downgrade_nomg does not. (No magic, no problem. โœจ)
  • sv_utf8_downgrade_flags has an additional flags parameter where you can specify SV_GMAGIC to process 'get' magic, or leave it cleared to not process 'get' magic.
     bool       sv_utf8_downgrade      (      SV * const sv,
                                              const bool fail_ok)
     bool  Perl_sv_utf8_downgrade      (pTHX_ SV * const sv,
                                              const bool fail_ok)
     bool       sv_utf8_downgrade_flags(      SV * const sv,
                                              const bool fail_ok,
                                              const U32 flags)
     bool  Perl_sv_utf8_downgrade_flags(pTHX_ SV * const sv,
                                              const bool fail_ok,
                                              const U32 flags)
     bool       sv_utf8_downgrade_nomg (      SV * const sv,
                                              const bool fail_ok)
     bool  Perl_sv_utf8_downgrade_nomg (pTHX_ SV * const sv,
                                              const bool fail_ok)

โœจ sv_utf8_encode โœจ

Okay bestie, this one takes the PV of an SV and converts it to UTF-8 โ€” but then it flips the SvUTF8 flag off so it looks like octets again. Sneaky little glow-down ๐Ÿ’…โœจ

     void       sv_utf8_encode(      SV * const sv)
     void  Perl_sv_utf8_encode(pTHX_ SV * const sv)

๐ŸŒˆ sv_utf8_upgrade / sv_utf8_upgrade_flags / sv_utf8_upgrade_flags_grow / sv_utf8_upgrade_nomg ๐ŸŒˆ

These four cuties convert the PV of an SV into its UTF-8-encoded form ๐Ÿฆ‹. If the SV isn't already in string form, it gets forced into it, no discussion. And they always set the SvUTF8 flag โ€” even if the whole string looks exactly the same in UTF-8 as it does not โ€” because they're avoiding future validity checks. Efficiency queen ๐Ÿ‘‘. They return the number of bytes in the converted string.

So how do these four differ? Only two ways, lowkey:

Difference numero uno: whether they do 'get magic' on sv.

  • sv_utf8_upgrade_nomg โ€” skips 'get magic' entirely ๐Ÿ™ˆ
  • sv_utf8_upgrade โ€” performs it โœจ
  • sv_utf8_upgrade_flags and sv_utf8_upgrade_flags_grow โ€” perform it if the SV_GMAGIC bit is set in flags, and don't if that bit is cleared ๐ŸŽ€

Difference numero dos: sv_utf8_upgrade_flags_grow has one extra parameter, extra, and it lets the caller reserve spare space beyond what's actually needed for the conversion. When would you want that? When you already know you're gonna need even more space super soon, and it's just more efficient to ask the system for space in a single call rather than coming back begging twice ๐Ÿ’€. Other than that, it's identical to sv_utf8_upgrade_flags.

Heads up bestie: these are not a general purpose byte-encoding-to-Unicode interface. If that's what you want, use the Encode extension, periodt.

Also, the SV_FORCE_UTF8_UPGRADE flag is now ignored. Gone. Irrelevant. Don't come for her ๐Ÿ’…

     STRLEN       sv_utf8_upgrade           (      SV *sv)
     STRLEN  Perl_sv_utf8_upgrade           (pTHX_ SV *sv)
     STRLEN       sv_utf8_upgrade_flags     (      SV * const sv,
                                                   const I32 flags)
     STRLEN  Perl_sv_utf8_upgrade_flags     (pTHX_ SV * const sv,
                                                   const I32 flags)
     STRLEN       sv_utf8_upgrade_flags_grow(      SV * const sv,
                                                   const I32 flags,
                                                   STRLEN extra)
     STRLEN  Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV * const sv,
                                                   const I32 flags,
                                                   STRLEN extra)
     STRLEN       sv_utf8_upgrade_nomg      (      SV *sv)
     STRLEN  Perl_sv_utf8_upgrade_nomg      (pTHX_ SV *sv)

๐ŸŽ€ sv_vcatpvf* / sv_vcatpvf_mg* / sv_vcatpvfn* / sv_vcatpvfn_flags* ๐ŸŽ€

Bestie, these are all described over under sv_catpvf โ€” go peek there ๐Ÿ’–


๐Ÿซถ sv_vsetpvf* / sv_vsetpvf_mg* / sv_vsetpvfn* ๐Ÿซถ

And these ones? Described under sv_setpvf. Same deal, go read that one ๐ŸŒธ


โญ sv_2cv โญ

Using various gambits (love a gambit era), this tries to get a CV out of an SV. And on top of that, if it possibly can, it tries to set *st and *gvp to the stash and GV that are associated with it. The flags sitting in lref get passed straight through to gv_fetchsv โœจ

     CV *       sv_2cv(      SV *sv, HV ** const st, GV ** const gvp,
                             const I32 lref)
     CV *  Perl_sv_2cv(pTHX_ SV *sv, HV ** const st, GV ** const gvp,
                             const I32 lref)

๐Ÿ’œ sv_2io ๐Ÿ’œ

More gambits, but this time we're hunting for an IO out of an SV. Here's the tea โ˜•: if it's a GV, you get the IO slot; if we're an RV, you get the recursive result; and if we're a string, you get the IO slot of the symbol named after the PV.

Note bestie: 'Get' magic on the sv you pass in is ignored. But it will be called on SvRV(sv) if sv is an RV. Iykyk ๐Ÿ™ˆ
     IO *       sv_2io(      SV * const sv)
     IO *  Perl_sv_2io(pTHX_ SV * const sv)

๐Ÿ”ฅ sv_2iv_flags ๐Ÿ”ฅ

Gives you back the integer value of an SV, doing whatever string conversion needs doing along the way. If flags has the SV_GMAGIC bit set, it does an mg_get() first. Normally you reach for this through the SvIV(sv) and SvIVx(sv) macros, fr fr.

     IV       sv_2iv_flags(      SV * const sv, const I32 flags)
     IV  Perl_sv_2iv_flags(pTHX_ SV * const sv, const I32 flags)

๐Ÿฆ‹ sv_2mortal ๐Ÿฆ‹

Marks an existing SV as mortal. So dramatic. ๐Ÿ’€ The SV is gonna get destroyed "soon" โ€” either by you explicitly calling FREETMPS, or implicitly at places like statement boundaries. SvTEMP() gets turned on, which means the SV's string buffer can be "stolen" if this SV ever gets copied. Sneaky but iconic.

Also go check out sv_newmortal and sv_mortalcopy while you're here ๐Ÿ‘‘

     SV *       sv_2mortal(      SV * const sv)
     SV *  Perl_sv_2mortal(pTHX_ SV * const sv)

๐ŸŒธ sv_2nv_flags ๐ŸŒธ

Returns the num value of an SV, doing any string or integer conversion that's necessary. If flags has the SV_GMAGIC bit set, it does an mg_get() first. Normally used via the SvNV(sv) and SvNVx(sv) macros ๐Ÿ’…

     NV       sv_2nv_flags(      SV * const sv, const I32 flags)
     NV  Perl_sv_2nv_flags(pTHX_ SV * const sv, const I32 flags)

๐Ÿ’– sv_2pv / sv_2pv_flags ๐Ÿ’–

These two implement the various forms of the "SvPV" in perlapi macros. But listen โ€” the macros are the preferred interface, so that's what you should actually be using, bestie ๐Ÿซถ

What do they do? They return a pointer to the string value of an SV (coercing it to a string if that's needed), and they set *lp to its length in bytes.

And the difference between them? The plain sv_2pvbyte always processes 'get' magic; and sv_2pvbyte_flags processes 'get' magic if and only if flags contains SV_GMAGIC โœจ

     char *       sv_2pv      (      SV *sv, STRLEN *lp)
     char *  Perl_sv_2pv      (pTHX_ SV *sv, STRLEN *lp)
     char *       sv_2pv_flags(      SV * const sv, STRLEN * const lp,
                                     const U32 flags)
     char *  Perl_sv_2pv_flags(pTHX_ SV * const sv, STRLEN * const lp,
                                     const U32 flags)

๐ŸŽ€ sv_2pvbyte / sv_2pvbyte_flags ๐ŸŽ€

Implementing the various forms of the "SvPVbyte" in perlapi macros. Same energy: the macros are the preferred interface ๐ŸŒˆ

They hand you a pointer to the byte-encoded representation of the SV and set *lp to its length. If the SV is marked as being encoded as UTF-8, it gets downgraded โ€” if that's even possible โ€” into a byte string. And if it can't be downgraded? They croak ๐Ÿ˜ญ no mercy.

Difference between the two: plain sv_2pvbyte always processes 'get' magic; sv_2pvbyte_flags does it if and only if flags contains SV_GMAGIC โญ

     char *       sv_2pvbyte      (      SV *sv, STRLEN * const lp)
     char *  Perl_sv_2pvbyte      (pTHX_ SV *sv, STRLEN * const lp)
     char *       sv_2pvbyte_flags(      SV *sv, STRLEN * const lp,
                                         const U32 flags)
     char *  Perl_sv_2pvbyte_flags(pTHX_ SV *sv, STRLEN * const lp,
                                         const U32 flags)

๐Ÿงš sv_2pvutf8 / sv_2pvutf8_flags ๐Ÿงš

Implementing the various forms of the "SvPVutf8" in perlapi macros โ€” and yeah, macros are still the preferred interface, we been knew ๐Ÿ’…

These return a pointer to the UTF-8-encoded representation of the SV and set *lp to its length in bytes. Fair warning though: they might cause the SV to get upgraded to UTF-8 as a side-effect ๐Ÿ‘€

The difference: plain sv_2pvutf8 always processes 'get' magic; sv_2pvutf8_flags processes it if and only if flags contains SV_GMAGIC โœจ

     char *       sv_2pvutf8      (      SV *sv, STRLEN * const lp)
     char *  Perl_sv_2pvutf8      (pTHX_ SV *sv, STRLEN * const lp)
     char *       sv_2pvutf8_flags(      SV *sv, STRLEN * const lp,
                                         const U32 flags)
     char *  Perl_sv_2pvutf8_flags(pTHX_ SV *sv, STRLEN * const lp,
                                         const U32 flags)

๐Ÿ‘‘ sv_2uv_flags ๐Ÿ‘‘

Returns the unsigned integer value of an SV, doing whatever string conversion is necessary. If flags has the SV_GMAGIC bit set, it does an mg_get() first. Normally you'd get here via the SvUV(sv) and SvUVx(sv) macros ๐ŸŒŸ

     UV       sv_2uv_flags(      SV * const sv, const I32 flags)
     UV  Perl_sv_2uv_flags(pTHX_ SV * const sv, const I32 flags)

โญ SvAMAGIC โญ

Returns a boolean telling you whether sv has overloading (that's active magic) enabled, or not. Yes/no. Slay.

Bestie, note this: you should do a GET magic check prior to an active magic check. Order matters ๐Ÿ™ˆ
     bool  SvAMAGIC(SV * sv)

๐ŸŽ€ SvAMAGIC_off ๐ŸŽ€

Indicates that sv has its overloading (active magic) disabled. Turned off, gone, not today ๐Ÿ’…

     void       SvAMAGIC_off(SV *sv)
     void  Perl_SvAMAGIC_off(SV *sv)

โœจ SvAMAGIC_on โœจ

Indicates that sv has its overloading (active magic) enabled. Popped off ๐Ÿ”ฅ

     void       SvAMAGIC_on(SV *sv)
     void  Perl_SvAMAGIC_on(SV *sv)

๐Ÿฆ‹ SvBoolFlagsOK ๐Ÿฆ‹

Returns a bool telling you whether the SV has the right flags set such that it's safe to call BOOL_INTERNALS_sv_isbool(), BOOL_INTERNALS_sv_isbool_true(), or BOOL_INTERNALS_sv_isbool_false(). Right now it's equivalent to SvIandPOK(sv) or "SvIOK(sv) && SvPOK(sv)" ๐ŸŽ€

So like โ€” serialization might want to unroll this check. And if you do that, bestie, you are strongly recommended to add code like assert(SvBoolFlagsOK(sv)); before you call using any of the BOOL_INTERNALS macros. Do not skip this, fr fr ๐Ÿ™

     U32  SvBoolFlagsOK(SV* sv)

๐ŸŒธ SvCUR ๐ŸŒธ

Returns the length of the PV inside the SV โ€” in bytes. And no, that might not match Perl's length, so don't get it twisted. For that, use sv_len_utf8(sv) instead ๐Ÿซถ Also go peek at SvLEN.

     STRLEN  SvCUR(SV* sv)

๐Ÿ’œ SvCUR_set ๐Ÿ’œ

Sets the current length, in bytes, of the C string that lives inside the SV. See SvCUR and SvIV_set if you want the full lore โœจ

     void  SvCUR_set(SV* sv, STRLEN len)

๐Ÿ’€ SvEND ๐Ÿ’€

Returns a pointer to the spot just after the last character in the string that's inside the SV โ€” and usually there's a trailing NUL character sitting there (even though Perl scalars don't strictly require one, they're just extra like that ๐Ÿ’…). See SvCUR. You access the character as *(SvEND(sv)).

โš ๏ธ Warning, bestie, this one's real: if SvCUR is equal to SvLEN, then SvEND points to unallocated memory. That's it. That's the danger. Be careful out there ๐Ÿ˜ญ
     char*  SvEND(SV* sv)

SvGAMAGIC

Bestie, vibe check incoming: this one returns true if the SV has get magic or overloading going on. If either of those is true, the scalar is live, active data โ€” it could hand you a brand-new value literally every single time you look at it ๐Ÿ‘€. So the rule is: read it once per logical operation, work with that value you grabbed, and move on. If neither is true, then the scalar's value can't change unless something writes to it. Periodt.

 U32  SvGAMAGIC(SV* sv)

SvGETMAGIC

Calls mg_get on an SV if it's got 'get' magic. Example bestie: this is what calls FETCH on a tied variable โœจ. And as of 5.37.1, this function is guaranteed to evaluate its argument exactly once โ€” one and done, no double-dipping ๐Ÿ’….

 void       SvGETMAGIC(      SV *sv)
 void  Perl_SvGETMAGIC(pTHX_ SV *sv)

SvGMAGICAL

Returns a U32 telling you whether the SV has GET magic assigned.

People usually check this right before pulling a value out of an SV, normally via SvGETMAGIC().

And like โ€” GET magic can do a lot: modify the value you're retrieving, swap it for a totally different one, derive it on the fly, or trigger some other whole behaviour. It's giving chaos goblin energy, so be aware ๐Ÿซถ.

 U32  SvGMAGICAL(SV* sv)

SvGROW

Expands the character buffer in the SV so there's room for the number of bytes you asked for. And remember to reserve space for that extra trailing NUL character too, bestie, don't forget it! It calls sv_grow to do the actual expansion if it's needed, and returns a pointer to the character buffer. The SV must be of type >= SVt_PV. One alternative: just call sv_grow yourself if you're not sure what type of SV you're holding.

โš ๏ธ Trap alert: you might mistakenly think len is the number of bytes to ADD to the existing size. Nope. It's the total size sv should be. Do not get this twisted ๐Ÿ’€.
 char *  SvGROW(SV* sv, STRLEN len)

SvIandPOK

Returns a bool for whether the SV is both SvPOK() and SvIOK() at the same time. Equivalent to SvIOK(sv) && SvPOK(sv), except it's more efficient. Slay.

 U32  SvIandPOK(SV* sv)

SvIandPOK_off

Unsets the PV and IV status of an SV in one single operation. Equivalent to SvIOK_off(sv); SvPK_off(v); but way more efficient. One move, no cap ๐Ÿ˜Œ.

 void  SvIandPOK_off(SV* sv)

SvIandPOK_on

Tells an SV that it's a string and a number, in one operation. Equivalent to SvIOK_on(sv); SvPOK_on(sv); but more efficient. Two truths, one macro, iconic.

 void  SvIandPOK_on(SV* sv)

SvIOK

Returns a U32 telling you whether the SV contains an integer.

 U32  SvIOK(SV* sv)

SvIOK_notUV

Returns a boolean for whether the SV contains a signed integer.

 bool  SvIOK_notUV(SV* sv)

SvIOK_off

Unsets the IV status of an SV.

 void  SvIOK_off(SV* sv)

SvIOK_on

Tells an SV that it is an integer.

 void  SvIOK_on(SV* sv)

SvIOK_only

Tells an SV that it's an integer and disables all the other OK bits. Only child behaviour, honestly ๐Ÿ’….

 void  SvIOK_only(SV* sv)

SvIOK_only_UV

Tells an SV that it is an unsigned integer and disables all other OK bits.

 void  SvIOK_only_UV(SV* sv)

SvIOK_UV

Returns a boolean for whether the SV contains an integer that must be interpreted as unsigned. Heads up bestie: a non-negative integer whose value fits in the range of both an IV and a UV may be flagged as either SvUOK or SvIOK. So don't come for it either way ๐ŸŒธ.

 bool  SvIOK_UV(SV* sv)

SvIOKp

Returns a U32 for whether the SV contains an integer, but it checks the private setting. Just use SvIOK instead, fr fr.

 U32  SvIOKp(SV* sv)

SvIsBOOL

Returns true if the SV is one of the special boolean constants (PL_sv_yes or PL_sv_no), or is a regular SV whose last assignment stored a copy of one. Yes queen, we can tell โœจ.

 bool  SvIsBOOL(SV* sv)

SvIsCOW

Returns a U32 for whether the SV is Copy-On-Write โ€” that's either shared hash key scalars, or full Copy On Write scalars if 5.9.0 is configured for COW.

 U32  SvIsCOW(SV* sv)

SvIsCOW_shared_hash

Returns a boolean for whether the SV is a Copy-On-Write shared hash key scalar.

 bool  SvIsCOW_shared_hash(SV* sv)

SvIV, SvIV_nomg, SvIVx

These each coerce the given SV to IV and hand it back. In many circumstances that returned value gets stored in sv's IV slot โ€” but not in all cases. (Use sv_setiv if you want to be sure it does. No guessing, bestie.)

As of 5.37.1, all of them are guaranteed to evaluate sv only once.

SvIVx is now identical to SvIV, but prior to 5.37.1 it was the only form guaranteed to evaluate sv only once. Glow-up era ๐ŸŒˆ.

SvIV_nomg is the same as SvIV, except it does not perform 'get' magic.

 IV       SvIV     (      SV *sv)
 IV  Perl_SvIV     (pTHX_ SV *sv)
 IV       SvIV_nomg(      SV *sv)
 IV  Perl_SvIV_nomg(pTHX_ SV *sv)
 IV       SvIVx    (      SV *sv)

SvIV_set

Sets the value of the IV pointer in sv to val. You could do the same thing with an lvalue assignment to SvIVX, but with future Perls it'll be more efficient to use SvIV_set instead. Future-proofing, we love to see it ๐Ÿ’œ.

 void  SvIV_set(SV* sv, IV val)

SvIVX

Returns the raw value sitting in the SV's IV slot โ€” no checks, no conversions. Only use this when you're sure SvIOK is true. See also SvIV.

 IV  SvIVX(SV* sv)

SvIVx*

Described under SvIV. Go peek up there bestie โฌ†๏ธ.

SvLEN

Returns the size of the string buffer in the SV, not including any part attributable to SvOOK. See SvCUR.

 STRLEN  SvLEN(SV* sv)

SvLEN_set

Set the size of the string buffer for the SV. See SvLEN.

 void  SvLEN_set(SV* sv, STRLEN len)

SvLOCK

Arranges for a mutual exclusion lock to be obtained on sv โ€” but only if a suitable module has been loaded. Mutual exclusion, she's exclusive ๐Ÿ’….

 void  SvLOCK(SV* sv)

SvMAGIC_set

Set the value of the MAGIC pointer in sv to val. See SvIV_set.

 void  SvMAGIC_set(SV* sv, MAGIC* val)

SvMAGICAL

Returns a U32 for whether the SV has "magical" behavior attached.

That covers any GET, SET, or RANDOM magic โ€” but it does not include overload functionality (aka active magic). For that, you use the separate SvAMAGIC() macro after checking for GET magic. Different magic, different macro, don't mix them up ๐Ÿ™ˆ.

 U32  SvMAGICAL(SV* sv)

SvNIOK

Returns a U32 for whether the SV contains a number โ€” integer or double.

 U32  SvNIOK(SV* sv)

SvNIOK_off

Unsets the NV/IV status of an SV.

 void  SvNIOK_off(SV* sv)

SvNIOKp

Returns a U32 for whether the SV contains a number, integer or double โ€” but it checks the private setting. Use SvNIOK instead, bestie.

 U32  SvNIOKp(SV* sv)

SvNOK

Returns a U32 for whether the SV contains a double.

 U32  SvNOK(SV* sv)

SvNOK_off

Unsets the NV status of an SV.

 void  SvNOK_off(SV* sv)

SvNOK_on

Tells an SV that it is a double.

 void  SvNOK_on(SV* sv)

SvNOK_only

Tells an SV that it is a double and disables all other OK bits.

 void  SvNOK_only(SV* sv)

SvNOKp

Returns a U32 for whether the SV contains a double, checking the private setting. Use SvNOK instead.

 U32  SvNOKp(SV* sv)

SvNV, SvNV_nomg, SvNVx

These each coerce the given SV to NV and return it. Again โ€” in many circumstances the returned value gets stored in sv's NV slot, but not in all cases. (Use sv_setnv to make sure it does.)

As of 5.37.1, all are guaranteed to evaluate sv only once.

SvNVx is now identical to SvNV, but prior to 5.37.1 it was the only form guaranteed to evaluate sv only once.

SvNV_nomg is the same as SvNV, except it does not perform 'get' magic.

 NV       SvNV     (      SV *sv)
 NV  Perl_SvNV     (pTHX_ SV *sv)
 NV       SvNV_nomg(      SV *sv)
 NV  Perl_SvNV_nomg(pTHX_ SV *sv)
 NV       SvNVx    (      SV *sv)

SvNV_set

Set the value of the NV pointer in sv to val. See SvIV_set.

 void  SvNV_set(SV* sv, NV val)

SvNVX

Returns the raw value in the SV's NV slot, no checks or conversions. Only use when you're sure SvNOK is true. See also SvNV.

 NV  SvNVX(SV* sv)

SvNVx*

Described under SvNV. Scroll up, you got this ๐Ÿฆ‹.

SvOK

Returns a U32 for whether the value is defined. Real talk: this is only meaningful for scalars.

 U32  SvOK(SV* sv)

SvOOK

Returns a U32 for whether the pointer to the string buffer is offset. This is a little internal hack used to speed up removing characters from the front of a SvPV. When SvOOK is true, the actual start of the allocated string buffer is SvOOK_offset() bytes before SvPVX. That offset used to live in SvIVX, but these days it's stored within the spare part of the buffer. Sneaky, efficient, iconic.

 U32  SvOOK(SV* sv)

SvOOK_off

Remove any string offset.

 void  SvOOK_off(SV * sv)

SvOOK_offset

Reads into len the offset from SvPVX back to the true start of the allocated buffer. That'll be non-zero if sv_chop has been used to efficiently chop characters off the front of the buffer. It's implemented as a macro, and it takes the address of len, which must be of type STRLEN. Careful: it evaluates sv more than once. And it sets len to 0 if SvOOK(sv) is false.

 void  SvOOK_offset(SV*sv, STRLEN len)

SvPOK

Returns a U32 for whether the SV contains a character string.

 U32  SvPOK(SV* sv)

SvPOK_off

Unsets the PV status of an SV.

 void  SvPOK_off(SV* sv)

SvPOK_on

Tells an SV that it is a string.

 void  SvPOK_on(SV* sv)

SvPOK_only

Tells an SV that it is a string and disables all other OK bits. It will also turn off the UTF-8 status. Noted ๐Ÿ“.

 void  SvPOK_only(SV* sv)

SvPOK_only_UTF8

Tells an SV that it is a string and disables all other OK bits, and leaves the UTF-8 status exactly as it was. The respectful version ๐Ÿ’–.

 void  SvPOK_only_UTF8(SV* sv)

SvPOKp

Returns a U32 for whether the SV contains a character string, checking the private setting. Use SvPOK instead.

 U32  SvPOKp(SV* sv)

โœจ SvPV โœจ

SvPV SvPV_const SvPV_flags SvPV_flags_const SvPV_flags_mutable SvPV_mutable SvPV_nolen SvPV_nolen_const SvPV_nomg SvPV_nomg_const SvPV_nomg_const_nolen SvPV_nomg_nolen SvPVbyte SvPVbyte_nolen SvPVbyte_nomg SvPVbyte_or_null SvPVbyte_or_null_nomg SvPVbytex SvPVbytex_nolen SvPVutf8 SvPVutf8_nolen SvPVutf8_nomg SvPVutf8_or_null SvPVutf8_or_null_nomg SvPVutf8x SvPVx SvPVx_const SvPVx_nolen SvPVx_nolen_const

okay so bestie, every single one of these hands you back a pointer to the string inside sv โ€” or, if sv isn't holding a string at all, a pointer to a stringified version of it. the SV is allowed to just. cache that stringified version and become SvPOK. iconic behavior honestly ๐Ÿ’…

this is like THE most basic, most common thing you do with an SV, which is why there are approximately one million slightly-different versions of it. bless. ๐Ÿ™ˆ

โš ๏ธ heads up queen: there is no guarantee that what SvPV(sv) returns is equal to SvPVX(sv), or that SvPVX(sv) contains valid data, or that calling SvPV(sv) (or any of these other forms) twice in a row gives you the same pointer value both times. this is because of how overloading and Copy-On-Write get handled. in those cases your return value might be pointing at a temporary buffer or something like it. if you absolutely need the SvPVX field to be valid โ€” say, because you wanna write into it โ€” then go look at SvPV_force.

so what even are the differences between all these forms? let's go ๐ŸŽ€

  • the forms with neither byte nor utf8 in their names (like SvPV or SvPV_nolen) can expose the SV's internal string buffer. if that buffer is entirely bytes 0-255 and has any bytes above 127 in it, then you MUST go consult SvUTF8 to figure out what code points the string is actually meant to hold. ngl, generally speaking it's probably safer to prefer SvPVbyte, SvPVutf8, and friends. more deets in "How do I pass a Perl string to a C library?" in perlguts.
  • the forms with flags in their names let you use the flags parameter to say "process 'get' magic" (set the SV_GMAGIC flag) or "skip 'get' magic" (clear it). all the other forms process 'get' magic โ€” except the ones with nomg in their names, which skip it.
  • the forms that take a len parameter will set that variable to the byte length of the resulting string. (they're macros, so do not use &len bestie ๐Ÿ˜ญ)
  • the forms with nolen in their names just don't have a len parameter. only use these when you know the PV is a C string, NUL-terminated, no sneaky NUL characters hiding in the middle โ€” or when you genuinely do not care about the length.
  • the forms with const in their names return const char *, so the compiler will hopefully yell at you if you try to modify the string contents (unless you went and casted the const away yourself, which, okay, your funeral โœจ).
  • the other forms return a mutable pointer, so the caller can modify the string. this is emphasized extra hard for the ones with mutable in their names.

as of 5.38, all forms are guaranteed to evaluate sv exactly once. for earlier Perls, use a form whose name ends in x if you want single evaluation. ๐Ÿ’€

SvPVutf8 is like SvPV but converts sv to UTF-8 first if it isn't already UTF-8. same energy for all the other utf8 forms vs their non-utf8 counterparts.

SvPVutf8_or_null and SvPVutf8_or_null_nomg do not have corresponding non-utf8 forms. instead they're like SvPVutf8_nomg, except when sv is undef they return NULL. ๐Ÿซถ

SvPVbyte is like SvPV but converts sv to byte representation first if it's currently encoded as UTF-8. if sv cannot be downgraded from UTF-8, it croaks. ๐Ÿ˜ค same pattern for the other byte-named forms vs their non-byte counterparts.

SvPVbyte_or_null has no corresponding non-byte form. it's like SvPVbyte but returns NULL when sv is undef.

char*        SvPV                 (SV* sv, STRLEN len)
const char*  SvPV_const           (SV* sv, STRLEN len)
char*        SvPV_flags           (SV* sv, STRLEN len, U32 flags)
const char*  SvPV_flags_const     (SV* sv, STRLEN len, U32 flags)
char*        SvPV_flags_mutable   (SV* sv, STRLEN len, U32 flags)
char*        SvPV_mutable         (SV* sv, STRLEN len)
char*        SvPV_nolen           (SV* sv)
const char*  SvPV_nolen_const     (SV* sv)
char*        SvPV_nomg            (SV* sv, STRLEN len)
const char*  SvPV_nomg_const      (SV* sv, STRLEN len)
const char*  SvPV_nomg_const_nolen(SV* sv)
char*        SvPV_nomg_nolen      (SV* sv)
char*        SvPVbyte             (SV* sv, STRLEN len)
char*        SvPVbyte_nolen       (SV* sv)
char*        SvPVbyte_nomg        (SV* sv, STRLEN len)
char*        SvPVbyte_or_null     (SV* sv, STRLEN len)
char*        SvPVbyte_or_null_nomg(SV* sv, STRLEN len)
char*        SvPVbytex            (SV* sv, STRLEN len)
char*        SvPVbytex_nolen      (SV* sv)
char*        SvPVutf8             (SV* sv, STRLEN len)
char*        SvPVutf8_nolen       (SV* sv)
char*        SvPVutf8_nomg        (SV* sv, STRLEN len)
char*        SvPVutf8_or_null     (SV* sv, STRLEN len)
char*        SvPVutf8_or_null_nomg(SV* sv, STRLEN len)
char*        SvPVutf8x            (SV* sv, STRLEN len)
char*        SvPVx                (SV* sv, STRLEN len)
const char*  SvPVx_const          (SV* sv, STRLEN len)
char*        SvPVx_nolen          (SV* sv)
const char*  SvPVx_nolen_const    (SV* sv)

โœจ SvPV_force โœจ

SvPV_force SvPV_force_flags SvPV_force_flags_mutable SvPV_force_flags_nolen SvPV_force_mutable SvPV_force_nolen SvPV_force_nomg SvPV_force_nomg_nolen SvPVbyte_force SvPVbytex_force SvPVutf8_force SvPVutf8x_force SvPVx_force

these are like SvPV and hand you the string in the SV, BUT they will force the SV into containing a string (SvPOK), and only a string (SvPOK_only), by hook or by crook. ๐Ÿ’ช you need one of these force routines if you're gonna go update the SvPVX directly. no skipping steps.

big yikes warning: coercing an arbitrary scalar into a plain PV will potentially strip useful data right out of it. for example, if the SV was SvROK, then the referent has its reference count decremented, and the SV itself may get converted into an SvPOK scalar with a string buffer holding a value like ARRAY(0x1234). it's giving "you asked for a string, enjoy your string" ๐Ÿ˜ญ

the differences between the forms, bestie:

  • the ones with flags in their names let you use the flags parameter to perform 'get' magic (set SV_GMAGIC) or skip 'get' magic (clear it). the other forms do perform 'get' magic โ€” except the ones with nomg in their names, which skip it.
  • the ones that take a len parameter set that variable to the byte length of the resultant string. (macros again, so please don't use &len ๐Ÿ™ˆ)
  • the ones with nolen in their names have no len parameter. only use them when you know the PV is a C string, NUL-terminated, no intermediate NUL characters โ€” or when you just don't care about the length.
  • the ones with mutable in their names are effectively the same as the ones without, but the name is out here emphasizing that the string is modifiable by the caller. which it is. in all the forms. surprise ๐ŸŽ€

SvPVutf8_force is like SvPV_force but converts sv to UTF-8 first if it's not already UTF-8.

SvPVutf8x_force is like SvPVutf8_force but guarantees evaluating sv only once; otherwise use the more efficient SvPVutf8_force.

SvPVbyte_force is like SvPV_force but converts sv to byte representation first if it's currently encoded as UTF-8. if the SV can't be downgraded from UTF-8, this croaks. ๐Ÿ’€

SvPVbytex_force is like SvPVbyte_force but guarantees evaluating sv only once; otherwise use the more efficient SvPVbyte_force.

char*  SvPV_force              (SV* sv, STRLEN len)
char*  SvPV_force_flags        (SV * sv, STRLEN len, U32 flags)
char*  SvPV_force_flags_mutable(SV * sv, STRLEN len, U32 flags)
char*  SvPV_force_flags_nolen  (SV * sv, U32 flags)
char*  SvPV_force_mutable      (SV * sv, STRLEN len)
char*  SvPV_force_nolen        (SV* sv)
char*  SvPV_force_nomg         (SV* sv, STRLEN len)
char*  SvPV_force_nomg_nolen   (SV * sv)
char*  SvPVbyte_force          (SV * sv, STRLEN len)
char*  SvPVbytex_force         (SV * sv, STRLEN len)
char*  SvPVutf8_force          (SV * sv, STRLEN len)
char*  SvPVutf8x_force         (SV * sv, STRLEN len)
char*  SvPVx_force             (SV* sv, STRLEN len)

โœจ SvPV_free โœจ

frees the PV buffer inside sv, leaving things in a precarious state ๐Ÿซฃ โ€” so this should only ever be used as part of some larger operation. do not just. casually free it and walk away. that's not the vibe.

void  SvPV_free(SV * sv)

โœจ SvPV_mutable* โœจ

SvPV_mutable* SvPV_nolen* SvPV_nolen_const* SvPV_nomg* SvPV_nomg_const* SvPV_nomg_const_nolen* SvPV_nomg_nolen*

described under "SvPV" ๐Ÿ‘† go scroll back up bestie, they're all hanging out under SvPV.


โœจ SvPV_renew โœจ

a low level micro optimization of SvGROW. honestly? it is generally better to use SvGROW instead. why? because SvPV_renew straight up ignores potential issues that SvGROW actually handles. ๐Ÿ™ƒ

sv needs to have a real PV that's unencumbered by stuff like COW. using SV_CHECK_THINKFIRST or SV_CHECK_THINKFIRST_COW_DROP before calling this should clean it up, but likeโ€ฆ why not just use SvGROW if you're not sure about the provenance? fr fr.

void  SvPV_renew(SV* sv, STRLEN len)

โœจ SvPV_set โœจ

this is probably not what you want to use. you probably wanted sv_usepvn_flags or sv_setpvn or sv_setpvs. just saying. ๐Ÿ’…

it sets the value of the PV pointer in sv to the Perl-allocated, NUL-terminated string val. see also SvIV_set.

and now the checklist, because there are MANY things to check: remember to free the previous PV buffer. beware that the existing pointer may be caught up in copy-on-write or other mischief, so do SvOOK_off(sv) and use sv_force_normal or SvPV_force (or check the SvIsCOW flag) FIRST to make sure this modification is safe. then finally โ€” if it is not a COW โ€” call SvPV_free to free the previous PV buffer. that's the whole ritual, no cap ๐Ÿ•ฏ๏ธ

void  SvPV_set(SV* sv, char* val)

๐ŸŽ€ SvPV_shrink_to_cur

Okay bestie, this one trims off any trailing unused memory in the PV of sv โ€” but like, sv has to have a real PV that isn't tied up in stuff like COW. And listen, think before you touch this. Asking yourself two things first: is that space saving actually worth giving up COW for? And will the size sv needs just stay the same?

If the answer to both is yes, then run "SV_CHECK_THINKFIRST" or "SV_CHECK_THINKFIRST_COW_DROP" before calling this. Periodt.

 void  SvPV_shrink_to_cur(SV* sv)

โœจ SvPVbyte*

Described under "SvPV". ๐Ÿ’…

SvPVbyte_force*

Described under "SvPV_force".

๐ŸŒธ SvPVbyte_nolen*, SvPVbyte_nomg*, SvPVbyte_or_null*, SvPVbyte_or_null_nomg*, SvPVbytex*

All described under "SvPV".

SvPVbytex_force*

Described under "SvPV_force".

SvPVbytex_nolen*

Described under "SvPV".

๐Ÿ’– SvPVCLEAR

Makes sure sv is an SVt_PV, that its SvCUR is 0, and that it's properly null terminated. It's giving sv_setpvs("") but, like, more efficient. Slay.

 char *  SvPVCLEAR(SV* sv)

SvPVCLEAR_FRESH

Same vibe as SvPVCLEAR, except it's optimized for brand-new SVt_PV/PVIV/PVNV/PVMG SVs that already have a PV buffer allocated but no SvTHINKFIRST. Fresh out the box โœจ

 char *  SvPVCLEAR_FRESH(SV* sv)

SvPVutf8*

Described under "SvPV".

SvPVutf8_force*

Described under "SvPV_force".

๐ŸŒˆ SvPVutf8_nolen*, SvPVutf8_nomg*, SvPVutf8_or_null*, SvPVutf8_or_null_nomg*, SvPVutf8x*

All described under "SvPV".

SvPVutf8x_force*

Described under "SvPV_force".


๐Ÿ‘‘ SvPVX, SvPVX_const, SvPVX_mutable, SvPVXx

These hand you back a pointer to the physical string inside the SV. The SV must contain a string, ok? And heads up: before 5.9.3 it was not safe to run these unless the SV's type was >= SVt_PV.

They're also used to stash the name of an autoloaded subroutine inside an XS AUTOLOAD routine โ€” peep "Autoloading with XSUBs" in perlguts for that.

SvPVXx is identical to SvPVX.

SvPVX_mutable is literally just a synonym for SvPVX, but the name is there to shout that the caller can modify the string.

SvPVX_const is different in that the return value got cast so the compiler will yell at you if you try to modify the string's contents (unless you cast away const yourself, wild behaviour).

 char*        SvPVX        (SV* sv)
 const char*  SvPVX_const  (SV* sv)
 char*        SvPVX_mutable(SV* sv)
 char*        SvPVXx       (SV* sv)

๐Ÿ’œ SvPVx*, SvPVx_const*

Described under "SvPV".

SvPVx_force*

Described under "SvPV_force".

SvPVx_nolen*, SvPVx_nolen_const*

Described under "SvPV".

๐Ÿฆ‹ SvPVXtrue

Returns a boolean answering whether sv contains a PV that counts as TRUE. You get FALSE back if sv doesn't contain a PV at all, or if the PV it does have is zero length, or if it's just the single character '0'. Every other PV value is considered TRUE.

As of Perl v5.37.1, sv gets evaluated exactly once โ€” in earlier releases it could get evaluated more than once. no cap.

 bool       SvPVXtrue(      SV *sv)
 bool  Perl_SvPVXtrue(pTHX_ SV *sv)

SvPVXx*

Described under "SvPVX".

๐Ÿ”ฅ SvREADONLY

Returns true if the argument is readonly, false otherwise. It's exposed to perl code through Internals::SvREADONLY().

 U32  SvREADONLY(SV* sv)

SvREADONLY_off

Marks an object as not-readonly. Exactly what that means depends on the object type, iykyk. Exposed to perl code via Internals::SvREADONLY().

 U32  SvREADONLY_off(SV* sv)

SvREADONLY_on

Marks an object as readonly. Exactly what that means depends on the object type. Exposed to perl code via Internals::SvREADONLY().

 U32  SvREADONLY_on(SV* sv)

๐ŸŒŸ SvREFCNT

Returns the value of the object's reference count. Exposed to perl code via Internals::SvREFCNT().

 U32  SvREFCNT(SV* sv)

๐Ÿ’€ SvREFCNT_dec, SvREFCNT_dec_set_NULL, SvREFCNT_dec_ret_NULL, SvREFCNT_dec_NN

These decrement the reference count of the SV you give them.

SvREFCNT_dec_NN is only allowed when sv is known to not be NULL.

The function SvREFCNT_dec_ret_NULL() is identical to SvREFCNT_dec() except it returns a NULL SV *. It's used by SvREFCNT_dec_set_NULL(), which is a macro that โ€” when you hand it a non-NULL argument โ€” decrements the ref count of its argument and then sets it to NULL. So like, you can swap code shaped like this:

 if (sv) {
    SvREFCNT_dec_NN(sv);
    sv = NULL;
 }

for this:

 SvREFCNT_dec_set_NULL(sv);
 void       SvREFCNT_dec         (      SV *sv)
 void  Perl_SvREFCNT_dec         (pTHX_ SV *sv)
 void       SvREFCNT_dec_set_NULL(      SV *sv)
 void  Perl_SvREFCNT_dec_set_NULL(pTHX_ SV *sv)
 SV *       SvREFCNT_dec_ret_NULL(      SV *sv)
 SV *  Perl_SvREFCNT_dec_ret_NULL(pTHX_ SV *sv)
 void       SvREFCNT_dec_NN      (      SV *sv)
 void  Perl_SvREFCNT_dec_NN      (pTHX_ SV *sv)

๐Ÿซถ SvREFCNT_inc, SvREFCNT_inc_NN, SvREFCNT_inc_simple, SvREFCNT_inc_simple_NN, SvREFCNT_inc_simple_void, SvREFCNT_inc_simple_void_NN, SvREFCNT_inc_void, SvREFCNT_inc_void_NN

These all bump up the ref count of the SV you pass in. The ones without void in their names return the SV.

SvREFCNT_inc is the base operation โ€” the rest are just optimizations for when you already know certain things about the input hold true. Which means, yeah, all of them can be replaced with SvREFCNT_inc.

SvREFCNT_inc_NN can only be used if you know sv isn't NULL. Since there's no NULLness to check, it's faster and smaller.

SvREFCNT_inc_void can only be used if you don't need the return value โ€” the macro doesn't have to return anything meaningful.

SvREFCNT_inc_void_NN can only be used if you both don't need the return value and know sv isn't NULL. No meaningful return value needed, no NULLness check needed, so it's smaller and faster.

SvREFCNT_inc_simple can only be used with expressions that have no side effects. Since there's no temporary value to store, it's faster.

SvREFCNT_inc_simple_NN can only be used with side-effect-free expressions where you also know sv isn't NULL. No temp value to store, no NULLness to check โ€” faster and smaller.

SvREFCNT_inc_simple_void can only be used with side-effect-free expressions, and you don't need the return value.

SvREFCNT_inc_simple_void_NN can only be used with side-effect-free expressions, where you don't need the return value, and you know sv isn't NULL.

 SV *       SvREFCNT_inc               (SV *sv)
 SV *  Perl_SvREFCNT_inc               (SV *sv)
 SV *       SvREFCNT_inc_NN            (SV *sv)
 SV *  Perl_SvREFCNT_inc_NN            (SV *sv)
 SV *       SvREFCNT_inc_simple        (SV *sv)
 SV *       SvREFCNT_inc_simple_NN     (SV *sv)
 void       SvREFCNT_inc_simple_void   (SV *sv)
 void       SvREFCNT_inc_simple_void_NN(SV *sv)
 void       SvREFCNT_inc_void          (SV *sv)
 void  Perl_SvREFCNT_inc_void          (SV *sv)
 void       SvREFCNT_inc_void_NN       (SV *sv)

๐Ÿงš SvRMAGICAL

Returns a U32 value telling you whether the SV has RANDOM magic assigned.

This is, like, the catch-all category for magic that isn't GET, SET, or ACTIVE magic. Go check perltie for some examples of other magical methods.

 U32  SvRMAGICAL(SV* sv)

โญ SvROK

Tests whether the SV is an RV.

 U32  SvROK(SV* sv)

SvROK_off

Unsets the RV status of an SV.

 void  SvROK_off(SV* sv)

SvROK_on

Tells an SV that it is an RV.

 void  SvROK_on(SV* sv)

๐Ÿ’ซ SvRV

Dereferences an RV so you get the SV back.

 SV*  SvRV(SV* sv)

SvRV_set

Sets the value of the RV pointer inside sv to val. Check "SvIV_set" for the full lore.

 void  SvRV_set(SV* sv, SV* val)

๐Ÿ”ฎ SvSETMAGIC

Invokes mg_set on an SV if it has 'set' magic. You need this after modifying a scalar, in case it's a magical variable like $| or a tied variable (it calls STORE). And psst โ€” this macro evaluates its argument more than once.

 void  SvSETMAGIC(SV* sv)

๐ŸŒบ SvSetMagicSV, SvSetMagicSV_nosteal, SvSetSV, SvSetSV_nosteal

If dsv is the same as ssv, these do absolutely nothing. Otherwise they all call some form of sv_setsv. Careful though: they may evaluate their arguments more than once.

The only differences are:

  • SvSetMagicSV and SvSetMagicSV_nosteal perform any required 'set' magic afterwards on the destination SV; SvSetSV and SvSetSV_nosteal do not.
  • SvSetSV_nosteal and SvSetMagicSV_nosteal call a non-destructive version of sv_setsv.
 void  SvSetMagicSV        (SV* dsv, SV* ssv)
 void  SvSetMagicSV_nosteal(SV* dsv, SV* ssv)
 void  SvSetSV             (SV* dsv, SV* ssv)
 void  SvSetSV_nosteal     (SV* dsv, SV* ssv)

๐Ÿ“ SvSHARE

Arranges for sv to be shared between threads โ€” if a suitable module has been loaded.

 void  SvSHARE(SV* sv)

SvSHARED_HASH

Returns the hash for sv created by newSVpvn_share.

 struct hek*  SvSHARED_HASH(SV * sv)

๐Ÿ’… SvSMAGICAL

Returns a U32 value telling you whether the SV has SET magic assigned.

This is typically used right after assigning a value to the SV, usually via SvSETMAGIC().

SET magic could influence how or where a value is stored, transform the stored value, or trigger post-assignment functionality. Sneaky lil thing.

 U32  SvSMAGICAL(SV* sv)

๐ŸŒธ SvSTASH

Returns the stash of the SV.

 HV*  SvSTASH(SV* sv)

SvSTASH_set

Sets the value of the STASH pointer inside sv to val. See "SvIV_set".

 void  SvSTASH_set(SV* sv, HV* val)

๐Ÿ’– SvTRUE, SvTRUE_NN, SvTRUE_nomg, SvTRUE_nomg_NN, SvTRUEx

These return a boolean telling you whether Perl would evaluate the SV as true or false. Wanna test defined/undefined instead? That's "SvOK".

As of Perl 5.32, literally all of these are guaranteed to evaluate sv only once. Before that release, only SvTRUEx guaranteed single evaluation โ€” and now SvTRUEx is identical to SvTRUE.

SvTRUE_nomg and TRUE_nomg_NN do not perform 'get' magic; the others do, unless the scalar is already SvPOK, SvIOK, or SvNOK (the public flags, not the private ones).

  • SvTRUE_NN is giving SvTRUE energy, but bestie โ€” it assumes sv is non-null (NN). If there's literally any chance it's NULL, use plain SvTRUE instead, no cap. ๐Ÿ™ˆ
  • SvTRUE_nomg_NN is like SvTRUE_nomg, but again, sv is assumed to be non-null (NN). And again โ€” if it might be NULL, use plain SvTRUE_nomg. Simple. ๐Ÿ’…
 bool       SvTRUE        (      SV *sv)
 bool  Perl_SvTRUE        (pTHX_ SV *sv)
 bool       SvTRUE_NN     (      SV *sv)
 bool  Perl_SvTRUE_NN     (pTHX_ SV *sv)
 bool       SvTRUE_nomg   (      SV *sv)
 bool  Perl_SvTRUE_nomg   (pTHX_ SV *sv)
 bool       SvTRUE_nomg_NN(      SV *sv)
 bool       SvTRUEx       (      SV *sv)
  • SvTYPE โ€” hands you back the type of the SV. Go look at svtype for the deets. โœจ
 svtype  SvTYPE(SV* sv)
  • SvUNLOCK โ€” releases a mutual exclusion lock on sv, but only if a suitable module has actually been loaded. Teamwork, kinda. ๐Ÿซถ
 void  SvUNLOCK(SV* sv)
  • SvUOK โ€” returns a boolean telling you whether the SV holds an integer that has to be read as unsigned. Little note for the girlies: a non-negative integer whose value is inside the range of both an IV and a UV might get flagged as either SvUOK or SvIOK. So don't be surprised. ๐Ÿ’ซ
 bool  SvUOK(SV* sv)
  • SvUPGRADE โ€” used to glow-up an SV into a more complex form. It calls sv_upgrade to do the actual upgrade if it's needed. Check svtype for the lore. ๐Ÿ“ˆ
 void  SvUPGRADE(SV* sv, svtype type)
  • SvUTF8 โ€” returns a U32 value telling you the UTF-8 status of an SV. If everything's set up properly, this says whether or not the SV contains UTF-8 encoded data. Pro move: use this after a call to SvPV or one of its variants, just in case any string overloading call updated the internal flag behind your back. ๐Ÿ˜ญ

And if you want to take the bytes pragma into account, use DO_UTF8 instead. iykyk.

 U32  SvUTF8(SV* sv)
  • SvUTF8_off โ€” unsets the UTF-8 status of an SV. The data is not changed, just the flag, bestie. And do not use this frivolously. โš ๏ธ
 void  SvUTF8_off(SV *sv)
  • SvUTF8_on โ€” turns on the UTF-8 status of an SV. Again: the data is not changed, just the flag. And again: do not use this frivolously. ๐Ÿ™…โ€โ™€๏ธ
 void  SvUTF8_on(SV *sv)
  • SvUV, SvUV_nomg, SvUVx โ€” each of these coerces the given SV to a UV and returns it. Real talk: in lots of circumstances the returned value will get stored in sv's UV slot, but not in all cases. (If you need to be sure it does, use sv_setuv.) ๐Ÿ’พ

As of 5.37.1, all of them are guaranteed to evaluate sv only once. Slay.

SvUVx is now identical to SvUV, but prior to 5.37.1, it was the only form guaranteed to evaluate sv only once. History, babe. ๐ŸŽ€

 UV       SvUV     (      SV *sv)
 UV  Perl_SvUV     (pTHX_ SV *sv)
 UV       SvUV_nomg(      SV *sv)
 UV  Perl_SvUV_nomg(pTHX_ SV *sv)
 UV       SvUVx    (      SV *sv)
  • SvUV_set โ€” sets the value of the UV pointer in sv to val. Same vibe as SvIV_set, go read that one. ๐Ÿซถ
 void  SvUV_set(SV* sv, UV val)
  • SvUVX, SvUVXx โ€” each of these returns the raw value in the SV's UV slot, with no checks and no conversions. Only use when you're 100% sure SvUOK is true. See also SvUV. And note: SvUVXx is an unnecessary synonym for SvUVX. That's it, that's the whole thing. ๐Ÿ’€
DEPRECATED! It is planned to remove SvUVXx from a future release of Perl. Do not use it for new code; remove it from existing code. Periodt. ๐Ÿšซ
 UV  SvUVX (SV* sv)
 UV  SvUVXx(SV* sv)
  • SvUVx* โ€” described under SvUV (scroll up, gorgeous โœจ).
  • SvVOK โ€” returns a boolean telling you whether the SV contains a v-string. ๐ŸŽ€
 bool  SvVOK(SV* sv)
  • SvVSTRING_mg โ€” returns the vstring magic, or NULL if there isn't any. ๐Ÿ”ฎ
 MAGIC*  SvVSTRING_mg(SV * sv)
  • uiv_2buf โ€” this function converts an IV or UV into its string representation. It's used internally by sv_2pv_flags() and do_print(). Backstage crew energy. ๐ŸŽฌ
 char *       uiv_2buf(char * const buf, const IV iv, UV uv,
                       const int is_uv, char ** const peob)
 char *  Perl_uiv_2buf(char * const buf, const IV iv, UV uv,
                       const int is_uv, char ** const peob)
  • vnewSVpvf* โ€” described under newSVpvf (go peek, bestie ๐Ÿ’œ).

โœจ Tainting โœจ

  • SvTAINT โ€” taints an SV if tainting is enabled and if some input to the current expression is tainted. Usually that's a variable, but it could also be implicit input like locale settings. SvTAINT propagates that taintedness to the outputs of an expression in a pessimistic fashion โ€” meaning it does not pay attention to precisely which outputs are influenced by which inputs. It's just out here tainting everything to be safe. ๐Ÿ˜ค
 void  SvTAINT(SV* sv)
  • SvTAINTED โ€” checks to see if an SV is tainted. Returns TRUE if it is, FALSE if it's not. Vibe check on the taint. ๐Ÿ”
 bool  SvTAINTED(SV* sv)
  • SvTAINTED_off โ€” untaints an SV. Okay so, be very careful with this one, because it short-circuits some of Perl's fundamental security features. ๐Ÿ˜ญ XS module authors should not use this function unless they fully understand all the implications of unconditionally untainting the value. Untainting should be done in the standard perl fashion โ€” via a carefully crafted regexp โ€” rather than directly untainting variables. Like, don't do the dangerous thing just because it's shorter. ๐Ÿšจ
 void  SvTAINTED_off(SV* sv)
  • SvTAINTED_on โ€” marks an SV as tainted if tainting is enabled. ๐ŸŒธ
 void  SvTAINTED_on(SV* sv)

โฐ Time โฐ

  • ASCTIME_R_PROTO โ€” this symbol encodes the prototype of asctime_r. It's zero if d_asctime_r is undef, and it's one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_asctime_r is defined. ๐Ÿ’…
  • CTIME_R_PROTO โ€” this symbol encodes the prototype of ctime_r. Zero if d_ctime_r is undef, and one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_ctime_r is defined. ๐ŸŽ€
  • GMTIME_MAX โ€” this symbol contains the maximum value for the time_t offset that the system function gmtime () accepts, and it defaults to 0. ๐Ÿ”
  • GMTIME_MIN โ€” this symbol contains the minimum value for the time_t offset that the system function gmtime () accepts, and it defaults to 0. ๐Ÿ”ฝ
  • GMTIME_R_PROTO โ€” this symbol encodes the prototype of gmtime_r. Zero if d_gmtime_r is undef, one of the REENTRANT_PROTO_T_ABC macros of reentr.h if d_gmtime_r is defined. โœจ
  • HAS_ASCTIME_R โ€” this symbol, if defined, indicates that the asctime_r routine is available to asctime re-entrantly. ๐Ÿ”
  • HAS_ASCTIME64 โ€” this symbol, if defined, indicates that the asctime64 () routine is available to do the 64bit variant of asctime (). ๐Ÿงฎ
  • HAS_CTIME_R โ€” this symbol, if defined, indicates that the ctime_r routine is available to ctime re-entrantly. ๐Ÿ”
  • HAS_CTIME64 โ€” this symbol, if defined, indicates that the ctime64 () routine is available to do the 64bit variant of ctime (). ๐Ÿงฎ
  • HAS_DIFFTIME โ€” this symbol, if defined, indicates that the difftime routine is available. โฑ๏ธ
  • HAS_DIFFTIME64 โ€” this symbol, if defined, indicates that the difftime64 () routine is available to do the 64bit variant of difftime (). ๐Ÿงฎ
  • HAS_FUTIMES โ€” this symbol, if defined, indicates that the futimes routine is available to change file descriptor time stamps with struct timevals. ๐Ÿ•ฐ๏ธ
  • HAS_GETITIMER โ€” this symbol, if defined, indicates that the getitimer routine is available to return interval timers. โฒ๏ธ
  • HAS_GETTIMEOFDAY โ€” this symbol, if defined, indicates that the gettimeofday() system call is available for a sub-second accuracy clock. Heads up: usually the file sys/resource.h needs to be included (see I_SYS_RESOURCE). And the type Timeval should be used to refer to "struct timeval". ๐ŸŒˆ
  • HAS_GMTIME_R โ€” this symbol, if defined, indicates that the gmtime_r routine is available to gmtime re-entrantly. ๐Ÿ”
  • HAS_GMTIME64 โ€” this symbol, if defined, indicates that the gmtime64 () routine is available to do the 64bit variant of gmtime (). ๐Ÿงฎ
  • HAS_LOCALTIME_R โ€” this symbol, if defined, indicates that the localtime_r routine is available to localtime re-entrantly. ๐Ÿ”
  • HAS_LOCALTIME64 โ€” this symbol, if defined, indicates that the localtime64 () routine is available to do the 64bit variant of localtime (). ๐Ÿงฎ
  • HAS_MKTIME โ€” this symbol, if defined, indicates that the mktime routine is available. ๐Ÿ—“๏ธ
  • HAS_MKTIME64 โ€” this symbol, if defined, indicates that the mktime64 () routine is available to do the 64bit variant of mktime (). ๐Ÿงฎ
  • HAS_NANOSLEEP โ€” this symbol, if defined, indicates that the nanosleep system call is available to sleep with 1E-9 sec accuracy. So precise. ๐Ÿ˜ด
  • HAS_SETITIMER โ€” this symbol, if defined, indicates that the setitimer routine is available to set interval timers. โฒ๏ธ
  • HAS_STRFTIME โ€” this symbol, if defined, indicates that the strftime routine is available to do time formatting. โœจ
  • HAS_TIME โ€” this symbol, if defined, indicates that the time() routine exists. ๐Ÿ•
  • HAS_TIMEGM โ€” this symbol, if defined, indicates that the timegm routine is available to do the opposite of gmtime (). ๐Ÿ”„
  • HAS_TIMES โ€” this symbol, if defined, indicates that the times() routine exists. Little tea: it became obsolete on some systems (SUNOS), which now use getrusage(). It may be necessary to include sys/times.h. ๐Ÿ‘€
  • HAS_TM_TM_GMTOFF โ€” this symbol, if defined, indicates to the C program that the struct tm has a tm_gmtoff field. ๐ŸŒ
  • HAS_TM_TM_ZONE โ€” this symbol, if defined, indicates to the C program that the struct tm has a tm_zone field. ๐ŸŒ
  • HAS_TZNAME โ€” this symbol, if defined, indicates that the tzname[] array is available to access timezone names. ๐Ÿ—บ๏ธ
  • HAS_USLEEP โ€” this symbol, if defined, indicates that the usleep routine is available to let the process sleep on a sub-second accuracy. ๐Ÿ’ค
  • HAS_USLEEP_PROTO โ€” this symbol, if defined, indicates that the system provides a prototype for the usleep() function. Otherwise, it's up to the program to supply one. A good guess is:
 extern int usleep(useconds_t);
  • I_TIME โ€” this symbol is always defined, and it indicates to the C program that it should include time.h. Periodt.
 #ifdef I_TIME
     #include <time.h>
 #endif
  • I_UTIME โ€” this symbol, if defined, indicates to the C program that it should include utime.h. ๐Ÿ•ฐ๏ธ
 #ifdef I_UTIME
     #include <utime.h>
 #endif
  • L_R_TZSET โ€” if localtime_r() needs tzset, it is defined in this define. ๐ŸŒ
  • LOCALTIME_MAX โ€” this symbol contains the maximum value for the time_t offset that the system function localtime () accepts, and it defaults to 0. ๐Ÿ”
  • "LOCALTIME_MIN" โ€” this lil symbol holds the minimum value for the time_t offset that the system's localtime() function will actually accept, and it defaults to 0. basically the floor of what the system vibes with. ๐Ÿ•
  • "LOCALTIME_R_NEEDS_TZSET" โ€” ok so here's the drama: a lot of libc localtime_r implementations just do not call tzset, which makes them behave differently from plain localtime(). the messy consequence is that you can't change timezones with $ENV{TZ} unless you explicitly call tzset yourself. this symbol makes perl call tzset before localtime_r so the whole thing works. no cap. ๐ŸŒ
  • "LOCALTIME_R_PROTO" โ€” this one encodes the prototype of localtime_r. it's 0 if d_localtime_r is undef, and if d_localtime_r is defined it's one of the REENTRANT_PROTO_T_ABC macros from reentr.h. ๐Ÿงฌ

"mini_mktime" โœจ

normalises struct tm values โ€” but without the localtime() semantics (and the overhead ๐Ÿ˜ฎโ€๐Ÿ’จ) that mktime() drags along with it.

 void       mini_mktime(struct tm *ptm)
 void  Perl_mini_mktime(struct tm *ptm)

"sv_strftime_ints", "sv_strftime_tm", "my_strftime" ๐Ÿ’–

these three implement libc strftime(), but they fix up a bunch of the deficiencies it has. bestie, you will come to regret sooner or later ever using libc's directly instead of these. trust. ๐Ÿ™ˆ

on failure they return NULL, and set errno to EINVAL.

sv_strftime_tm and sv_strftime_ints are the preferred ones, because they transparently handle the UTF-8ness of the current locale, of the input fmt, and of the returned result. only if the current LC_TIME locale is a UTF-8 one (and use bytes is not in effect) will the result be marked as UTF-8. ๐Ÿ’…

for these, the caller assumes ownership of the returned SV with a reference count of 1.

my_strftime is kept around for backwards compatibility. knowing whether its result should be considered UTF-8 or not requires a significant amount of extra logic. ๐Ÿ˜ญ

heads up: all three of these functions always execute in the underlying LC_TIME locale of the program, so the results are based on that locale. periodt.

the stringified fmt parameter in all of them is the same as the system libc strftime. the available conversion specifications vary by platform. these days, every specification listed in the ANSI C99 standard should be usable everywhere. those are a A b B c d H I j m M p S U w W x X y Y Z %. ๐ŸŒˆ

but note that some of those conversion specifiers give non-portable results. for example, a A b B c p Z change according to the locale settings of the user, and neither how to set locales (the locale names) nor what output to expect is standardized. the c specifier changes according to the user's timezone settings and the operating system's timezone computation rules. and Z is notoriously unportable since timezone names aren't standardized. sticking to the numeric specifiers is the safest route. ๐Ÿ›ฃ๏ธ

at the time of this writing, for example, %s is not available on Windows-like systems.

the functions differ as follows: ๐Ÿ‘‡

  • the fmt parameter and the return from my_strftime are char * instead of the SV * in the other two functions. this means the UTF-8ness of the format and the result are unspecified. the result MUST be arranged to be FREED BY THE CALLER). ๐Ÿ’€
  • sv_strftime_ints and my_strftime take a bunch of integer parameters that together completely define a given time. they calculate the struct tm to pass to libc strftime(), and call that function. see below for the meaning of the parameters.

sv_strftime_tm takes a pointer to an already filled-in struct tm parameter, so it skips that calculation. โœจ

  • my_strftime takes two extra parameters that are ignored โ€” they're kept only for historical reasons. those are wday and yday.

the C99 Standard calls for struct tm to contain at least these fields:

 int tm_sec;    // seconds after the minute โ€” [0, 60]
 int tm_min;    // minutes after the hour โ€” [0, 59]
 int tm_hour;   // hours since midnight โ€” [0, 23]
 int tm_mday;   // day of the month โ€” [1, 31]
 int tm_mon;    // months since January โ€” [0, 11]
 int tm_year;   // years since 1900
 int tm_wday;   // days since Sunday โ€” [0, 6]
 int tm_yday;   // days since January 1 โ€” [0, 365]
 int tm_isdst;  // Daylight Saving Time flag

tm_wday and tm_yday are output only โ€” the other fields give enough info to accurately calculate them, and that's what they're internally used for. ๐Ÿง 

the numbers enclosed in the square brackets above give the maximum legal ranges for values in the corresponding field. those ranges are restricted for some inputs. for example, not all months have 31 days, but all hours have 60 minutes. if you set a number that's outside the corresponding range, perl and the libc functions will automatically normalise it to be inside the range, adjusting other values as necessary. for example, specifying February 29 is the same as saying March 1 for non-leap years; and using a minute value of 60 will instead change that to a 0, and increment the hour, which in turn, if the hour was 23, will roll it over to 0 and increment the day, and so on. ๐ŸŒ€

each parameter to sv_strftime_ints and my_strftime populates the similarly-named field in this structure.

a value of 60 is legal for tm_sec, but only for those moments when an official leap second has been declared. it's undefined behavior to use them otherwise, and the behavior does vary depending on the implementation. some implementations take your word for it that this is a leap second, leaving it as the 61st second of the given minute; some roll it over to be the 0th second of the following minute; some treat it as 0. some non-conforming implementations always roll it over to the next minute, regardless of whether an actual leap second is happening or not. (and yes, it is a real problem that different computers have a different conception of what the current time is; you can search the internet for details.) ๐Ÿ˜ตโ€๐Ÿ’ซ

there's no limit (outside the size of int) for the value of tm_year, but sufficiently negative values (for earlier than 1900) may give different results on different systems and locales. some libc implementations may know when a given locale adopted the Gregorian calendar, and adjust for that. others will not. (and some countries didn't adopt the Gregorian calendar until after 1900.) probably all implementations assume modern time zones go back forever, before they were actually invented, starting in the last half of the 19th century. ๐Ÿ•ฐ๏ธ

the treatment of the isdst field has varied over previous Perl versions, and has been buggy (both by perl and by some libc implementations), but is now aligned, as best as we can, with the POSIX Standard, like this: ๐Ÿ’…

  • isdst is 0 โ€” the function is to assume that daylight savings time is not in effect. this should now always work properly, since perl uses its own implementation in this case, avoiding the non-conforming libc ones. โœ…
  • isdst is >0 โ€” the function is to assume that daylight savings time is in effect, though some underlying libc implementations treat this as a hint instead of a mandate. ๐Ÿ™ƒ
  • isdst is <0 โ€” the function is to try to calculate for itself whether daylight savings time is in effect. more recent libc implementations are better at this than earlier ones. ๐Ÿ”

some libc implementations have extra fields in struct tm. the two that perl handles are:

 int tm_gmtoff;            // Seconds East of UTC [%z]
 const char * tm_zone;     // Timezone abbreviation [%Z]

these are both output only. using the respective conversion specifications (enclosed in the square brackets) in the fmt parameter is a portable way to gain access to these values, working both on systems that have and don't have these fields. ๐ŸŽ€

example, in the C locale:

 my_strftime( "%A, %B %d, %Y", 0, 0, 0, 12, 11, 95, 0, 0, -1 );

returns

 "Tuesday, December 12, 1995"
 SV *         sv_strftime_ints(      SV *fmt, int sec, int min,
                                     int hour, int mday, int mon,
                                     int year, int isdst)
 SV *    Perl_sv_strftime_ints(pTHX_ SV *fmt, int sec, int min,
                                     int hour, int mday, int mon,
                                     int year, int isdst)
 SV *         sv_strftime_tm  (      SV *fmt,
                                     const struct tm *mytm)
 SV *    Perl_sv_strftime_tm  (pTHX_ SV *fmt,
                                     const struct tm *mytm)
 char *       my_strftime     (      const char *fmt, int sec,
                                     int min, int hour, int mday,
                                     int mon, int year, int wday,
                                     int yday, int isdst)
 char *  Perl_my_strftime     (pTHX_ const char *fmt, int sec,
                                     int min, int hour, int mday,
                                     int mon, int year, int wday,
                                     int yday, int isdst)

โœจ Typedef names โœจ

Okay bestie, gather round. These are the typedef names from the config realm โ€” the portability besties that let your C code slay on whatever platform Perl was compiled on. Keep the names exactly as written, no rebranding, periodt. ๐Ÿ’…

  • DB_Hash_t โ€” this symbol holds the type of the prefix structure element in the db.h header file. In older versions of DB it was int, but newer ones switched it up to size_t. ๐Ÿ‘‘
  • DB_Prefix_t โ€” this symbol holds the type of the prefix structure element in the db.h header file. In older versions of DB it was int, while in newer ones it is u_int32_t. โœจ
  • Direntry_t โ€” this symbol is set to struct direct or struct dirent depending on whether dirent is available or not. You should use this pseudo type to portably declare your directory entries. ๐Ÿ“
  • Fpos_t โ€” this symbol holds the type used to declare file positions in libc. It can be fpos_t, long, uint, etc... It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿ“
  • Free_t โ€” this variable contains the return type of free(). It is usually void, but occasionally int. ๐Ÿงน
  • Gid_t โ€” this symbol holds the return type of getgid() and the type of argument to setrgid() and related functions. Typically, it is the type of group ids in the kernel. It can be int, ushort, gid_t, etc... It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿ‘ฏ
  • Gid_t_f โ€” this symbol defines the format string used for printing a Gid_t. ๐Ÿ–จ๏ธ
  • Gid_t_sign โ€” this symbol holds the signedness of a Gid_t. 1 for unsigned, -1 for signed. โš–๏ธ
  • Gid_t_size โ€” this symbol holds the size of a Gid_t in bytes. ๐Ÿ“
  • Groups_t โ€” this symbol holds the type used for the second argument to getgroups() and setgroups(). Usually, this is the same as gidtype (gid_t), but sometimes it isn't. It can be int, ushort, gid_t, etc... It may be necessary to include sys/types.h to get any typedef'ed information. This is only required if you have getgroups() or setgroups().. ๐Ÿซ‚
  • Malloc_t โ€” this symbol is the type of pointer returned by malloc and realloc. ๐Ÿง 
  • Mmap_t โ€” this symbol holds the return type of the mmap() system call (and simultaneously the type of the first argument). Usually set to void * or caddr_t. ๐Ÿ—บ๏ธ
  • Mode_t โ€” this symbol holds the type used to declare file modes for systems calls. It is usually mode_t, but may be int or unsigned short. It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿ”
  • Netdb_hlen_t โ€” this symbol holds the type used for the 2nd argument to gethostbyaddr(). ๐ŸŒ
  • Netdb_host_t โ€” this symbol holds the type used for the 1st argument to gethostbyaddr(). ๐Ÿ 
  • Netdb_name_t โ€” this symbol holds the type used for the argument to gethostbyname(). ๐Ÿท๏ธ
  • Netdb_net_t โ€” this symbol holds the type used for the 1st argument to getnetbyaddr(). ๐Ÿ•ธ๏ธ
  • Off_t โ€” this symbol holds the type used to declare offsets in the kernel. It can be int, long, off_t, etc... It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿ“Œ
  • Off_t_size โ€” this symbol holds the number of bytes used by the Off_t. ๐Ÿ“
  • Pid_t โ€” this symbol holds the type used to declare process ids in the kernel. It can be int, uint, pid_t, etc... It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿงฌ
  • Rand_seed_t โ€” this symbol defines the type of the argument of the random seed function. ๐ŸŽฒ
  • Select_fd_set_t โ€” this symbol holds the type used for the 2nd, 3rd, and 4th arguments to select. Usually, this is fd_set *, if HAS_FD_SET is defined, and int * otherwise. This is only useful if you have select(), of course. ๐Ÿ‘€
  • Shmat_t โ€” this symbol holds the return type of the shmat() system call. Usually set to void * or char *. ๐Ÿงฒ
  • Signal_t โ€” this symbol's value is either void or int, corresponding to the appropriate return type of a signal handler. Thus, you can declare a signal handler using Signal_t (*handler)(), and define the handler using Signal_t handler(sig). ๐Ÿšจ
  • Size_t โ€” this symbol holds the type used to declare length parameters for string functions. It is usually size_t, but may be unsigned long, int, etc. It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿ“ฆ
  • Size_t_size โ€” this symbol holds the size of a Size_t in bytes. ๐Ÿ“
  • Sock_size_t โ€” this symbol holds the type used for the size argument of various socket calls (just the base type, not the pointer-to). ๐Ÿงฆ
  • SSize_t โ€” this symbol holds the type used by functions that return a count of bytes or an error condition. It must be a signed type. It is usually ssize_t, but may be long or int, etc. It may be necessary to include sys/types.h or unistd.h to get any typedef'ed information. We will pick a type such that sizeof(SSize_t) == sizeof(Size_t). โœ๏ธ
  • Time_t โ€” this symbol holds the type returned by time(). It can be long, or time_t on BSD sites (in which case sys/types.h should be included). โฐ
  • Uid_t โ€” this symbol holds the type used to declare user ids in the kernel. It can be int, ushort, uid_t, etc... It may be necessary to include sys/types.h to get any typedef'ed information. ๐Ÿง‘โ€๐Ÿ’ป
  • Uid_t_f โ€” this symbol defines the format string used for printing a Uid_t. ๐Ÿ–จ๏ธ
  • Uid_t_sign โ€” this symbol holds the signedness of a Uid_t. 1 for unsigned, -1 for signed. โš–๏ธ
  • Uid_t_size โ€” this symbol holds the size of a Uid_t in bytes. ๐Ÿ“

๐Ÿฆ‹ Unicode Support ๐ŸŒธ

Unicode Support in perlguts has an introduction to this API, so go sip that tea if you want the full lore. โ˜•

See also Character classification, Character case changing, and String Handling. Various functions outside this section also work specially with Unicode. Search for the string utf8 in this document. ๐Ÿ”

  • BOM_UTF8 โ€” this is a macro that evaluates to a string constant of the UTF-8 bytes that define the Unicode BYTE ORDER MARK (U+FEFF) for the platform that perl is compiled on. This allows code to use a mnemonic for this character that works on both ASCII and EBCDIC platforms. sizeof(BOM_UTF8) - 1 can be used to get its length in bytes. ๐ŸŒˆ
  • bytes_cmp_utf8 โ€” compares the sequence of characters (stored as octets) in b, blen with the sequence of characters (stored as UTF-8) in u, ulen. Returns 0 if they are equal, -1 or -2 if the first string is less than the second string, +1 or +2 if the first string is greater than the second string. โœจ

-1 or +1 is returned if the shorter string was identical to the start of the longer string. -2 or +2 is returned if there was a difference between characters within the strings. ๐Ÿ’…

            int       bytes_cmp_utf8(      const U8 *b, STRLEN blen,
                                           const U8 *u, STRLEN ulen)
            int  Perl_bytes_cmp_utf8(pTHX_ const U8 *b, STRLEN blen,
                                           const U8 *u, STRLEN ulen)
  • bytes_from_utf8* โ€” described under utf8_to_bytes_overwrite. ๐Ÿ”
  • bytes_to_utf8, bytes_to_utf8_free_me, bytes_to_utf8_temp_pv โ€” these each convert a string s of length *lenp bytes from the native encoding into UTF-8 (UTF-EBCDIC on EBCDIC platforms), returning a pointer to the UTF-8 string, and setting *lenp to its length in bytes. ๐Ÿฆ‹
    • bytes_to_utf8 always allocates new memory for the result, making sure it is NUL-terminated.
    • bytes_to_utf8_free_me simply returns a pointer to the input string if the string's UTF-8 representation is the same as its native representation. Otherwise, it behaves like bytes_to_utf8, returning a pointer to new memory containing the conversion of the input. In other words, it returns the input string if converting the string would be a no-op. Note that when no new string is allocated, the function can't add a NUL to the original string if one wasn't already there.
    • In both cases, the caller is responsible for arranging for any new memory to get freed.
    • bytes_to_utf8_temp_pv simply returns a pointer to the input string if the string's UTF-8 representation is the same as its native representation, thus behaving like bytes_to_utf8_free_me in this situation. Otherwise, it behaves like bytes_to_utf8, returning a pointer to new memory containing the conversion of the input. The difference is that it also arranges for the new memory to automatically be freed by calling SAVEFREEPV on it.
    • bytes_to_utf8_free_me takes an extra parameter, free_me to communicate to the caller that memory was allocated or not. If that parameter is NULL, bytes_to_utf8_free_me acts identically to bytes_to_utf8, always allocating new memory.

But when it is a non-NULL pointer, bytes_to_utf8_free_me stores into it either NULL if no memory was allocated; or a pointer to that new memory. This allows the following convenient paradigm: ๐ŸŽ€

            void * free_me;
            U8 converted = bytes_to_utf8_free_me(string, &len, &free_me);

            ...

            Safefree(free_me);

You don't have to know if memory was allocated or not. Just call Safefree unconditionally. free_me will contain a suitable value to pass to Safefree for it to do the right thing, regardless. Your design is likely flawed if you find yourself using free_me for anything other than passing to Safefree. ๐Ÿ’€

Upon return, the number of variants in the string can be computed by having saved the value of *lenp before the call, and subtracting the after-call value of *lenp from it. ๐Ÿงฎ

If you want to convert to UTF-8 from encodings other than the native (Latin1 or EBCDIC), see sv_recode_to_utf8(). ๐Ÿ”„

            U8 *       bytes_to_utf8        (      const U8 *s, STRLEN *lenp)
            U8 *  Perl_bytes_to_utf8        (pTHX_ const U8 *s, STRLEN *lenp)
            U8 *       bytes_to_utf8_free_me(      const U8 *s, STRLEN *lenp,
                                                   void **free_me)
            U8 *  Perl_bytes_to_utf8_free_me(pTHX_ const U8 *s, STRLEN *lenp,
                                                   void **free_me)
            U8 *       bytes_to_utf8_temp_pv(      const U8 *s, STRLEN *lenp)
            U8 *  Perl_bytes_to_utf8_temp_pv(pTHX_ const U8 *s, STRLEN *lenp)
  • c9strict_utf8_to_uv* โ€” described under utf8_to_uv. ๐Ÿงš
  • DO_UTF8 โ€” returns a bool giving whether or not the PV in sv is to be treated as being encoded in UTF-8. ๐Ÿ’œ

You should use this after a call to SvPV() or one of its variants, in case any call to string overloading updates the internal UTF-8 encoding flag.

            bool  DO_UTF8(SV* sv)

"extended_utf8_to_uv*"

okay bestie this one's just a lil redirect ๐Ÿ’ซ โ€” it's Described under "utf8_to_uv". go read that one, it's the same tea.


"foldEQ_utf8"

this one is giving comparison gatekeeper โœจ it returns true if the leading portions of the strings s1 and s2 โ€” and yes, either or BOTH of them can be in UTF-8, no biggie โ€” are the same case-insensitively; false otherwise. how far into the strings you actually compare? that's decided by the other input parameters, so let's get into it ๐Ÿซถ

  • if u1 is true, the string s1 is assumed to be in UTF-8-encoded Unicode; otherwise it's assumed to be in native 8-bit encoding. and when we say "correspondingly for u2 with respect to s2" โ€” yeah, exact same deal for the second string, icon behaviour ๐Ÿ’…
  • if the byte length l1 is non-zero, it says how far into s1 to check for fold equality. in other words, s1+l1 gets used as a goal to reach. the scan will not count as a match unless the goal is reached, and scanning won't continue past that goal. Correspondingly for l2 with respect to s2, obviously ๐ŸŒธ
  • if pe1 is non-NULL and the pointer it points to is not NULL, that pointer is treated as an end pointer to the position 1 byte past the maximum point in s1 beyond which scanning will not continue under any circumstances. (this routine assumes that UTF-8 encoded input strings are not malformed โ€” literally, malformed input can cause it to read past pe1, so be careful babes ๐Ÿ˜ญ). this means that if both l1 and pe1 are specified, and pe1 is less than s1+l1, the match will never be successful, because it can never get as far as its goal (and in fact is asserted against). Correspondingly for pe2 with respect to s2.
  • at least one of s1 and s2 must have a goal (so at least one of l1 and l2 must be non-zero), and if both do, both have to be reached for a successful match. also, if the fold of a character is multiple characters, all of them must be matched (peep the tr21 reference below for 'folding' โ€” it's the receipts).
  • upon a successful match, if pe1 is non-NULL, it gets set to point to the beginning of the next character of s1 beyond what was matched. Correspondingly for pe2 and s2 ๐Ÿ’–
  • for case-insensitiveness, the "casefolding" of Unicode is used instead of upper/lowercasing both the characters, see https://www.unicode.org/reports/tr21/ (Case Mappings) ๐Ÿ‘‘
 I32       foldEQ_utf8(      const char *s1, char **pe1, UV l1,
                             bool u1, const char *s2, char **pe2,
                             UV l2, bool u2)
 I32  Perl_foldEQ_utf8(pTHX_ const char *s1, char **pe1, UV l1,
                             bool u1, const char *s2, char **pe2,
                             UV l2, bool u2)

"is_ascii_string*"

Described under "is_utf8_invariant_string" โ€” go check that section, bestie, it's right below ๐Ÿฆ‹


"is_c9strict_utf8_string*", "is_c9strict_utf8_string_loc*", "is_c9strict_utf8_string_loclen*"

all three of these โœจ Described under "is_utf8_string". same vibe, different strictness.


"is_invariant_string*"

Described under "is_utf8_invariant_string" ๐Ÿ’œ


"is_strict_utf8_string*", "is_strict_utf8_string_loc*", "is_strict_utf8_string_loclen*"

Described under "is_utf8_string" ๐ŸŽ€


"is_utf8_char_buf*"

Described under "isUTF8_CHAR" โ€” yeah that's literally the whole thing, it's a redirect bestie ๐Ÿ˜Œ


"is_utf8_fixed_width_buf_flags", "is_utf8_fixed_width_buf_loc_flags", "is_utf8_fixed_width_buf_loclen_flags"

these three each return TRUE if the fixed-width buffer starting at s with length len is entirely valid UTF-8, subject to the restrictions given by flags; otherwise they return FALSE. no cap ๐Ÿ™ˆ

  • if flags is 0, any well-formed UTF-8, as extended by Perl, is accepted without restriction. and here's the cute part โ€” if the final few bytes of the buffer don't form a complete code point, this still returns TRUE anyway, provided that is_utf8_valid_partial_char_flags returns TRUE for them ๐Ÿซถ
  • flags can be zero or any combination of the UTF8_DISALLOW_foo flags accepted by utf8_to_uv, and with the same meanings. same flags, same energy ๐Ÿ’…
  • these functions differ from is_utf8_string_flags only in that the latter returns FALSE if the final few bytes of the string don't form a complete code point. so like, that's the whole distinction, okay?
  • is_utf8_fixed_width_buf_loc_flags does all the preceding, but takes an extra parameter, ep, into which it stores the location of the failure, if ep is not NULL. if instead the function returns TRUE, *ep will point to the beginning of any partial character at the end of the buffer; if there is no partial character, *ep will contain s+len โœจ
  • is_utf8_fixed_width_buf_loclen_flags does all the preceding, but takes another extra parameter, el, into which it stores the number of complete, valid characters found, if el is not NULL ๐Ÿ‘‘
 bool       is_utf8_fixed_width_buf_flags       (
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U32 flags)
 bool  Perl_is_utf8_fixed_width_buf_flags       (
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U32 flags)
 bool       is_utf8_fixed_width_buf_loc_flags   (
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U8 **ep,
                                                      const U32 flags)
 bool  Perl_is_utf8_fixed_width_buf_loc_flags   (
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U8 **ep,
                                                      const U32 flags)
 bool       is_utf8_fixed_width_buf_loclen_flags(
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U8 **ep,
                                                      STRLEN *el,
                                                      const U32 flags)
 bool  Perl_is_utf8_fixed_width_buf_loclen_flags(
                                                     const U8 * const s,
                                                      STRLEN len,
                                                      const U8 **ep,
                                                      STRLEN *el,
                                                      const U32 flags)

"is_utf8_invariant_string", "is_utf8_invariant_string_loc", "is_ascii_string", "is_invariant_string"

these each return TRUE if the first len bytes of the string s are the same regardless of the UTF-8 encoding of the string (or UTF-EBCDIC encoding on EBCDIC machines); otherwise they return FALSE. that is, they return TRUE if they are UTF-8 invariant. iconic concept honestly ๐Ÿ’– on ASCII-ish machines, all the ASCII characters and only the ASCII characters fit this definition. on EBCDIC machines, the ASCII-range characters are invariant, but so also are the C1 controls โ€” plot twist โœจ

  • if len is 0, it will be calculated using strlen(s), (which means if you use this option, that s can't have embedded NUL characters and has to have a terminating NUL byte). so like, keep that in mind, bestie ๐Ÿ™ˆ

all forms except is_utf8_invariant_string_loc have identical behavior. the only difference with it is that it has an extra pointer parameter, ep, into which, if it isn't NULL, the location of the first UTF-8 variant character in the ep pointer will be stored upon failure. if all characters are UTF-8 invariant, this function does not change the contents of *ep ๐ŸŒธ

is_invariant_string is somewhat misleadingly named. is_utf8_invariant_string is preferred, as it indicates under what conditions the string is invariant. periodt.

is_ascii_string is misleadingly-named. on ASCII-ish platforms, the name isn't misleading: the ASCII-range characters are exactly the UTF-8 invariants. but EBCDIC machines have more UTF-8 invariants than just the ASCII characters, so the name is_utf8_invariant_string is preferred ๐Ÿ’…

see also "is_utf8_string" and "is_utf8_fixed_width_buf_flags" ๐Ÿฆ‹

 bool       is_utf8_invariant_string    (const U8 * const s,
                                         STRLEN len)
 bool       is_utf8_invariant_string_loc(const U8 * const s,
                                         STRLEN len,
                                         const U8 **ep)
 bool  Perl_is_utf8_invariant_string_loc(const U8 * const s,
                                         STRLEN len,
                                         const U8 **ep)
 bool       is_ascii_string             (const U8 * const s,
                                         STRLEN len)
 bool       is_invariant_string         (const U8 * const s,
                                         STRLEN len)

"is_utf8_string", "is_utf8_string_loc", "is_utf8_string_loclen", "is_strict_utf8_string", "is_strict_utf8_string_loc", "is_strict_utf8_string_loclen", "is_c9strict_utf8_string", "is_c9strict_utf8_string_loc", "is_c9strict_utf8_string_loclen", "is_utf8_string_flags", "is_utf8_string_loc_flags", "is_utf8_string_loclen_flags"

these each return TRUE if the first len bytes of string s form a valid UTF-8 string for varying degrees of strictness, FALSE otherwise. yes, varying degrees of strictness โ€” pick your energy, bestie ๐Ÿ˜Œ

  • if len is 0, it will be calculated using strlen(s) (which means if you use this option, that s can't have embedded NUL characters and has to have a terminating NUL byte). and note this: all characters being ASCII constitutes 'a valid UTF-8 string' ๐Ÿ‘‘

some of the functions also return information about the string. the ones that have the suffix _loc in their names have an extra parameter, ep. if that is not NULL, the function stores into it the location of how far it got in parsing s.

  • if the function is returning TRUE, this will be a pointer to the byte immediately after the end of s โœจ
  • if FALSE, it will be the location of the first byte that fails the criteria ๐Ÿ’€

the functions that instead have the suffix _loclen have a second extra parameter, el. they act as the plain _loc functions do with their ep parameter, but if el is not null, the functions store into it the number of UTF-8 encoded characters found at the point where parsing stopped.

  • if the function is returning TRUE, this will be the full count of the UTF-8 characters in s ๐ŸŽ€
  • if FALSE, it will be the count before the first invalid one ๐Ÿ˜ญ

Like, okay, real talk bestie: is_utf8_string (and its little sisters is_utf8_string_loc and is_utf8_string_loclen) think Perl's extended UTF-8 is valid. That means code points above Unicode, surrogates, and non-character code points all count as valid to these functions. ๐Ÿ’… Which is slay internally, but problems may arise in interchange with non-Perl applications, or (unlikely) between machines with different word sizes. So, y'know. Context matters.

is_strict_utf8_string (and is_strict_utf8_string_loc and is_strict_utf8_string_loclen) are the picky queens โ€” they consider only Unicode-range code points (that's 0 to 0x10FFFF) valid, with the surrogates and non-character code points being invalid. This level of strictness is what's safe to accept from outside sources that use Unicode rules. ๐Ÿ›ก๏ธ

The forms whose names contain c9strict conform to the level of strictness given in Unicode Corrigendum #9 http://www.unicode.org/versions/corrigendum9.html. Meaning: Unicode-range code points including non-character ones are valid, but not the surrogates. This level of strictness is considered safe for cooperating components that know how the other components handle non-character code points. ๐Ÿค

The forms whose names contain _flags let you customize the acceptable level of strictness, because of course you want options. They take an extra parameter, flags, to indicate the types of code points that are acceptable. And like:

  • If flags is 0, they give the same results as is_utf8_string (and kin).
  • If flags is UTF8_DISALLOW_ILLEGAL_INTERCHANGE, they give the same results as is_strict_utf8_string (and kin).
  • If flags is UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE, they give the same results as is_c9strict_utf8_string (and kin).
  • Otherwise flags may be any combination of the UTF8_DISALLOW_foo flags understood by utf8_to_uv, with the same meanings.

Pro tip no cap: it's better to use one of the non-_flags functions if they give you the desired strictness, as those have a better chance of being inlined by the C compiler. Tiny perf queen behaviour. โœจ

See also is_utf8_invariant_string, is_utf8_fixed_width_buf_flags,

bool       is_utf8_string                (const U8 *s,
                                          STRLEN len)
bool  Perl_is_utf8_string                (const U8 *s,
                                          STRLEN len)
bool       is_utf8_string_loc            (const U8 *s,
                                          const STRLEN len,
                                          const U8 **ep)
bool  Perl_is_utf8_string_loc            (const U8 *s,
                                          const STRLEN len,
                                          const U8 **ep)
bool       is_utf8_string_loclen         (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool  Perl_is_utf8_string_loclen         (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool       is_strict_utf8_string         (const U8 *s,
                                          STRLEN len)
bool  Perl_is_strict_utf8_string         (const U8 *s,
                                          STRLEN len)
bool       is_strict_utf8_string_loc     (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep)
bool  Perl_is_strict_utf8_string_loc     (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep)
bool       is_strict_utf8_string_loclen  (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool  Perl_is_strict_utf8_string_loclen  (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool       is_c9strict_utf8_string       (const U8 *s,
                                          STRLEN len)
bool  Perl_is_c9strict_utf8_string       (const U8 *s,
                                          STRLEN len)
bool       is_c9strict_utf8_string_loc   (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep)
bool  Perl_is_c9strict_utf8_string_loc   (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep)
bool       is_c9strict_utf8_string_loclen(const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool  Perl_is_c9strict_utf8_string_loclen(const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el)
bool       is_utf8_string_flags          (const U8 *s,
                                          STRLEN len,
                                          const U32 flags)
bool  Perl_is_utf8_string_flags          (const U8 *s,
                                          STRLEN len,
                                          const U32 flags)
bool       is_utf8_string_loc_flags      (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          const U32 flags)
bool  Perl_is_utf8_string_loc_flags      (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          const U32 flags)
bool       is_utf8_string_loclen_flags   (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el,
                                          const U32 flags)
bool  Perl_is_utf8_string_loclen_flags   (const U8 *s,
                                          STRLEN len,
                                          const U8 **ep,
                                          STRLEN *el,
                                          const U32 flags)

๐Ÿฆ‹ is_utf8_valid_partial_char / is_utf8_valid_partial_char_flags

Okay so these two each return FALSE if the sequence of bytes starting at s and looking no further than e - 1 is the UTF-8 encoding for one or more code points. Like, FALSE comes back if s points to at least one entire UTF-8 encoded character. Full character found, nothing to worry about, kthanksbye. ๐Ÿ’–

Otherwise, they return TRUE if there exists at least one non-empty sequence of bytes that when appended to sequence s, starting at position e causes the entire sequence to be the well-formed UTF-8 of some code point.

In other words โ€” and I love this phrasing โ€” they return TRUE if s points to an incomplete UTF-8-encoded code point; FALSE otherwise. ๐Ÿงฉ

Where is this useful? When a fixed-length buffer is being tested for being well-formed UTF-8, but the final few bytes in it don't comprise a full character. I.e. it's split somewhere in the middle of the final code point's UTF-8 representation. (Presumably when the buffer is refreshed with the next chunk of data, the new first bytes will complete the partial code point.) This function verifies that the final bytes in the current buffer are in fact the legal beginning of some code point, so that if they aren't, the failure can be signalled without having to wait for the next read. Efficiency queen behaviour fr fr. ๐Ÿ‘‘

is_utf8_valid_partial_char behaves identically to is_utf8_valid_partial_char_flags when the latter is called with a zero flags parameter. That parameter restricts the classes of code points that are considered to be valid. When zero, Perl's extended UTF-8 is used. Otherwise flags can be any combination of the UTF8_DISALLOW_foo flags accepted by utf8_to_uv. If there is any sequence of bytes that can complete the input partial character in such a way that a non-prohibited character is formed, the function returns TRUE; otherwise FALSE.

Careful bestie: non-character code points cannot be determined based on partial character input, so TRUE is always returned if s looks like it could be the beginning on one of those. But many of the other possible excluded types can be determined from just the first one or two bytes. ๐ŸŽ€
bool       is_utf8_valid_partial_char      (const U8 * const s0,
                                            const U8 * const e)
bool  Perl_is_utf8_valid_partial_char      (const U8 * const s0,
                                            const U8 * const e)
bool       is_utf8_valid_partial_char_flags(const U8 * const s0,
                                            const U8 * const e,
                                            const U32 flags)
bool  Perl_is_utf8_valid_partial_char_flags(const U8 * const s0,
                                            const U8 * const e,
                                            const U32 flags)

๐ŸŒธ isUTF8_CHAR / isSTRICT_UTF8_CHAR / isC9_STRICT_UTF8_CHAR / isUTF8_CHAR_flags / is_utf8_char_buf

These each evaluate to non-zero if the first few bytes of the string starting at s and looking no further than e - 1 are well-formed UTF-8 that represents some code point โ€” for varying degrees of strictness, obvs. Otherwise they evaluate to 0. And if non-zero, the value gives how many bytes starting at s comprise the code point's representation. Any bytes remaining before e, but beyond the ones needed to form the first code point in s, are not examined. Snooze you lose, those bytes stay untouched. ๐Ÿ˜ด

These exist so you can efficiently decide if the next few bytes in s are legal UTF-8 for a single character. Speed demon energy. โšก

With isUTF8_CHAR, the code point can be any that will fit in an IV on this machine, using Perl's extension to official UTF-8 to represent those higher than the Unicode maximum of 0x10FFFF. That means it will consider byte sequences valid that are unrecognized or considered illegal by non-Perl applications. ๐Ÿซฃ Perl stays doing its own thing, per usual.

cont. bestie we were mid-isUTF8_CHAR tea and we are NOT stopping ๐Ÿ’…

So here's the strictness ladder, okay? ๐ŸŒˆ

  • With isSTRICT_UTF8_CHAR, the acceptable code points get restricted to the ones Unicode defines as fully interchangeable across applications. Translation: code points above the Unicode range (max legal is 0x10FFFF), surrogates, and non-character code points all get rejected. bye โœ‹
  • With isC9_STRICT_UTF8_CHAR, acceptable code points are restricted to those Unicode defines as fully interchangeable within an application. That means code points above the Unicode range and surrogates get rejected, but non-character code points are accepted. It's giving "we're flexible actually." See Unicode Corrigendum #9 <http://www.unicode.org/versions/corrigendum9.html> ๐Ÿฆ‹

Use isUTF8_CHAR_flags to customize exactly which code points are acceptable. The tea โ˜•:

  • if flags is 0, you get the same results as isUTF8_CHAR
  • if flags is UTF8_DISALLOW_ILLEGAL_INTERCHANGE, you get the same results as isSTRICT_UTF8_CHAR
  • if flags is UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE, you get the same results as isC9_STRICT_UTF8_CHAR
  • otherwise, flags may be any combination of the UTF8_DISALLOW_foo flags understood by utf8_to_uv, with the same meanings โœจ

The three alternative macros exist for the most commonly needed validations. They're likely to run somewhat faster than this more general one, because they can be inlined into your code. speed demon energy fr ๐ŸŽ๏ธ

Use one of the is_utf8_string forms to check entire strings.

Also note: a UTF-8 "invariant" character (i.e. ASCII on non-EBCDIC machines) is a valid UTF-8 character. no cap ๐Ÿ’–

is_utf8_char_buf is the old name for isUTF8_CHAR. Do not use it in new code. it's giving deprecated, we don't do that here ๐Ÿ™ˆ

 Size_t       isUTF8_CHAR          (const U8 * const s0,
                                    const U8 * const e)
 Size_t  Perl_isUTF8_CHAR          (const U8 * const s0,
                                    const U8 * const e)
 Size_t       isSTRICT_UTF8_CHAR   (const U8 * const s0,
                                    const U8 * const e)
 Size_t  Perl_isSTRICT_UTF8_CHAR   (const U8 * const s0,
                                    const U8 * const e)
 Size_t       isC9_STRICT_UTF8_CHAR(const U8 * const s0,
                                    const U8 * const e)
 Size_t  Perl_isC9_STRICT_UTF8_CHAR(const U8 * const s0,
                                    const U8 * const e)
 Size_t       isUTF8_CHAR_flags    (const U8 * const s0,
                                    const U8 * const e,
                                    const U32 flags)
 Size_t  Perl_isUTF8_CHAR_flags    (const U8 * const s0,
                                    const U8 * const e,
                                    const U32 flags)
 STRLEN       is_utf8_char_buf     (const U8 *buf,
                                    const U8 *buf_end)
 STRLEN  Perl_is_utf8_char_buf     (const U8 *buf,
                                    const U8 *buf_end)

LATIN1_TO_NATIVE

Returns the native equivalent of the input Latin-1 code point (including ASCII and control characters) that you hand it as ch. So LATIN1_TO_NATIVE(66) on EBCDIC platforms returns 194. Both of those represent the character "B" on their respective platforms. iconic crossover event ๐Ÿ’ซ

On ASCII platforms no conversion is needed at all, so this macro just expands to its input โ€” zero time nor space requirements added to the implementation. slay, efficiency queen ๐Ÿ‘‘

If you're converting code points that might be bigger than will fit in a character, use UNI_TO_NATIVE instead, bestie.

 U8  LATIN1_TO_NATIVE(U8 ch)

NATIVE_TO_LATIN1

Returns the Latin-1 (including ASCII and control characters) equivalent of the input native code point you give it in ch. So NATIVE_TO_LATIN1(193) on EBCDIC platforms returns 65. Both represent the character "A" on their respective platforms. ๐Ÿ’œ

On ASCII platforms no conversion is needed, so the macro expands to just its input โ€” again, no time nor space requirements added. โœจ

For code points potentially larger than will fit in a character, use NATIVE_TO_UNI.

 U8  NATIVE_TO_LATIN1(U8 ch)

NATIVE_TO_UNI

Returns the Unicode equivalent of the input native code point in ch. So NATIVE_TO_UNI(195) on EBCDIC platforms returns 67. Both represent the character "C" on their respective platforms. ๐ŸŽ€

On ASCII platforms no conversion is needed โ€” expands to just its input, adding no time nor space requirements. periodt.

 UV  NATIVE_TO_UNI(UV ch)

pv_uni_display

Builds into the scalar dsv a displayable version of the UTF-8 encoded string spv, with length len. The displayable version is at most pvlim bytes long โ€” and if it would be longer, the rest gets truncated and ... gets appended. rude but necessary ๐Ÿ˜ญ

The flags argument can have any combination of these flag bits:

  • UNI_DISPLAY_ISPRINT โ€” displays isPRINT()able characters as themselves ๐Ÿ–จ๏ธ
  • UNI_DISPLAY_BACKSLASH โ€” displays the \\[nrfta\\] as the backslashed versions (like \n)
    • (UNI_DISPLAY_BACKSLASH is preferred over UNI_DISPLAY_ISPRINT for \\.)
  • UNI_DISPLAY_BACKSPACE โ€” displays \b for a backspace, but only when UNI_DISPLAY_BACKSLASH also is set
  • UNI_DISPLAY_REGEX โ€” this is a shorthand for UNI_DISPLAY_ISPRINT along with UNI_DISPLAY_BACKSLASH
  • UNI_DISPLAY_QQ โ€” this is a shorthand for all three UNI_DISPLAY_ISPRINT, UNI_DISPLAY_BACKSLASH, and UNI_DISPLAY_BACKSLASH (yes bestie, that's what it says, iykyk ๐Ÿ’€)

The pointer to the PV of the dsv is returned.

See also sv_uni_display.

 char *       pv_uni_display(      SV *dsv, const U8 *spv,
                                   STRLEN len, STRLEN pvlim,
                                   UV flags)
 char *  Perl_pv_uni_display(pTHX_ SV *dsv, const U8 *spv,
                                   STRLEN len, STRLEN pvlim,
                                   UV flags)

REPLACEMENT_CHARACTER_UTF8

A macro that evaluates to a string constant of the UTF-8 bytes that define the Unicode REPLACEMENT CHARACTER (U+FFFD) for the platform that perl is compiled on. This lets your code use a mnemonic for this character that works on both ASCII and EBCDIC platforms. ๐Ÿซถ

sizeof(REPLACEMENT_CHARACTER_UTF8) - 1 gets you its length in bytes. little math moment ๐Ÿงฎ

strict_utf8_to_uv*

Described under utf8_to_uv. go look, bestie ๐Ÿ‘€

sv_cat_decode

encoding is assumed to be an Encode object. The PV of ssv is assumed to be octets in that encoding, and decoding the input starts from the position which (PV + *offset) pointed to.

dsv gets concatenated with the decoded UTF-8 string from ssv. Decoding terminates when the string tstr appears in the decoding output, or when the input ends on the PV of ssv.

The value which offset points will be modified to the last input position on ssv. โœจ

Returns TRUE if the terminator was found, else returns FALSE.

 bool       sv_cat_decode(      SV *dsv, SV *encoding, SV *ssv,
                                int *offset, char *tstr, int tlen)
 bool  Perl_sv_cat_decode(pTHX_ SV *dsv, SV *encoding, SV *ssv,
                                int *offset, char *tstr, int tlen)

sv_recode_to_utf8

encoding is assumed to be an Encode object. On entry, the PV of sv is assumed to be octets in that encoding, and sv will be converted into Unicode (and UTF-8). glow up ๐Ÿ’…

If sv already is UTF-8 (or if it is not POK), or if encoding is not a reference, nothing is done to sv. no touchy.

๐Ÿšจ If encoding is not an Encode::XS Encoding object, bad things will happen. (See encoding and Encode.) you have been warned, bestie ๐Ÿ˜ญ

The PV of sv is returned.

 char *       sv_recode_to_utf8(      SV *sv, SV *encoding)
 char *  Perl_sv_recode_to_utf8(pTHX_ SV *sv, SV *encoding)

sv_uni_display

Builds into the scalar dsv a displayable version of the scalar sv. The displayable version is at most pvlim bytes long โ€” if longer, the rest is truncated and ... will be appended. ๐ŸŒธ

The flags argument is as in pv_uni_display().

The pointer to the PV of the dsv is returned.

 char *       sv_uni_display(      SV *dsv, SV *ssv, STRLEN pvlim,
                                   UV flags)
 char *  Perl_sv_uni_display(pTHX_ SV *dsv, SV *ssv, STRLEN pvlim,
                                   UV flags)

UNI_TO_NATIVE

Returns the native equivalent of the input Unicode code point in ch. So UNI_TO_NATIVE(68) on EBCDIC platforms returns 196. Both represent the character "D" on their respective platforms. ๐Ÿ’–

On ASCII platforms no conversion is needed โ€” the macro expands to just its input, adding no time nor space requirements to the implementation.

 UV  UNI_TO_NATIVE(UV ch)

UNICODE_IS_NONCHAR

Returns a boolean as to whether or not uv is one of the Unicode non-character code points. ๐ŸŽ€

 bool  UNICODE_IS_NONCHAR(const UV uv)

UNICODE_IS_REPLACEMENT

Returns a boolean as to whether or not uv is the Unicode REPLACEMENT CHARACTER.

 bool  UNICODE_IS_REPLACEMENT(const UV uv)

UNICODE_IS_SUPER

Returns a boolean as to whether or not uv is above the maximum legal Unicode code point of U+10FFFF. over the line, literally โœ‹

 bool  UNICODE_IS_SUPER(const UV uv)

UNICODE_IS_SURROGATE

Returns a boolean as to whether or not uv is one of the Unicode surrogate code points.

 bool  UNICODE_IS_SURROGATE(const UV uv)

UNICODE_REPLACEMENT

Evaluates to 0xFFFD, the code point of the Unicode REPLACEMENT CHARACTER. there it is, the iconic one โญ

UTF8_CHK_SKIP*

Described under UTF8SKIP. go read that one, bestie ๐Ÿ‘‘

utf8_distance

Returns the number of UTF-8 characters between the UTF-8 pointers a and b. ๐Ÿงš

โš ๏ธ WARNING: use only if you know that the pointers point inside the same UTF-8 buffer. do not be casual about this, fr fr ๐Ÿ’€
 IV       utf8_distance(      const U8 *a, const U8 *b)
 IV  Perl_utf8_distance(pTHX_ const U8 *a, const U8 *b)

utf8_hop

Returns the UTF-8 pointer s displaced by off characters โ€” forward if off is positive, backward if it's negative. ๐Ÿฆ‹

s does not need to be pointing to the starting byte of a character. If it isn't, one count of off will be used up to get to the start of the next character for forward hops, and to the start of the current character for negative ones.

โš ๏ธ WARNING: Prefer utf8_hop_safe to this one. that's the whole tea, bestie ๐Ÿ’…
๐Ÿšจ STOP RIGHT THERE BESTIE. The next bit is a huge neon warning sign and we do not skip those in this house.

Do NOT use this function unless you know that off is within the UTF-8 data that s points at, and that when you come in the door, s is either aligned on the first byte of a character or sitting just after the last byte of a character. Like, no vibes-based guessing here. Know it. ๐Ÿ’…

U8 *       utf8_hop(const U8 *s, SSize_t off)
U8 *  Perl_utf8_hop(const U8 *s, SSize_t off)

utf8_hop_back</p>

utf8_hop_back_overshoot</p>

Okay so both of these take a UTF-8-encoded string that starts at start, plus a position into it handed to you as s, and they give you back the position that is s displaced by up to off characters backwards. ๐ŸŒธ

If there are fewer than off characters hanging out between start and s, no drama โ€” the functions just return start.

The two are diff in one way: utf8_hop_back_overshoot can tell you how many characters off beyond the edge your little request was. When its parameter, &remaining, is not NULL, it stores that excess count into it โ€” and zero if the request was totally fulfilled, no overshoot, icon behavior. Then the actual number of characters displaced can be calculated as off - remaining. And when that parameter is NULL, this function behaves exactly like plain utf8_hop_back. Same energy, no extra receipts. ๐Ÿซถ

s doesn't need to be pointing at the starting byte of a character. If it isn't, one count of off gets used up just to scoot over to that start.

off must be non-positive, and if it's zero, nothing happens at all โ€” s comes back to you unchanged. And the fact that it otherwise has to be negative means the earlier description is a lie, oops ๐Ÿ˜ญ โ€” the manpage says it was done to avoid burdening you with this detail too soon. An off of -2 means displace two characters backwards, so the displacement is really the absolute value of off. remaining will also be non-positive. If there was only one character between start and s and you asked for a displacement of -2, remaining would be set to -1. The subtraction formula still works, and it yields that only -1 character was displaced. Math ate, honestly. โœจ

U8 *       utf8_hop_back          (const U8 *s, SSize_t off,
                                   const U8 * const start)
U8 *  Perl_utf8_hop_back          (const U8 *s, SSize_t off,
                                   const U8 * const start)
U8 *       utf8_hop_back_overshoot(const U8 *s, SSize_t off,
                                   const U8 * const start,
                                   SSize_t *remaining)
U8 *  Perl_utf8_hop_back_overshoot(const U8 *s, SSize_t off,
                                   const U8 * const start,
                                   SSize_t *remaining)

utf8_hop_forward</p>

utf8_hop_forward_overshoot</p>

Now the mirror versions. Each of these takes a position, s0, into a UTF-8-encoded string that ends at the byte before end, and returns the position within it that is s0 displaced by up to off characters forwards. ๐Ÿฆ‹

If there are fewer than off characters between s0 and end, the functions return end.

They differ in two ways:

  • utf8_hop_forward_overshoot can return how many characters beyond the edge the request was for. When its parameter, &remaining, is not NULL, the function stores the count of the excess into it โ€” zero if the request was completely fulfilled. The actual number of characters displaced can then be calculated as off - remaining.
  • utf8_hop_forward will panic ๐Ÿ˜ฑ if it's called with s0 already positioned at or beyond the edge of the string ending at end, and the request is to go even further over the edge. utf8_hop_forward_overshoot presumes the caller will handle any errors, and just stores off into remaining without doing anything else.
(The above contains a slight lie, bestie. When remaining is NULL, the two functions act identically. ๐Ÿ’€)

s0 doesn't need to be pointing at the starting byte of a character. If it isn't, one count of off gets used up getting to that start.

off must be non-negative, and if it's zero, no action is taken โ€” s0 is returned unchanged.

U8 *       utf8_hop_forward          (const U8 *s, SSize_t off,
                                      const U8 * const end)
U8 *  Perl_utf8_hop_forward          (const U8 *s, SSize_t off,
                                      const U8 * const end)
U8 *       utf8_hop_forward_overshoot(const U8 *s, SSize_t off,
                                      const U8 * const end,
                                      SSize_t *remaining)
U8 *  Perl_utf8_hop_forward_overshoot(const U8 *s, SSize_t off,
                                      const U8 * const end,
                                      SSize_t *remaining)

utf8_hop_safe</p>

utf8_hop_overshoot</p>

These two take a UTF-8-encoded string starting at start and ending at end, plus a position into it given by s, and return the position within it that is s displaced by up to off characters โ€” forwards if off is positive, backwards if off is negative. (And if off is 0, nothing happens at all. Zero is zero.) ๐ŸŒˆ

If there are fewer than off characters between s and the respective edge, the functions return that edge.

The difference? utf8_hop_overshoot can return how many characters beyond the edge the request was for. When its parameter, &remaining, is not NULL, the function stores the count of the excess into it โ€” zero if the request was completely fulfilled. The actual number of characters displaced can then be calculated as off - remaining. And when this parameter is NULL, it acts identically to plain utf8_hop_safe. Periodt. ๐Ÿ’œ

s doesn't need to be pointing at the starting byte of a character. If it isn't, one count of off gets used up getting to that start.

To be more precise: the displacement is by the absolute value of off, and the excess count is the absolute value of remaining. โญ

U8 *       utf8_hop_safe     (const U8 *s, SSize_t off,
                              const U8 * const start,
                              const U8 * const end)
U8 *  Perl_utf8_hop_safe     (const U8 *s, SSize_t off,
                              const U8 * const start,
                              const U8 * const end)
U8 *       utf8_hop_overshoot(const U8 *s, SSize_t off,
                              const U8 * const start,
                              const U8 * const end,
                              SSize_t *remaining)
U8 *  Perl_utf8_hop_overshoot(const U8 *s, SSize_t off,
                              const U8 * const start,
                              const U8 * const end,
                              SSize_t *remaining)

UTF8_IS_INVARIANT</p>

Evaluates to 1 if the byte c represents the same character when it's encoded in UTF-8 as when it isn't. Otherwise it evaluates to 0. UTF-8 invariant characters can be copied as-is when converting to/from UTF-8, which saves time โ€” free real estate, kind of. ๐Ÿ“

In spite of the name, this macro gives the correct result if the input string that c came from is not encoded in UTF-8. Iconic, no notes.

If you're checking whether a UV is invariant, go see UVCHR_IS_INVARIANT.

bool  UTF8_IS_INVARIANT(char c)

UTF8_IS_NONCHAR</p>

Evaluates to non-zero if the first few bytes of the string starting at s โ€” looking no further than e - 1 โ€” are well-formed UTF-8 representing one of the Unicode non-character code points. Otherwise it evaluates to 0. If the value is non-zero, it gives you how many bytes starting at s make up that code point's representation. โœจ

bool  UTF8_IS_NONCHAR(const U8 *s, const U8 *e)

UTF8_IS_REPLACEMENT</p>

Evaluates to non-zero if the first few bytes of the string starting at s โ€” looking no further than e - 1 โ€” are well-formed UTF-8 representing the Unicode REPLACEMENT CHARACTER. Otherwise: 0. If non-zero, the value tells you how many bytes starting at s comprise the code point's representation. ๐ŸŽ€

bool  UTF8_IS_REPLACEMENT(const U8 *s, const U8 *e)

UTF8_IS_SUPER</p>

Remember how Perl recognizes an extension to UTF-8 that can encode code points bigger than the ones Unicode defines, which are 0..0x10FFFF? Yeah. That. ๐Ÿ‘‘

This macro evaluates to non-zero if the first few bytes of the string starting at s โ€” looking no further than e - 1 โ€” come from that UTF-8 extension. Otherwise it evaluates to 0. If it's non-zero, the return is how many bytes starting at s comprise the code point's representation.

0 is returned if the bytes aren't well-formed extended UTF-8, or if they represent a code point that can't fit in a UV on the current platform. Which means this macro can give you different results on a 64-bit word machine than on one with a 32-bit word size. Same code, different platform, different answer โ€” vibe check accordingly. ๐Ÿ˜ญ

Also note: it is illegal in Perl to have code points larger than what can fit in an IV on the current machine; and it's illegal in Unicode to have any that this macro matches. So like, don't. ๐Ÿšจ

bool  UTF8_IS_SUPER(const U8 *s, const U8 *e)

UTF8_IS_SURROGATE</p>

Evaluates to non-zero if the first few bytes of the string starting at s โ€” looking no further than e - 1 โ€” are well-formed UTF-8 representing one of the Unicode surrogate code points. Otherwise it evaluates to 0. If non-zero, the value gives you how many bytes starting at s comprise the code point's representation. ๐Ÿงš

bool  UTF8_IS_SURROGATE(const U8 *s, const U8 *e)

utf8_length</p>

Returns the number of characters in that sequence of UTF-8-encoded bytes starting at s and ending at the byte just before e. And if <s> and <e> point to the exact same place, it returns 0 with no warning raised โ€” quiet, chill, no drama. ๐Ÿซถ

But if e < s, or if the scan would end up past e, it raises a UTF8 warning and returns the number of valid characters. So you get the goods and a lil warning. ๐Ÿ’…

STRLEN       utf8_length(      const U8 *s0, const U8 *e)
STRLEN  Perl_utf8_length(pTHX_ const U8 *s0, const U8 *e)

UTF8_MAXBYTES</p>

The maximum width of a single UTF-8 encoded character, in bytes.

NOTE: Strictly speaking, Perl's UTF-8 should not be called UTF-8, because UTF-8 is an encoding of Unicode, and Unicode's upper limit, 0x10FFFF, can be expressed with 4 bytes. But Perl thinks of UTF-8 as a way to encode non-negative integers in a binary format โ€” even the ones above Unicode. So the name is a bit of a lie, we're all aware, moving on. ๐Ÿ™ˆ

UTF8_MAXBYTES_CASE</p>

The maximum number of UTF-8 bytes a single Unicode character can uppercase/lowercase/titlecase/fold into. Casing can grow your character, bestie, and this is the ceiling of how much. ๐ŸŒธ


UTF8_SAFE_SKIP*</p>

UTF8_SKIP*</p>

Described under UTF8SKIP. Go look there, iykyk. ๐Ÿ”ฅ

๐Ÿ’– utf8_to_bytes_overwrite, utf8_to_bytes_new_pv, utf8_to_bytes_temp_pv, utf8_to_bytes, bytes_from_utf8 ๐Ÿ’–

NOTE: utf8_to_bytes is experimental and may change or be removed without notice. ๐Ÿ‘€

Okay so all five of these convert a string that's encoded as UTF-8 into the equivalent native byte representation, if that's possible. The first three forms are the ones you actually want โ€” their API is way nicer to use, and each one returns true if the result is in bytes, or false if the conversion failed. ๐Ÿซถ

  • utf8_to_bytes_overwrite
  • utf8_to_bytes_new_pv
  • utf8_to_bytes_temp_pv

These three differ mainly in what shape the returned string takes and whether the input string is allowed to be const. In each of them, if the input string was already in native bytes, or just wasn't convertible, the input isn't changed at all.

In each of these three functions, the input s_ptr is a pointer to the string to be converted, and *lenp is its length (so the very first byte will be at *sptr[0]).

utf8_to_bytes_overwrite overwrites the input string with the bytes conversion. Which means the input string should not be const. (Converting the multi-byte UTF-8 encoding down to single bytes never expands the result, so overwriting is always feasible, no drama. ๐Ÿ’…)

Both utf8_to_bytes_new_pv and utf8_to_bytes_temp_pv allocate new memory to hold the converted string, and they never change the input. So the input string may be const. They differ in that utf8_to_bytes_temp_pv arranges for that new memory to be automatically freed. With utf8_to_bytes_new_pv, the caller is responsible for freeing the memory. And โ€” as explained below โ€” not all successful calls result in new memory being allocated. So this function also returns to the caller (via an extra parameter, *free_me) a pointer to any new memory, or NULL if none was allocated.

The functions return false when the input isn't well-formed UTF-8, or when it contains at least one UTF-8 sequence that represents a code point that can't be expressed as a byte. The contents of *s_ptr and *lenp are not changed, and utf8_to_bytes_new_pv sets *free_me to NULL. ๐Ÿ˜ญ

They all return true when either:

  • The input turned out to already be in bytes form โ€” the contents of *s_ptr and *lenp are not changed, and utf8_to_bytes_new_pv sets *free_me to NULL.
  • The input was successfully converted
    • For utf8_to_bytes_overwrite โ€” the input string *s_ptr was overwritten with the native bytes, NUL terminator included. *lenp has been updated with the new length.
    • For utf8_to_bytes_new_pv and utf8_to_bytes_temp_pv โ€” the input string was not changed. Instead, new memory has been allocated containing the translation of the input into native bytes, with a NUL terminator byte. *s_ptr now points to that new memory, and *lenp contains its length.
      • For utf8_to_bytes_temp_pv, the new memory has been arranged to be automatically freed, via a call to SAVEFREEPV.
      • For utf8_to_bytes_new_pv, *free_me has been set to *s_ptr, and it is the caller's responsibility to free the new memory when done using it. This paradigm is the convenient way to use it:
 void * free_me;
 if (utf8_to_bytes_new_pv(&s, &len, &free_me) {
    ...
 }
 else {
    ...
 }

 ...

 Safefree(free_me);

free_me can double as a boolean (non-NULL meaning true) telling you the input really was changed, if you need to revisit that later in the code. And ngl, if you ever find yourself using free_me for any other purpose, your design is probably flawed. ๐Ÿ™ˆ

Note that in all cases, *s_ptr and *lenp will have correct and consistent values, updated as was necessary.

Also note: upon a successful conversion, the number of variants in the string can be computed by having saved the value of *lenp before the call, and subtracting the after-call value of *lenp from it. Same goes for the other two functions described below. โœจ

  • utf8_to_bytes

Plain utf8_to_bytes (which has never lost its experimental status) also converts a UTF-8 encoded string to bytes, but there are more glitches the caller has to be prepared to handle.

The input string is passed with one less indirection level: s.

  • If the conversion was a noop โ€” the contents of s and *lenp are not changed, and the function returns s.
  • If the conversion was successful โ€” the contents of s were changed, and *lenp updated to be the correct length. The function returns s (unchanged).
  • If the conversion failed โ€” the contents of s were not changed. The function returns NULL and sets *lenp to -1, cast to STRLEN. This means you will have to use a temporary containing the string length to pass to the function if you'll need that value afterwards. ๐Ÿ’€
  • bytes_from_utf8

bytes_from_utf8 also converts a potentially UTF-8 encoded string s to bytes. It preserves s, allocating new memory for the converted string.

In contrast to the other functions, the input string to this one doesn't have to be UTF-8. If it isn't, the caller has set *is_utf8p to be false, and the function does nothing, returning the original s.

It also does nothing if there are code points in the string that aren't expressible in native byte encoding, returning the original s.

Otherwise, *is_utf8p is set to 0, and the return value is a pointer to a newly created string containing the native byte equivalent of s, whose length is returned in *lenp, updated. The new string is NUL-terminated. The caller is responsible for arranging for the memory used by this string to get freed. ๐Ÿงš

The major problem with this function is that memory is allocated and filled even when the input string was already in bytes form.

New code should use the first three functions listed above. ๐Ÿ‘‘
 bool       utf8_to_bytes_overwrite(      U8 **s_ptr,
                                         STRLEN *lenp)
 bool  Perl_utf8_to_bytes_overwrite(pTHX_ U8 **s_ptr,
                                         STRLEN *lenp)
 bool       utf8_to_bytes_new_pv   (      U8 const **s_ptr,
                                         STRLEN *lenp,
                                         void **free_me)
 bool  Perl_utf8_to_bytes_new_pv   (pTHX_ U8 const **s_ptr,
                                         STRLEN *lenp,
                                         void **free_me)
 bool       utf8_to_bytes_temp_pv  (      U8 const **s_ptr,
                                         STRLEN *lenp)
 bool  Perl_utf8_to_bytes_temp_pv  (pTHX_ U8 const **s_ptr,
                                         STRLEN *lenp)
 U8 *       utf8_to_bytes          (      U8 *s, STRLEN *lenp)
 U8 *  Perl_utf8_to_bytes          (pTHX_ U8 *s, STRLEN *lenp)
 U8 *       bytes_from_utf8        (      const U8 *s,
                                         STRLEN *lenp,
                                         bool *is_utf8p)
 U8 *  Perl_bytes_from_utf8        (pTHX_ const U8 *s,
                                         STRLEN *lenp,
                                         bool *is_utf8p)

๐ŸŒˆ utf8_to_uv, extended_utf8_to_uv, strict_utf8_to_uv, c9strict_utf8_to_uv, utf8_to_uv_or_die, utf8_to_uvchr_buf, utf8_to_uvchr ๐ŸŒˆ

DEPRECATED! It is planned to remove utf8_to_uvchr from a future release of Perl. Do not use it for new code; remove it from existing code. Periodt. ๐Ÿ’€

These functions each translate from UTF-8 to UTF-32 (or UTF-64 on 64 bit platforms). In other words, they give you a code point ordinal value. (On EBCDIC platforms, the initial encoding is UTF-EBCDIC, and the output is a native code point.)

For example, the string "A" would be converted to the number 65 on an ASCII platform, and to 193 on an EBCDIC one. Converting the string "ABC" would yield the same results, because the functions stop after the first character converted. And converting the string "\N{LATIN CAPITAL LETTER A WITH MACRON} plus anything more in the string" would yield the number 0x100 on both types of platforms, since that first character is U+0100. ๐ŸŒธ

The functions whose names contain to_uvchr are older than the functions whose names don't have chr in them. The API in the older functions is harder to use correctly, and so they're kept only for backwards compatibility, and may eventually become deprecated. If you're writing a module and use Devel::PPPort, your code can use the new functions back to at least Perl v5.7.1. ๐Ÿซถ

All the functions accept, without complaint, well-formed UTF-8 for any non-problematic Unicode code point 0 .. 0x10FFFF. There are two types of Unicode problematic code points: surrogate characters and non-character code points. (See perlunicode.) Some of the functions reject one or both of these. Private use characters and those code points yet to be assigned to a particular character are never considered problematic. Additionally, most of the functions accept non-Unicode code points, those starting at 0x110000.

There are two sets of these functions:

  • utf8_to_uv forms

Almost all code should use only utf8_to_uv, extended_utf8_to_uv, strict_utf8_to_uv, c9strict_utf8_to_uv, or utf8_to_uv_or_die. The other functions are either the problematic old form, or they're for specialized uses.

utf8_to_uv_or_die has a simpler interface than the other four, for use when any errors encountered should be fatal. It throws an exception with any errors found; otherwise it returns the code point the input sequence represents. ๐Ÿ‘‘

So the other four functions? ๐Ÿ’– They each return "true" when the sequence of bytes starting at s forms a complete, legal UTF-8 (or UTF-EBCDIC) sequence for a code point โ€” and false when it doesn't. Periodt.

They take one extra parameter too: the address of an IV, &cp. Then *cp gets set to the native code point value the sequence represents, and *advance gets set to its length, in bytes. Iconic behavior, honestly.

If a function returns "false", then *cp is set to the Unicode REPLACEMENT CHARACTER, and *advance points to the next position along s where the next possible UTF-8 character could begin. And bestie, listen โ€” failing to use this position as the next starting point while parsing strings has led to successful attacks by crafted inputs. That part is not a vibe, that part is a whole warning. ๐Ÿšจ

These functions only examine as many bytes along s as are needed to form a complete UTF-8 representation of a single code point; they never peek at the byte at e, or beyond. And they return false (or just straight-up die, in the case of utf8_to_uv_or_die) if the code point needs more than e - s bytes to represent.

They differ only in what flavor of UTF-8 they accept. All of them reject syntactically invalid UTF-8. No exceptions, no mercy:

  • strict_utf8_to_uv โ€” on top of everything, this one rejects any UTF-8 that translates into a code point that isn't specified by Unicode to be freely exchangeable, namely the surrogate characters and non-character code points (besides non-Unicode code points, any above 0x10FFFF). And it does not raise a warning when it rejects these. Silent. Deadly. ๐Ÿ’…
  • c9strict_utf8_to_uv โ€” instead uses the exchangeable definition given by Unicode's Corregendum #9, which accepts non-character code points while still rejecting surrogates. Also does not raise a warning when rejecting these.
  • utf8_to_uv
  • utf8_to_uv_or die โ€” accept all syntactically valid UTF-8, as extended by Perl to allow 64-bit code points to be encoded.

extended_utf8_to_uv is merely a synonym for utf8_to_uv. Use this form when you want to draw attention to the fact that it accepts any code point. But since Perl programs traditionally do this by default, plain utf8_to_uv is the form most often used. She's the main character for a reason. ๐Ÿ‘‘

Whenever syntactically invalid input is rejected, an explanatory warning message is raised โ€” unless utf8 warnings (or the appropriate subcategory) are turned off. And here's the thing: a given input sequence may contain multiple malformations, giving rise to multiple warnings, because the functions attempt to find and report on all the malformations in a sequence. All the possible malformations are listed in utf8_to_uv_msgs, with some examples of multiple ones for the same sequence. You can use that function or utf8_to_uv_flags to exert more control over the input that is considered acceptable, and the warnings that are raised. Control freak? Valid. ๐ŸŽ€

Often, s is an arbitrarily long string containing the UTF-8 representations of many code points in a row, and these functions are called in the course of parsing s to find all those code points.

If your code doesn't know how to deal with illegal input โ€” which would be typical of a low level routine, ngl โ€” the loop could look like:

 while (s < e) {
     Size_t advance;
     UV cp;
     (void) utf8_to_uv(s, e, &cp, &advance);
     <handle 'cp'>
     s += advance;
 }

A REPLACEMENT CHARACTER will be inserted everywhere that malformed input occurs. Obviously we aren't expecting such outcomes ๐Ÿ™ˆ, but your code will be protected from attacks and many harmful effects that could otherwise occur. Protected, wrapped, cozy.

If the situation is such that it would be a bug for the input to be invalid, a somewhat simpler loop suffices:

 while (s < e) {
     Size_t advance;
     UV cp = utf8_to_uv_or_die(s, e, &advance);
     <handle 'cp'>
     s += advance;
 }

This will throw an exception on invalid input, so your code doesn't have to concern itself with that possibility. She said "not my problem." ๐Ÿ’…

If you do have a plan for handling malformed input, you could instead write:

 while (s < e) {
     Size_t advance;
     UV cp;

     if (UNLIKELY(! utf8_to_uv(s, e, &cp, &advance)) {
         <bail out or convert to handleable>
     }

     <handle 'cp'>

     s += advance;
 }

You may pass NULL to these functions instead of a pointer to your advance variable. But โ€” and this is a big but โ€” the only legitimate case to do this is if you are only examining the first character in s, and have no plans to ever look further. You could also advance by using UTF8SKIP, but this gives the correct result if and only if the input is well-formed; and this practice has led to successful attacks against such code; and it is extra work always, as the functions have already done the equivalent work and return the correct value in advance, regardless of whether the input is well-formed or not. So like, why would you. ๐Ÿ˜ญ

Except with utf8_to_uv_or_die, you must always pass a non-NULL pointer into which to store the (first) code point s represents. If you don't care about this value, you should be using one of the isUTF8_CHAR functions instead.


โœจ utf8_to_uvchr forms โœจ

These are the old form equivalents of utf8_to_uv (and its synonym, extended_utf8_to_uv). They are utf8_to_uvchr and utf8_to_uvchr_buf. There is no old form equivalent of either strict_utf8_to_uv nor c9strict_utf8_to_uv. They simply don't exist, bestie, don't go looking. ๐Ÿฆ‹

utf8_to_uvchr is DEPRECATED. Do NOT use it; it is a security hole ready to bring destruction onto you and yours. ๐Ÿ˜ฑ I am not being dramatic, that's literally what the page says.

utf8_to_uvchr_buf is discouraged and may eventually become deprecated. It checks if the sequence of bytes starting at s form a complete, legal UTF-8 (or UTF-EBCDIC) sequence for a code point. If so, it returns the code point value the sequence represents, and *retlen will be set to its length, in bytes. So the next possible character in s begins at s + *retlen. Cute, right?

The function only examines as many bytes along s as are needed to form a complete UTF-8 representation of a single code point, but it never examines the byte at e, or beyond.

If the sequence examined starting at s is not legal Perl extended UTF-8, the translation fails, and the resultant behavior unfortunately depends on if the warnings category utf8 is enabled or not. Yeah. It's giving "it depends." ๐Ÿซ 

  • If utf8 warnings are disabled โ€” the Unicode REPLACEMENT CHARACTER is silently returned, and *retlen is set (if retlen isn't NULL) so that (s + *retlen) is the next possible position in s that could begin a non-malformed character.

But note that it is ambiguous whether a REPLACEMENT CHARACTER was actually in the input, or if this function synthetically generated one. In the unlikely event that you care, you'd have to examine the input to disambiguate. ๐Ÿ™ƒ

  • If utf8 warnings are enabled โ€” a warning will be displayed, and 0 is returned and *retlen is set (if retlen isn't NULL) to -1.

But note that 0 may also be returned if *s is a legal NUL character. This means that you have to disambiguate a 0 return. You can do this by checking that the first byte of s is indeed a NUL; or by making sure to always pass a non-NULL retlen pointer, and by examining it.

Also note that should you wish to proceed with parsing s, you have no easy way of knowing where to start looking in it for the next possible character. It is important to look in the right place to prevent attacks on your code. It would be better to have instead called an equivalent function that provides this information; any of the utf8_to_uv series, or utf8n_to_uvchr.

Because of these quirks, utf8_to_uvchr_buf is very difficult to use correctly and handle all cases. Generally, you need to bail out at the first failure it finds.

The deprecated utf8_to_uvchr behaves the same way as utf8_to_uvchr_buf for well-formed input, and for the malformations it is capable of finding, but doesn't find all of them, and it can read beyond the end of the input buffer, which is why it is deprecated. Reading past the end of your buffer? Jail. Immediately. ๐Ÿš”

The utf8_to_uv() family of functions is preferred because they make it easier to write code safe from attacks. You should be converting to them; this will result in simpler, more robust code. That's the glow up, bestie, take it. ๐ŸŒˆ

            bool       utf8_to_uv         (      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool  Perl_utf8_to_uv         (      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool       extended_utf8_to_uv(      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool  Perl_extended_utf8_to_uv(      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool       strict_utf8_to_uv  (      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool  Perl_strict_utf8_to_uv  (      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool       c9strict_utf8_to_uv(      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            bool  Perl_c9strict_utf8_to_uv(      const U8 * const s,
                                                 const U8 * const e,
                                                 UV *cp_p, Size_t *advance_p)
            UV         utf8_to_uv_or_die  (      const U8 * const s,
                                                 const U8 *e,
                                                 Size_t *advance_p)
            UV    Perl_utf8_to_uv_or_die  (      const U8 * const s,
                                                 const U8 *e,
                                                 Size_t *advance_p)
            UV         utf8_to_uvchr_buf  (      const U8 *s, const U8 *send,
                                                 STRLEN *retlen)
            UV    Perl_utf8_to_uvchr_buf  (pTHX_ const U8 *s, const U8 *send,
                                                 STRLEN *retlen)
            UV         utf8_to_uvchr      (      const U8 *s, STRLEN *retlen)
            UV    Perl_utf8_to_uvchr      (pTHX_ const U8 *s, STRLEN *retlen)

"utf8_to_uv_errors*"

Okay bestie, this one's easy โ€” it's explained over at "utf8_to_uv_msgs". Go look there ๐Ÿซถ

"utf8_to_uv_flags" + "utf8n_to_uvchr"

Okay so these two are basically glow-ups of "utf8_to_uv", for when you need way more say over which UTF-8 sequences you're gonna accept. Ngl, you probably won't need these unless you're doing something pretty specialized. ๐Ÿ’…

"utf8n_to_uvchr" is more like a glow-up of "utf8_to_uvchr_buf", except it's got fewer quirky little behaviors, and a whole different way of telling it which bytes in s it's allowed to peek at. Instead of an e parameter, it takes a curlen parameter โ€” so the furthest byte in s it can ever look at is s + curlen - 1. And its failure return value does not depend on whether warnings are enabled or not. It's always 0 on failure. But โ€” and this is the same little plot twist as "utf8_to_uvchr_buf" โ€” 0 could also be the return for successfully translating an input NUL character. So use the exact same disambiguation trick given above to tell them apart. ๐Ÿ•ต๏ธ

But here's the win: unlike "utf8_to_uvchr_buf", you can actually trust *retlen โ€” except when the "UTF8_CHECK_ONLY" flag (described below) is in play โ€” to tell you where the next possible character along s starts. So that quirk? Gone. Periodt. Which means you should always use *retlen to figure out where the next character in s begins. ๐Ÿ‘‘

Both functions have an extra parameter, flags, on top of the ones in "utf8_to_uv" and "utf8_to_uvchr_buf". You use it to either broaden or restrict what counts as acceptable UTF-8. flags means the same thing and behaves the same way in both functions. When flags is 0, these functions accept any syntactically valid Perl-extended-UTF-8 sequence that doesn't overflow the platform's word size. ๐ŸŒˆ

So there's two flavors of flags, bestie: ones that control accepting particular sequences, and ones that control raising warnings when you run into sequences. They're totally independent of each other. So you can reject and not warn; warn and still accept; or both reject and warn. When a sequence gets rejected, it gets translated into the Unicode REPLACEMENT CHARACTER instead of whatever it was actually meant to represent. ๐Ÿ’€

Unless it says otherwise down below, warnings are subject to the "utf8" warnings category being turned on.
  • "UTF8_CHECK_ONLY" โ€” This one suppresses any warnings. And it changes what gets stored into *retlen with the "uvchr" family of functions โ€” and not in a good way, lowkey for the worse. It's not likely to be of any use to you. You can use "UTF8_ALLOW_ANY" (described below) instead to also turn off warnings, and that flag doesn't mess with *retlen at all. This flag gets ignored if "UTF8_DIE_IF_MALFORMED" is also set. ๐Ÿ™ˆ
  • "UTF8_FORCE_WARN_IF_MALFORMED" โ€” Normally, no warnings get generated if warnings are turned off lexically or globally, no matter what flags say to the contrary. But this flag effectively turns warnings on temporarily, for the duration of this function's execution. Do not use it lightly. This flag is ignored if "UTF8_CHECK_ONLY" is also set. ๐Ÿ”ฅ
  • "UTF8_DISALLOW_SURROGATE", "UTF8_WARN_SURROGATE" โ€” These reject and/or warn about UTF-8 sequences that represent surrogate characters. The warning categories "utf8" and "non_unicode" control whether warnings actually get raised.
  • "UTF8_DISALLOW_NONCHAR", "UTF8_WARN_NONCHAR" โ€” These reject and/or warn about UTF-8 sequences that represent non-character code points. The warning categories "utf8" and "nonchar" control whether warnings actually get raised.
  • "UTF8_DISALLOW_SUPER", "UTF8_WARN_SUPER" โ€” These reject and/or warn about UTF-8 sequences that represent code points above 0x10FFFF. The warning categories "utf8" and "non_unicode" control whether warnings actually get raised.
  • "UTF8_DISALLOW_ILLEGAL_INTERCHANGE", "UTF8_WARN_ILLEGAL_INTERCHANGE" โ€” These are the same as selecting all three of the corresponding SURROGATE, NONCHAR and SUPER flags listed above. All such code points are not considered to be safely, freely exchangeable between processes. ๐Ÿšซ
  • "UTF8_DISALLOW_ILLEGAL_C9_INTERCHANGE", "UTF8_WARN_ILLEGAL_C9_INTERCHANGE" โ€” These are the same as selecting both the corresponding SURROGATE and SUPER flags listed above. Unicode issued Unicode Corrigendum #9 (https://www.unicode.org/versions/corrigendum9.html) to allow non-character code points to be exchanged by processes that are aware of the possibility. (They're still discouraged, though.) For more discussion see "Noncharacter code points" in perlunicode.
  • "UTF8_DISALLOW_PERL_EXTENDED", "UTF8_WARN_PERL_EXTENDED" โ€” These reject and/or warn when you hit sequences that need Perl's extension to UTF-8 to represent them. These are all for code points above 0x10FFFF, so they're a subset of the ones controlled by SUPER or either of the illegal interchange sets of flags. The warning categories "utf8", "non_unicode", and "portable" control whether warnings actually get raised.

Okay so the lore โœจ: Perl predates Unicode, and earlier standards allowed for code points all the way up through 0x7FFF_FFFF (2**31 - 1). And Perl, obviously, would love for you to be able to represent in UTF-8 any code point that's available on the platform. To do that, some extension has to be used to express them. Perl uses a natural extension to UTF-8 to represent the ones up to 2**36-1, and then invented a further extension to represent even higher ones, so that any code point that fits in a 64-bit word can be represented. We lump both of these extensions together and call them Perl extended UTF-8. (Other people have invented other extensions, but they're incompatible with Perl's. ๐Ÿ’€)

On EBCDIC platforms starting in Perl v5.24, the Perl extension for representing extremely high code points kicks in at 0x3FFF_FFFF (2**30 -1), which is lower than it is on ASCII. Prior to that, code points 2**31 and higher were just unrepresentable, and a different, incompatible method was used to represent code points between 2**30 and 2**31 - 1.

It's likely that programs written in something other than Perl wouldn't be able to read files that contain these; and Perl also wouldn't understand files written by something that uses a different extension. So that's why you can specify that above-Unicode code points are generally accepted and/or warned about, but still exclude the ones that require this extension to represent. ๐Ÿงš

  • "UTF8_ALLOW_ANY" and kin โ€” Other flags can be passed to allow, in a limited way, syntactic malformations and/or overflowing the number of bits available in a UV on the platform. These functions won't treat the relevant malformations as errors, so they won't raise any warnings for them. "utf8_to_uv_msgs" will return "true".

But heads up โ€” all such malformations translate to the REPLACEMENT CHARACTER, no matter what any of the flags say. ๐Ÿ˜ญ

The only such flag you'd ever have any actual reason to use is "UTF8_ALLOW_ANY", which applies to any of the syntactic malformations and overflow, except for empty input. The other flags are analogous to the ones in the "_GOT_" bits list in "utf8_to_uv_msgs".

  • "UTF8_DIE_IF_MALFORMED" โ€” If the function would otherwise return "false", it croaks instead. The "UTF8_FORCE_WARN_IF_MALFORMED" flag is effectively turned on so that the cause of the croak gets displayed. ๐Ÿ’€
            bool       utf8_to_uv_flags(const U8 * const s,
                                        const U8 * const e, UV *cp_p,
                                        Size_t *advance_p, U32 flags)
            bool  Perl_utf8_to_uv_flags(const U8 * const s,
                                        const U8 * const e, UV *cp_p,
                                        Size_t *advance_p, U32 flags)
            UV         utf8n_to_uvchr  (const U8 *s, STRLEN curlen,
                                        STRLEN *retlen, const U32 flags)
            UV    Perl_utf8n_to_uvchr  (const U8 *s, STRLEN curlen,
                                        STRLEN *retlen, const U32 flags)

โœจ "utf8_to_uv_msgs", "utf8n_to_uvchr_msgs", "utf8_to_uv_errors", "utf8n_to_uvchr_error" โœจ

okay bestie, these four are glow-ups of "utf8_to_uv_flags" and "utf8n_to_uvchr" ๐Ÿ’… โ€” they exist for one very specific hyper-specialized situation: when you, the caller, need to know the exact malformations that got found and/or the diagnostics that would have been raised. iykyk.

They each take one or two extra parameters โ€” pointers to where this info gets stashed ๐Ÿซถ. The ones with _msgs in their names return both types of info, so they take two extra parameters. The ones with _error return just the malformations, so they take just one extra parameter. And real talk: when those extra parameters are both 0, these functions behave identically to the function they extend. no notes ๐Ÿ’€

When the "errors" parameter is not NULL, it should be the address of a U32 variable, into which the functions store a bitmap (described just below, stay with me) with a bit set for each malformation the function found โ€” and 0 if there were none ๐ŸŽ€.

The "ALLOW"-type flags are ignored when determining the content of this variable. Like, even if you "allow" a particular malformation, if it gets encountered, the corresponding bit will be set to notify you that one was encountered ๐Ÿ‘€. However โ€” the bits for conditions that are accepted by default aren't set unless the flags passed to the function indicate that they should be rejected or warned about when encountering them. These are all explicitly noted in the list below, along with the controlling flags, so read carefully babes ๐Ÿ“–โœจ


๐ŸŒˆ the bits returned in "errors" and their meanings

  • UTF8_GOT_CONTINUATION โ€” the input sequence was malformed in that the first byte was a UTF-8 continuation byte.
  • UTF8_GOT_EMPTY โ€” the input parameters indicated the length of "s" is 0. Technically this is a coding error, not a malformation โ€” you should check before calling these functions if there's actually anything to convert ๐Ÿ™ˆ. But perl needs to be able to recover from bad input, and this is how it does it.
  • UTF8_GOT_LONG โ€” the input sequence was malformed in that there is some other sequence that evaluates to the same code point, but that sequence is shorter than this one. Until Unicode 3.1, it was legal for programs to accept this malformation, but it was discovered that this created security issues ๐Ÿ˜ญ so yeah, that's a no from us.
  • UTF8_GOT_NONCHAR โ€” the code point represented by the input UTF-8 sequence is for a Unicode non-character code point. This bit is set only if the input "flags" parameter contains either the "UTF8_DISALLOW_NONCHAR" or the "UTF8_WARN_NONCHAR" flags.
  • UTF8_GOT_NON_CONTINUATION โ€” the input sequence was malformed in that a non-continuation-type byte was found in a position where only a continuation-type one should be. See also "UTF8_GOT_SHORT".
  • UTF8_GOT_OVERFLOW โ€” the input sequence was malformed in that it is for a code point that is not representable in the number of bits available in an IV on the current platform.
  • UTF8_GOT_PERL_EXTENDED โ€” the input sequence is not standard UTF-8, but a Perl extension ๐Ÿฆ‹. This bit is set only if the input "flags" parameter contains either the "UTF8_DISALLOW_PERL_EXTENDED" or the "UTF8_WARN_PERL_EXTENDED" flags.
  • UTF8_GOT_SHORT โ€” the input sequence was malformed in that "curlen" is smaller than required for a complete sequence. In other words, the input is for a partial character sequence.

"UTF8_GOT_SHORT" and "UTF8_GOT_NON_CONTINUATION" both indicate a too-short sequence. The difference is that "UTF8_GOT_NON_CONTINUATION" indicates always that there is an error, while "UTF8_GOT_SHORT" means that an incomplete sequence was looked at. If no other flags are present, it means that the sequence was valid as far as it went. Depending on the application, this could mean one of three things:

  • The "e" or "curlen" parameters passed in were too small, and the function was prevented from examining all the necessary bytes.
  • The buffer being looked at is based on reading data, and the data received so far stopped in the middle of a character, so that the next read will read the remainder of this character. (It is up to the caller to deal with the split bytes somehow ๐Ÿ‘‘)
  • This is a real error, and the partial sequence is all we're going to get ๐Ÿ’€
  • UTF8_GOT_SUPER โ€” the input sequence was malformed in that it is for a non-Unicode code point; that is, one above the legal Unicode maximum. This bit is set only if the input "flags" parameter contains either the "UTF8_DISALLOW_SUPER" or the "UTF8_WARN_SUPER" flags.
  • UTF8_GOT_SURROGATE โ€” the input sequence was malformed in that it is for a Unicode UTF-16 surrogate code point. This bit is set only if the input "flags" parameter contains either the "UTF8_DISALLOW_SURROGATE" or the "UTF8_WARN_SURROGATE" flags.

Note that more than one bit may have been set by these functions ๐Ÿ‘€โœจ. That's because it is possible for multiple malformations to be present in the same sequence. An example would be an overlong sequence evaluating to a surrogate when surrogates are forbidden. Another example is overflow โ€” standard UTF-8 never overflows, so something that does must have been expressed using Perl's extended UTF-8. It also is above all legal Unicode code points. So there will be a bit set for up to all three of these things:

  1. Overflow always;
  2. perl-extended if the calling flags indicate those should be rejected or warned about; and
  3. above-Unicode, provided the calling flags indicate those should be rejected or warned about.

If you don't care about the system's messages text nor warning categories, you can customize error handling by calling one of the _error functions, using either of the flags "UTF8_ALLOW_ANY" or "UTF8_CHECK_ONLY" to suppress any warnings, and then examine the *errors return. If you don't use those flags, warnings will be raised as usual ๐Ÿ“ข.

But if you do care, instead use one of the functions with _msgs in their names ๐ŸŽ€. These allow you to completely customize error handling by suppressing any warnings that would otherwise be raised โ€” instead returning all relevant information in a structure specified by an extra parameter, "msgs", a pointer to a variable which has been declared to be an "AV*", and into which the function creates a new AV to store information, described below, about all the malformations that were encountered. iconic behaviour fr fr ๐Ÿ’…

When this parameter is non-NULL, the "UTF8_DIE_IF_MALFORMED" and "UTF8_FORCE_WARN_IF_MALFORMED" flags are asserted against in DEBUGGING builds, and are ignored in non-DEBUGGING ones. The "UTF8_CHECK_ONLY" flag is always ignored.

What is considered a malformation is affected by "flags", the same as described in "utf8_to_uv_flags". No array element is generated for malformations that are "allowed" by the input flags โ€” in contrast to the bitmap returned in a non-NULL *errors ๐Ÿ”ฅ.


๐Ÿงš each element of the "msgs" AV array

Each one is an anonymous hash with the following three key-value pairs:

  • "text" โ€” a "SVpv" containing the text of the message about the problematic input. This text is identical to any warning that otherwise would have been raised if the appropriate warning categories were enabled.
  • "warn_categories" โ€” this is 0 if the "flags" parameter to the function would ordinarily not have caused the message to be output as a warning; otherwise it is the warning category (or categories) that would have been used to generate a warning for "text", packed into a "SVuv". For example, if "flags" contains "UTF8_DISALLOW_SURROGATE", but not "UTF8_WARN_SURROGATE", this would be 0 if the input was a surrogate.
  • "flag" โ€” a "SVuv" containing a single flag bit associated with this message. The bit corresponds to some bit in the *errors return value, such as "UTF8_GOT_LONG".

The array is sorted so that element "[0]" contains the first message that would have otherwise been raised; "[1]", the second; and so on ๐ŸŒธ.

You thus can completely override the normal error handling; you can check the lexical warnings state (or not) when choosing what to do with the returned messages. main character energy, honestly ๐Ÿ’œ

The caller, of course, is responsible for freeing any returned AV. don't forget bestie ๐Ÿ˜ญ


 bool       utf8_to_uv_msgs     (const U8 * const s0, const U8 *e,
                                 UV *cp_p, Size_t *advance_p,
                                 U32 flags, U32 *errors,
                                 AV **msgs)
 bool  Perl_utf8_to_uv_msgs     (const U8 * const s0, const U8 *e,
                                 UV *cp_p, Size_t *advance_p,
                                 U32 flags, U32 *errors,
                                 AV **msgs)
 UV         utf8n_to_uvchr_msgs (const U8 * const s0,
                                 STRLEN curlen, STRLEN *retlen,
                                 const U32 flags, U32 *errors,
                                 AV **msgs)
 UV    Perl_utf8n_to_uvchr_msgs (const U8 * const s0,
                                 STRLEN curlen, STRLEN *retlen,
                                 const U32 flags, U32 *errors,
                                 AV **msgs)
 bool       utf8_to_uv_errors   (const U8 * const s,
                                 const U8 * const e, UV *cp_p,
                                 Size_t *advance_p, U32 flags,
                                 U32 *errors)
 bool  Perl_utf8_to_uv_errors   (const U8 * const s,
                                 const U8 * const e, UV *cp_p,
                                 Size_t *advance_p, U32 flags,
                                 U32 *errors)
 UV         utf8n_to_uvchr_error(const U8 *s, STRLEN curlen,
                                 STRLEN *retlen, const U32 flags,
                                 U32 *errors)
 UV    Perl_utf8n_to_uvchr_error(const U8 *s, STRLEN curlen,
                                 STRLEN *retlen, const U32 flags,
                                 U32 *errors)

utf8_to_uv_or_die*, utf8_to_uvchr*, utf8_to_uvchr_buf*

Okay bestie, these three are all described under utf8_to_uv ๐Ÿ’– so go peek there, iykyk โœจ

utf8n_to_uvchr*

Described under utf8_to_uv_flags ๐Ÿซถ

utf8ness_t

So this typedef is used by a bunch of core functions that return PV strings, and its whole job is to tell you the UTF-8ness of those strings ๐ŸŒˆ

If youโ€™re writing a new function, bestie, you probably should instead return the PV in an SV with the UTF-8 flag of the SV properly set, rather than use this mechanism ๐Ÿ‘€

The possible values this can be are:

  • UTF8NESS_YES โ€” this means the string definitely should be treated as a sequence of UTF-8-encoded characters ๐Ÿ’… Most code that needs to handle this typedef should be of the form:
if (utf8ness_flag == UTF8NESS_YES) {
    treat as utf8;  // like turning on an SV UTF-8 flag
}
  • UTF8NESS_NO โ€” this means the string definitely should be treated as a sequence of bytes, not encoded as UTF-8 ๐Ÿงš
  • UTF8NESS_IMMATERIAL โ€” this means it is equally valid to treat the string as bytes, or as UTF-8 characters; use whichever way you want ๐Ÿ’ซ This happens when the string consists entirely of characters which have the same representation whether encoded in UTF-8 or not โœจ
  • UTF8NESS_UNKNOWN โ€” this means it is unknown how the string should be treated ๐Ÿ˜ญ No core function will ever return this value to a non-core caller. Instead, it is used by the caller to initialize a variable to a non-legal value. A typical call will look like:
utf8ness_t string_is_utf8 = UTF8NESS_UNKNOWN
const char * string = foo(arg1, arg2, ..., &string_is_utf8);
if (string_is_utf8 == UTF8NESS_YES) {
   do something for UTF-8;
}

The following relationships hold between the enum values:

  • 0 <= enum value <= UTF8NESS_IMMATERIAL โ€” the string may be treated in code as non-UTF8 ๐Ÿ‘‘
  • UTF8NESS_IMMATERIAL <= <enum value โ€” the string may be treated in code as encoded in UTF-8 ๐ŸŒธ

UTF8SKIP, UTF8_SKIP, UTF8_CHK_SKIP, UTF8_SAFE_SKIP

Each of these returns the number of bytes in the UTF-8 encoded character whose first (perhaps only) byte is pointed to by s ๐Ÿ’–

  • UTF8SKIP and UTF8_SKIP are synonyms. Use them when there is no possibility that the character pointed to by s is malformed โœจ
  • If there is a possibility of malformed input, use instead:
    • UTF8_SAFE_SKIP if you know the maximum ending pointer in the buffer pointed to by s ๐ŸŒˆ
      • If the buffer has enough bytes to hold the character, it returns the same value as UTF8SKIP and UTF8_SKIP would. If the buffer has fewer bytes than can fit, it returns the number of bytes available in the buffer, which could be 0 if s >= e. On DEBUGGING builds, it asserts that s <= e ๐Ÿ‘€
    • UTF8_CHK_SKIP if you donโ€™t know the maximum ending pointer ๐Ÿฆ‹
      • This version doesnโ€™t blindly assume that the input string pointed to by s is well-formed, but verifies that there isnโ€™t a NUL terminating character before the expected end of the next character in s. The length UTF8_CHK_SKIP returns stops just before any such NUL ๐Ÿ›‘
      • Perl tends to add NULs, as an insurance policy, after the end of strings in SVโ€™s, so it is likely that using this macro on an SV string will prevent inadvertent reading beyond the end of the input buffer, even if it is malformed UTF-8 ๐Ÿ’€
      • This macro is intended to be used by XS modules where the inputs could be malformed, and it isnโ€™t feasible to restructure to use the safer UTF8_SAFE_SKIP, for example when interfacing with a C library ๐Ÿ’…
 STRLEN  UTF8SKIP      (const char* s)
 STRLEN  UTF8_SKIP     (const char* s)
 STRLEN  UTF8_CHK_SKIP (const char* s)
 STRLEN  UTF8_SAFE_SKIP(const char* s, const char* e)

uv_to_utf8, uv_to_utf8_flags, uvchr_to_utf8, uvchr_to_utf8_flags

These each add the UTF-8 representation of the native code point uv to the end of the string d; d should have at least UVCHR_SKIP(uv)+1 (up to UTF8_MAXBYTES+1) free bytes available ๐ŸŽ€ The return value is the pointer to the byte after the end of the new character. In other words,

d = uv_to_utf8(d, uv);

This is the Unicode-aware way of saying

*(d++) = uv;

(uvchr_to_utf8 is a synonym for uv_to_utf8.) ๐Ÿ’–

uv_to_utf8_flags is used to make some classes of code points problematic in some way ๐Ÿ‘€ uv_to_utf8 is effectively the same as calling uv_to_utf8_flags with flags set to 0, meaning no class of code point is considered problematic. That means any input code point from 0..IV_MAX is considered to be fine. IV_MAX is typically 0x7FFF_FFFF in a 32-bit word ๐ŸŒˆ

(uvchr_to_utf8_flags is a synonym for uv_to_utf8_flags.) โœจ

A code point can be problematic in one of two ways. Its use could just raise a warning, and/or it could be forbidden with the function failing, and returning NULL ๐Ÿ˜ญ

The potential classes of problematic code points and the flags that make them so are:

  • If uv is a Unicode surrogate code point and UNICODE_WARN_SURROGATE is set, the function will raise a warning, provided UTF8 warnings are enabled โš ๏ธ If instead UNICODE_DISALLOW_SURROGATE is set, the function will fail and return NULL ๐Ÿ›‘ If both flags are set, the function will both warn and return NULL ๐Ÿ’€
  • Similarly, the UNICODE_WARN_NONCHAR and UNICODE_DISALLOW_NONCHAR flags affect how the function handles a Unicode non-character ๐Ÿงš
  • And likewise, the UNICODE_WARN_SUPER and UNICODE_DISALLOW_SUPER flags affect the handling of code points that are above the Unicode maximum of 0x10FFFF ๐Ÿ‘‘ Languages other than Perl may not be able to accept files that contain these ๐Ÿ‘€
  • The flag UNICODE_WARN_ILLEGAL_INTERCHANGE selects all three of the above WARN flags; and UNICODE_DISALLOW_ILLEGAL_INTERCHANGE selects all three DISALLOW flags โœจ UNICODE_DISALLOW_ILLEGAL_INTERCHANGE restricts the allowed inputs to the strict UTF-8 traditionally defined by Unicode ๐ŸŒธ Similarly, UNICODE_WARN_ILLEGAL_C9_INTERCHANGE and UNICODE_DISALLOW_ILLEGAL_C9_INTERCHANGE are shortcuts to select the above-Unicode and surrogate flags, but not the non-character ones, as defined in Unicode Corrigendum #9 https://www.unicode.org/versions/corrigendum9.html ๐Ÿ’… See "Noncharacter code points" in perlunicode ๐Ÿ’–
  • Extremely high code points were never specified in any standard, and require an extension to UTF-8 to express, which Perl does ๐ŸŒˆ It is likely that programs written in something other than Perl would not be able to read files that contain these; nor would Perl understand files written by something that uses a different extension ๐Ÿ˜ญ For these reasons, there is a separate set of flags that can warn and/or disallow these extremely high code points, even if other above-Unicode ones are accepted. They are the UNICODE_WARN_PERL_EXTENDED and UNICODE_DISALLOW_PERL_EXTENDED flags โœจ For more information see UTF8_GOT_PERL_EXTENDED ๐Ÿ‘€ Of course UNICODE_DISALLOW_SUPER will treat all above-Unicode code points, including these, as malformations ๐Ÿ’€ (Note that the Unicode standard considers anything above 0x10FFFF to be illegal, but there are standards predating it that allow up to 0x7FFF_FFFF (2**31 -1)) ๐ŸŽ€
  • A somewhat misleadingly named synonym for UNICODE_WARN_PERL_EXTENDED is retained for backward compatibility: UNICODE_WARN_ABOVE_31_BIT ๐Ÿ‘‘ Similarly, UNICODE_DISALLOW_ABOVE_31_BIT is usable instead of the more accurately named UNICODE_DISALLOW_PERL_EXTENDED ๐Ÿฆ‹ The names are misleading because on EBCDIC platforms, these flags can apply to code points that actually do fit in 31 bits. The new names accurately describe the situation in all cases ๐Ÿ’…
 U8 *       uv_to_utf8         (      U8 *d, UV uv)
 U8 *  Perl_uv_to_utf8         (pTHX_ U8 *d, UV uv)
 U8 *       uv_to_utf8_flags   (      U8 *d, UV uv, UV flags)
 U8 *  Perl_uv_to_utf8_flags   (pTHX_ U8 *d, UV uv, UV flags)
 U8 *       uvchr_to_utf8      (      U8 *d, UV uv)
 U8 *  Perl_uvchr_to_utf8      (pTHX_ U8 *d, UV uv)
 U8 *       uvchr_to_utf8_flags(      U8 *d, UV uv, UV flags)
 U8 *  Perl_uvchr_to_utf8_flags(pTHX_ U8 *d, UV uv, UV flags)

uv_to_utf8_msgs, uvchr_to_utf8_flags_msgs

These functions are identical ๐Ÿ‘ฏโ€โ™€๏ธ THEY SHOULD BE USED IN ONLY VERY SPECIALIZED CIRCUMSTANCES ๐Ÿšจ The uv_to_utf8_msgs spelling is preferred in new code ๐Ÿ’–

Most code should use "uv_to_utf8_flags"() rather than call these directly ๐Ÿ‘‘

These functions are for code that wants any warning and/or error messages to be returned to the caller rather than be displayed ๐Ÿ“ฌ Any message that would have been displayed if all lexical warnings are enabled will instead be returned โœจ

They are just like uv_to_utf8_flags but take an extra parameter placed after all the others, msgs ๐ŸŽ€ If this parameter is 0, the functions behave identically to uv_to_utf8_flags ๐Ÿ’ซ Otherwise, msgs should be a pointer to an HV * variable, in which these functions create a new HV to contain any appropriate message ๐ŸŒธ The hash has three key-value pairs, as follows:

  • text โ€” the text of the message as a SVpv ๐Ÿ’…
  • warn_categories โ€” the warning category (or categories) packed into a SVuv ๐ŸŒˆ
  • flag_bit โ€” a single flag bit associated with this message, in a SVuv โญ The bit corresponds to some bit in the *errors return value. The possibilities are:
    • UNICODE_GOT_SURROGATE
    • UNICODE_GOT_NONCHAR
    • UNICODE_GOT_SUPER
    • UNICODE_GOT_PERL_EXTENDED
Itโ€™s important to note that specifying this parameter as non-null will cause any warning the functions would otherwise generate to be suppressed, and instead be placed in *msgs ๐Ÿ˜ฑ The caller can check the lexical warnings state (or not) when choosing what to do with the returned message ๐Ÿ‘€

Only a single message gets handed back โ€” and btw if a code point needs Perl extended UTF-8 to represent itself, it's also above-Unicode. If either the UNICODE_WARN_PERL_EXTENDED or UNICODE_DISALLOW_PERL_EXTENDED flags are set, the return is controlled by them; if neither one is set, then the return is controlled by the UNICODE_WARN_SUPER and UNICODE_DISALLOW_SUPER flags instead.

The caller is, of course, the one responsible for freeing any returned HV. so like, clean up after urself bestie ๐Ÿ’…

 U8 *       uv_to_utf8_msgs         (      U8 *d, UV uv, UV flags,
                                           HV **msgs)
 U8 *  Perl_uv_to_utf8_msgs         (pTHX_ U8 *d, UV uv, UV flags,
                                           HV **msgs)
 U8 *       uvchr_to_utf8_flags_msgs(      U8 *d, UV uv, UV flags,
                                           HV **msgs)
 U8 *  Perl_uvchr_to_utf8_flags_msgs(pTHX_ U8 *d, UV uv, UV flags,
                                           HV **msgs)

โœจ "UVCHR_IS_INVARIANT"

Evaluates to 1 if the representation of code point cp is the exact same whether or not it's encoded in UTF-8, otherwise it evaluates to 0. UTF-8 invariant characters can just be copied as-is when you're converting to/from UTF-8, which saves time. And cp is Unicode if it's above 255, otherwise it's platform-native.

 bool  UVCHR_IS_INVARIANT(UV cp)

โœจ "UVCHR_SKIP"

returns the number of bytes you need to represent the code point cp when it's encoded as UTF-8. cp is a native (ASCII or EBCDIC) code point if it's less than 255, and a Unicode code point otherwise.

 STRLEN  UVCHR_SKIP(UV cp)

โœจ "uvchr_to_utf8*"

โœจ "uvchr_to_utf8_flags*"

Described under "uv_to_utf8" ๐Ÿ‘ˆ go look there, bestie

โœจ "uvchr_to_utf8_flags_msgs*"

Described under "uv_to_utf8_msgs" ๐Ÿ‘ˆ yeah same deal


๐ŸŒˆ Utility Functions ๐ŸŒˆ

โญ "C_ARRAY_END"

Returns a pointer to one element past the final element of the input C array. classic "one past the end" behavior, no cap.

 void *  C_ARRAY_END(void *a)

โญ "C_ARRAY_LENGTH"

Returns the number of elements in the input C array โ€” so yeah, you want your zero-based indices to be less than but not equal to that number. (<, not <=. periodt.)

 STRLEN  C_ARRAY_LENGTH(void *a)

โญ "getcwd_sv"

Fill sv with current working directory

 int       getcwd_sv(      SV *sv)
 int  Perl_getcwd_sv(pTHX_ SV *sv)

โญ "grok_bin"

โญ "grok_hex"

โญ "grok_oct"

These each convert a string representing a number to numeric form. The number is binary in grok_bin, octal in grok_oct, and hexadecimal in grok_hex. three flavors, one function family ๐Ÿ“

On entry, start and *len_p give the string to scan, *flags gives conversion flags, and approximation should be NULL or a pointer to an NV. The scan stops at the end of the string, or right before the first invalid character. Unless PERL_SCAN_SILENT_ILLDIGIT is set in *flags, encountering an invalid character (except NUL) will also trigger a warning. On return, *len_p is set to the length of the scanned string, and *flags gives output flags.

If the value is <= UV_MAX, it's returned as a UV, the output flags are clear, and nothing is written to *approximation. If the value is > UV_MAX:

  • UV_MAX is returned
  • PERL_SCAN_GREATER_THAN_UV_MAX is set in *flags.
  • If approximation is not null, an approximation of the correct value is written into *approximation (which is an NV).

Unless PERL_SCAN_DISALLOW_PREFIX is set in *flags on entry:

  • For grok_bin โ€” the input string may optionally be prefixed with 0b or plain b
  • For grok_hex โ€” the input string may optionally be prefixed with 0x or plain x
  • For grok_oct โ€” this flag is ignored; there is no optional prefix. The typical 0 prefix is just part of the number.

If PERL_SCAN_ALLOW_UNDERSCORES is set in *flags then any or all pairs of digits may be separated from each other by a single underscore, and also a single leading underscore is accepted. (yes you can have the lil _ dividers, iconic honestly โœจ)

 UV       grok_bin(      const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)
 UV  Perl_grok_bin(pTHX_ const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)
 UV       grok_hex(      const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)
 UV  Perl_grok_hex(pTHX_ const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)
 UV       grok_oct(      const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)
 UV  Perl_grok_oct(pTHX_ const char *start, STRLEN *len_p,
                         I32 *flags, NV *approximation)

โญ "IN_PERL_COMPILETIME"

Returns 1 if this macro is being called during the compilation phase of the program; otherwise 0;

 bool  IN_PERL_COMPILETIME

โญ "IN_PERL_RUNTIME"

Returns 1 if this macro is being called during the execution phase of the program; otherwise 0;

 bool  IN_PERL_RUNTIME

โญ "is_safe_syscall"

โญ "IS_SAFE_SYSCALL"

These are synonymous.

They test that the given pv (with length len) doesn't contain any internal NUL characters. If it does, set errno to ENOENT, optionally warn using the syscalls category, and return FALSE.

Return TRUE if the name is safe. ๐Ÿซถ

what and op_name are used in any warning.

 bool       is_safe_syscall(      const char *pv, STRLEN len,
                                  const char *what,
                                  const char *op_name)
 bool  Perl_is_safe_syscall(pTHX_ const char *pv, STRLEN len,
                                  const char *what,
                                  const char *op_name)
 bool       IS_SAFE_SYSCALL(      const char *pv, STRLEN len,
                                  const char *what,
                                  const char *op_name)

โญ "my_setenv"

A wrapper for the C library setenv(3). Do not use the latter, ok? because the perl version has desirable safeguards. genuinely, don't skip the safeguards ๐Ÿ’€

 void       my_setenv(      const char *nam, const char *val)
 void  Perl_my_setenv(pTHX_ const char *nam, const char *val)

โญ "newPADxVOP"

Constructs, checks and returns an op containing a pad offset. type is the opcode, which should be one of OP_PADSV, OP_PADAV, OP_PADHV or OP_PADCV. The returned op will have the op_targ field set by the padix argument.

This is convenient when you're constructing a large optree in nested function calls, because it avoids needing to store the pad op directly just to set the op_targ field as a side-effect. For example:

 o = op_append_elem(OP_LINESEQ, o,
     newPADxVOP(OP_PADSV, 0, padix));
 OP *       newPADxVOP(      I32 type, I32 flags, PADOFFSET padix)
 OP *  Perl_newPADxVOP(pTHX_ I32 type, I32 flags, PADOFFSET padix)

โญ "phase_name"

Returns the given phase's name as a NUL-terminated string.

Like, for example, if you want to print a stack trace that includes the current interpreter phase you might do this:

 const char* phase_name = phase_name(PL_phase);
 mess("This is weird. (Perl phase: %s)", phase_name);
 const char *       phase_name(      enum perl_phase phase)
 const char *  Perl_phase_name(pTHX_ enum perl_phase phase)

โญ "StructCopy"

This is an architecture-independent macro that does a shallow copy of one structure to another. shallow, bestie. shallow. ๐Ÿ™ˆ

 void  StructCopy(type *src, type *dest, type)

โญ "sv_destroyable"

Dummy routine which reports that object can be destroyed when there is no sharing module present. It ignores its single SV argument, and returns 'true'. Exists to avoid a test for a NULL function pointer, and because it could potentially warn under some level of strict-ness.

 bool       sv_destroyable(      SV *sv)
 bool  Perl_sv_destroyable(pTHX_ SV *sv)

โญ "sv_nosharing"

Dummy routine which "shares" an SV when there is no sharing module present. Or "locks" it. Or "unlocks" it. In other words, it ignores its single SV argument. Exists to avoid a test for a NULL function pointer, and because it could potentially warn under some level of strict-ness.

(not it doing absolutely nothing and still being here for the vibes ๐Ÿ˜ญ)

 void       sv_nosharing(      SV *sv)
 void  Perl_sv_nosharing(pTHX_ SV *sv)

โœจ Versioning โœจ

๐Ÿ’– new_version ๐Ÿ’–

okay so this one hands you a brand new version object made from the SV you pass in, bestie:

SV *sv = new_version(SV *ver);

and here's the thing โ€” it does not touch the ver SV you gave it. like, at all. it leaves it exactly how it found it ๐Ÿซถ. so if you wanted it upgraded in place instead, go look at "upg_version" instead, that's literally its whole job.

 SV *       new_version(      SV *ver)
 SV *  Perl_new_version(pTHX_ SV *ver)

๐Ÿ’… PERL_REVISION ๐Ÿ’…

DEPRECATED! It is planned to remove PERL_REVISION from a future release of Perl. Do not use it for new code; remove it from existing code.

this is the major number component of the perl interpreter you're currently compiling or executing. iconic fact: it's been 5 from 1993 all the way into 2020. it's giving "committed to the bit" ๐Ÿ’€

but no, don't use it โ€” instead use one of the version comparison macros. see "PERL_VERSION_EQ".


๐ŸŽ€ PERL_SUBVERSION ๐ŸŽ€

DEPRECATED! It is planned to remove PERL_SUBVERSION from a future release of Perl. Do not use it for new code; remove it from existing code.

this one is the micro number component of the perl interpreter currently being compiled or executing. in stable releases it gives you the dot release number for maintenance updates. in development releases it gives you a tag for a snapshot of the status at various points in the development cycle โœจ (yes it's a whole mood tracker for the dev cycle, slay)

instead, please use one of the version comparison macros. see "PERL_VERSION_EQ".


๐Ÿฆ‹ PERL_VERSION ๐Ÿฆ‹

DEPRECATED! It is planned to remove PERL_VERSION from a future release of Perl. Do not use it for new code; remove it from existing code.

the minor number component of the perl interpreter currently being compiled or executing. between 1993 into 2020, this ranged from 0 to 33. glow-up era fr.

instead use one of the version comparison macros. see "PERL_VERSION_EQ".


๐Ÿ‘‘ PERL_VERSION_EQ, PERL_VERSION_GE, PERL_VERSION_GT, PERL_VERSION_LE, PERL_VERSION_LT, PERL_VERSION_NE ๐Ÿ‘‘

these tell you whether or not the perl currently being compiled has the specified relationship to the perl given by the parameters. for example:

#if PERL_VERSION_GT(5,24,2)
  code that will only be compiled on perls after v5.24.2
#else
  fallback code
#endif

note that this is usable in making compile-time decisions ๐Ÿง โœจ

and here's the bestie cheat code: you may use the special value '*' for the final number to mean ALL possible values for it. thus,

#if PERL_VERSION_EQ(5,31,'*')

means all perls in the 5.31 series. and

#if PERL_VERSION_NE(5,24,'*')

means all perls EXCEPT 5.24 ones. and

#if PERL_VERSION_LE(5,9,'*')

is effectively

#if PERL_VERSION_LT(5,10,0)

this means you don't have to think so much when converting from the existing deprecated "PERL_VERSION" to using this macro:

#if PERL_VERSION <= 9

becomes

#if PERL_VERSION_LE(5,9,'*')

and the signatures, verbatim, no cap:

 bool  PERL_VERSION_EQ(const U8 major, const U8 minor,
                       const U8 patch)
 bool  PERL_VERSION_GE(const U8 major, const U8 minor,
                       const U8 patch)
 bool  PERL_VERSION_GT(const U8 major, const U8 minor,
                       const U8 patch)
 bool  PERL_VERSION_LE(const U8 major, const U8 minor,
                       const U8 patch)
 bool  PERL_VERSION_LT(const U8 major, const U8 minor,
                       const U8 patch)
 bool  PERL_VERSION_NE(const U8 major, const U8 minor,
                       const U8 patch)

๐ŸŒˆ prescan_version ๐ŸŒˆ

this validates that a given string can be parsed as a version object, but it doesn't actually do the parsing. it's a vibe check, not a commitment ๐Ÿซถ. can use either strict or lax validation rules. can optionally set a number of hint variables to save the parsing code some time when tokenizing. very considerate of it honestly ๐Ÿ’…

 const char *       prescan_version(      const char *s,
                                          bool strict,
                                          const char **errstr,
                                          bool *sqv,
                                          int *ssaw_decimal,
                                          int *swidth,
                                          bool *salpha)
 const char *  Perl_prescan_version(pTHX_ const char *s,
                                          bool strict,
                                          const char **errstr,
                                          bool *sqv,
                                          int *ssaw_decimal,
                                          int *swidth,
                                          bool *salpha)

๐Ÿ’œ scan_version ๐Ÿ’œ

returns a pointer to the next character after the parsed version string, and also upgrades the passed-in SV to an RV. multitasking icon behavior fr.

function must be called with an already existing SV like

    sv = newSV(0);
    s = scan_version(s, SV *sv, bool qv);

performs some preprocessing to the string to ensure that it has the correct characteristics of a version. Flags the object if it contains an underscore (which denotes this is an alpha version ๐Ÿผ). The boolean qv denotes that the version should be interpreted as if it had multiple decimals, even if it doesn't.

 const char *       scan_version(      const char *s, SV *rv,
                                       bool qv)
 const char *  Perl_scan_version(pTHX_ const char *s, SV *rv,
                                       bool qv)

๐ŸŒธ upg_version ๐ŸŒธ

in-place upgrade of the supplied SV to a version object. glow-up, but for SVs โœจ

    SV *sv = upg_version(SV *sv, bool qv);

returns a pointer to the upgraded SV. set the boolean qv if you want to force this SV to be interpreted as an "extended" version.

 SV *       upg_version(      SV *ver, bool qv)
 SV *  Perl_upg_version(pTHX_ SV *ver, bool qv)

๐Ÿ“ vcmp ๐Ÿ“

version-object-aware cmp. both operands must already have been converted into version objects โ€” no feeding it random strings and hoping, bestie, it will not hold your hand ๐Ÿ’€

 int       vcmp(      SV *lhv, SV *rhv)
 int  Perl_vcmp(pTHX_ SV *lhv, SV *rhv)

๐Ÿงš vnormal ๐Ÿงš

accepts a version object and returns the normalized string representation. call like:

    sv = vnormal(rv);

NOTE: you can pass either the object directly or the SV contained within the RV. flexible queen ๐Ÿ’…

the SV returned has a refcount of 1.

 SV *       vnormal(      SV *vs)
 SV *  Perl_vnormal(pTHX_ SV *vs)

โญ vnumify โญ

accepts a version object and returns the normalized floating point representation. call like:

    sv = vnumify(rv);

NOTE: you can pass either the object directly or the SV contained within the RV.

the SV returned has a refcount of 1.

 SV *       vnumify(      SV *vs)
 SV *  Perl_vnumify(pTHX_ SV *vs)

๐ŸŽ€ vstringify ๐ŸŽ€

in order to maintain maximum compatibility with earlier versions of Perl, this function will return either the floating point notation or the multiple dotted notation, depending on whether the original version contained 1 or more dots, respectively. it's reading the room, honestly.

the SV returned has a refcount of 1.

 SV *       vstringify(      SV *vs)
 SV *  Perl_vstringify(pTHX_ SV *vs)

๐Ÿ”ฅ vverify ๐Ÿ”ฅ

validates that the SV contains valid internal structure for a version object. it may be passed either the version object (RV) or the hash itself (HV). if the structure is valid, it returns the HV. if the structure is invalid, it returns NULL.

    SV *hv = vverify(sv);

note that it only confirms the bare minimum structure (so as not to get confused by derived classes which may contain additional hash entries):

  • the SV is an HV or a reference to an HV
  • the hash contains a "version" key
  • the "version" key has a reference to an AV as its value
 SV *       vverify(      SV *vs)
 SV *  Perl_vverify(pTHX_ SV *vs)

๐Ÿ’€ Warning and Dieing ๐Ÿ’€

in all these calls, the "U32 wn" parameters are warning category constants. you can see the ones currently available in "Category Hierarchy" in warnings โ€” just capitalize all letters in the names and prefix them by "WARN_". so, for example, the category "void" used in a perl program becomes "WARN_VOID" when used in XS code and passed to one of the calls below. glow-up via uppercase, periodt โœจ

๐Ÿ˜ญ ck_warner, ck_warner_d ๐Ÿ˜ญ

if none of the warning categories given by "err" are enabled, do nothing; otherwise call "warner" or "warner_nocontext" with the passed-in parameters;.

"err" must be one of the "packWARN", "packWARN2", "packWARN3", "packWARN4" macros populated with the appropriate number of warning categories.

the two forms differ only in that "ck_warner_d" should be used if warnings for any of the categories are by default enabled.

 void       ck_warner  (      U32 err, const char *pat, ...)
 void  Perl_ck_warner  (pTHX_ U32 err, const char *pat, ...)
 void       ck_warner_d(      U32 err, const char *pat, ...)
 void  Perl_ck_warner_d(pTHX_ U32 err, const char *pat, ...)

๐Ÿ’… ckWARN, ckWARN2, ckWARN3, ckWARN4 ๐Ÿ’…

these return a boolean as to whether or not warnings are enabled for any of the warning category(ies) parameters: "w", "w1", ....

should any of the categories by default be enabled even if not within the scope of "use warnings", instead use the "ckWARN_d" macros.

the categories must be completely independent โ€” one may not be subclassed from the other. keep them separate, bestie, no messy entanglements ๐Ÿ™ˆ
 bool  ckWARN (U32 w)
 bool  ckWARN2(U32 w1, U32 w2)
 bool  ckWARN3(U32 w1, U32 w2, U32 w3)
 bool  ckWARN4(U32 w1, U32 w2, U32 w3, U32 w4)

โœจ ckWARN_d, ckWARN2_d, ckWARN3_d, ckWARN4_d โœจ

like "ckWARN", but for use if and only if the warning category(ies) is by default enabled even if not within the scope of "use warnings".

 bool  ckWARN_d (U32 w)
 bool  ckWARN2_d(U32 w1, U32 w2)
 bool  ckWARN3_d(U32 w1, U32 w2, U32 w3)
 bool  ckWARN4_d(U32 w1, U32 w2, U32 w3, U32 w4)

๐Ÿฆ‹ ckWARN2*, ckWARN3*, ckWARN4* ๐Ÿฆ‹

described under "ckWARN" โ€” that's it, that's the whole bit. go read that one, it's literally right there ๐Ÿ‘†

๐ŸŒธ CLEAR_ERRSV ๐ŸŒธ

clear the contents of $@, setting it to the empty string. liberation โœจ

this replaces any read-only SV with a fresh SV and removes any magic. new SV, who dis.

 void  CLEAR_ERRSV()

๐Ÿ’œ croak, croak_sv, vcroak, die, die_sv, croak_nocontext, die_nocontext ๐Ÿ’œ

these are XS interfaces to Perl's "die" function.

the arguments are used to generate a string message. if the message does not end with a newline, it will be extended with some indication of the current location in the code, as described for "mess_sv". it's giving "here's exactly where things went wrong, bestie, so you can't even pretend you don't know" ๐Ÿ˜ญ

These are all doing the same dramatic thing: they throw an exception, and they never come back. Ever. The error message becomes the exception, and control defaults to bailing out to the nearest enclosing eval โ€” but a $SIG{__DIE__} handler can absolutely step in and change the plot. Either way: none of these functions ever actually return normally. ๐Ÿซถ

In croak_sv and die_sv, baseex is the error message or object. If it's a reference, it gets used as-is (no touchy โœ‹). If it's anything else, it gets used as a string.

Wanna die with a simple string message? One of the other forms might be way more your speed โ€” those take a sprintf-style format pattern plus arguments to build the message for you.

The arguments to vcroak are specified as a va_list. The arguments to all the remaining forms are specified as a sprintf-style list of arguments.

And here's a lil historical tea ๐Ÿต for the non-_sv forms: if pat is null, then the contents of ERRSV ($@) get used as the error message or object instead of building one out of the arguments. Use the _sv forms instead if you want to throw a non-string object, or build an error message in an SV yourself โ€” those do not involve clobbering ERRSV. (No clobbering bestie, we don't do that here ๐Ÿ’…)

The difference between the croak forms and the die forms is only the return type. The croak ones return void; the die ones are listed as returning (confusingly ๐Ÿ˜ญ) an OP *, even though they never actually return. So only reach for the die forms when that return type is genuinely required. Periodt.

When called from outside the perl core, plain croak and die have always been the same as croak_nocontext and die_no_context, respectively. That's now true even when called from within core. ๐Ÿ‘‘

void       croak          (      const char *pat, ...)
void  Perl_croak          (pTHX_ const char *pat, ...)
void       croak_sv       (      SV *baseex)
void  Perl_croak_sv       (pTHX_ SV *baseex)
void       vcroak         (      const char *pat, va_list *args)
void  Perl_vcroak         (pTHX_ const char *pat, va_list *args)
OP *       die            (      const char *pat, ...)
OP *  Perl_die            (pTHX_ const char *pat, ...)
OP *       die_sv         (      SV *baseex)
OP *  Perl_die_sv         (pTHX_ SV *baseex)
void       croak_nocontext(      const char *pat, ...)
void  Perl_croak_nocontext(      const char *pat, ...)
OP *       die_nocontext  (      const char *pat, ...)
OP *  Perl_die_nocontext  (      const char *pat, ...)

๐Ÿ’€ croak_no_modify

This one wraps up a super common reason for dying, and it generates terser object code than using the generic Perl_croak. It's exactly equivalent to croak("%s", PL_no_modify) โ€” which expands to something like Modification of a read-only value attempted. โœจ

Less code used on exception code paths means less CPU cache pressure. Tiny win, huge vibes.

void       croak_no_modify()
void  Perl_croak_no_modify()

croak_nocontext*

croak_sv*

die*

die_nocontext*

die_sv*

All described under croak ๐Ÿ‘† (go read it, bestie).

๐ŸŒธ ERRSV

Returns the SV for $@, creating it if needed.

SV *  ERRSV

fatal_warner*

Described under warner ๐Ÿ‘‡ โ€” keep scrolling.

๐Ÿงš line_t

This is the typedef you use to declare variables that are meant to hold line numbers.

Use the LINE_Tf format to display these.

๐ŸŽ€ packWARN, packWARN2, packWARN3, packWARN4

These macros pack warning categories into a single U32 so you can pass them to macros and functions that take a warning category parameter. The number of categories to pack is literally in the name โ€” and you pass a matching number of category parameters.

U32  packWARN (U32 w1)
U32  packWARN2(U32 w1, U32 w2)
U32  packWARN3(U32 w1, U32 w2, U32 w3)
U32  packWARN4(U32 w1, U32 w2, U32 w3, U32 w4)

PL_dowarn

The C variable that roughly corresponds to Perl's $^W warning variable. But plot twist: $^W is treated as a boolean, whereas PL_dowarn is a whole collection of flag bits. ๐ŸŒˆ

On threaded perls, each thread gets an independent copy of this variable โ€” each one initialized at creation time with the current value of the creating thread's copy.

U8  PL_dowarn

๐Ÿšซ qerror

DEPRECATED! It is planned to remove qerror from a future release of Perl. Do not use it for new code; remove it from existing code.

It's a deprecated alias for defer_error.

void       qerror(      SV *err)
void  Perl_qerror(pTHX_ SV *err)

๐Ÿงผ SANE_ERRSV

Cleans up ERRSV so we can safely set it. It replaces any read-only SV with a fresh writable copy and removes any magic. โœจ

void  SANE_ERRSV()

sv_regex_global_pos_clear

Resets the value in the regexp global match position magic, if it exists, so that it does not take effect. (Clearing the drama, respectfully.)

void       sv_regex_global_pos_clear(      SV *sv)
void  Perl_sv_regex_global_pos_clear(pTHX_ SV *sv)

sv_regex_global_pos_get

If the given SV has regexp global match position magic, this sets the STRLEN pointed to by posp to the current value of the position and returns true. If not, returns false. Simple as that ๐Ÿ’…

If flags is zero, the return value counts in units of characters. If the SV_POSBYTES flag is present, it counts instead in units of bytes โ€” which can be different if the SV has the SvUTF8 flag set. ๐Ÿ‘€

bool       sv_regex_global_pos_get(      SV *sv, STRLEN *posp,
                                         U32 flags)
bool  Perl_sv_regex_global_pos_get(pTHX_ SV *sv, STRLEN *posp,
                                         U32 flags)

sv_regex_global_pos_set

Sets the value in the regexp global match position magic, first adding it if necessary. If pos is given as a negative value, it counts backwards from the end of the string. ๐Ÿ”™

If flags is zero, pos counts in units of characters. If the SV_POSBYTES flag is present, it counts instead in units of bytes โ€” which may be different if the SV has the SvUTF8 flag set. In that case, it is the caller's responsibility to make sure pos only lands on the boundary between characters, and not in the middle of a multi-byte character. โš ๏ธ

void       sv_regex_global_pos_set(      SV *sv, STRLEN pos,
                                         U32 flags)
void  Perl_sv_regex_global_pos_set(pTHX_ SV *sv, STRLEN pos,
                                         U32 flags)

๐Ÿฆ‹ sv_vstring_get

If the given SV has vstring magic, this stores the length of it into the variable addressed by lenp, and returns the string pointer. If not, it returns NULL.

If a pointer is handed back to the caller, it points to memory owned by the SV itself. The caller is not responsible for freeing it after this call โ€” but heads up, it will not stay valid for longer than the lifetime of the SV itself. So if you need to access it after that time, take a copy. ๐Ÿ“

const char *       sv_vstring_get(      SV * const sv,
                                        STRLEN *lenp)
const char *  Perl_sv_vstring_get(pTHX_ SV * const sv,
                                        STRLEN *lenp)

vcroak*

Described under croak ๐Ÿ‘†

vfatal_warner*

vwarner*

Described under warner ๐Ÿ‘‡

๐Ÿ“ฃ warn, warn_nocontext, warn_sv, vwarn

These are XS interfaces to Perl's warn function. (Yes, the one you know and love.)

The arguments are used to generate a string message. If the message doesn't end with a newline, it gets extended with some indication of the current location in the code, as described for mess_sv.

The message or object will by default be written to standard error โ€” but this is subject to modification by a $SIG{__WARN__} handler. ๐Ÿ’–

In warn_sv, baseex is the message or object. If it's a reference, it's used as-is. Otherwise it's used as a string.

warn and warn_nocontext behave identically when called from outside the perl core โ€” unless PERL_WANT_VARARGS has been explicitly #defined. When it has been, or when called from inside the core, they differ only in that warn requires the thread context (aTHX) to be available.

The arguments to vwarn are specified as a va_list. The arguments to the remaining forms are specified as a sprintf-style list of arguments.

Unlike with the croak functions, pat is not permitted to be null. ๐Ÿšซ

See also warner.

void       warn          (      const char *pat, ...)
void  Perl_warn          (pTHX_ const char *pat, ...)
void       warn_nocontext(      const char *pat, ...)
void  Perl_warn_nocontext(      const char *pat, ...)
void       warn_sv       (      SV *baseex)
void  Perl_warn_sv       (pTHX_ SV *baseex)
void       vwarn         (      const char *pat, va_list *args)
void  Perl_vwarn         (pTHX_ const char *pat, va_list *args)

๐Ÿ’œ warner, warner_nocontext, vwarner, fatal_warner, vfatal_warner

Each of these outputs a warning of the specified category (or categories) given by err, using the sprintf-style format pattern pat and the arguments.

err must be one of the packWARN, packWARN2, packWARN3, packWARN4 macros, populated with the appropriate number of warning categories. (You already met them up there โ˜๏ธ)

If any of the warning categories they specify is fatal, a fatal exception is thrown. ๐Ÿ’€

fatal_warner and vfatal_warner act as if fatal warnings are enabled for the warning. If called when there are pending compilation errors, these functions may actually return โ€” yes, plot twist, they can come back. They're currently used to generate "used only once" fatal warnings, since the COP where the name being reported is no longer the current COP when the warning is generated โ€” and they may be useful for similar cases.

In any event, a message is generated by the pattern and arguments. If the message does not end with a newline, it will be extended with some indication of the current location in the code, as described for mess_sv.

The error message or object will by default be written to standard error, but this is subject to modification by a $SIG{__WARN__} handler. โœจ

pat is not permitted to be null. ๐Ÿšซ

warner and warner_nocontext behave identically when called from outside the perl core unless PERL_WANT_VARARGS has been explicitly #defined. When it has, or when called from inside the core, they differ only in that warner requires the thread context (aTHX) to be available.

Okay so bestie, we're still in the warning zone โ€” let's finish this bit and then it's XS o'clock ๐Ÿ’…

The args for vwarner and vfatal_warner come in as a va_list. The rest of these bad boys want a plain old sprintf-style list of arguments. Periodt.

These functions are not the same as their similarly-named warn cousins, okay? Because those warn ones are for XS code that just wants to unconditionally throw a warning onto the screen, no questions asked. These ones are for code that might be in the middle of compiling a perl program, so they do extra checking to figure out whether that warning should actually be straight-up fatal. Big difference. โœจ

void       warner          (      U32 err, const char *pat, ...)
void  Perl_warner          (pTHX_ U32 err, const char *pat, ...)
void       warner_nocontext(      U32 err, const char *pat, ...)
void  Perl_warner_nocontext(      U32 err, const char *pat, ...)
void       vwarner         (      U32 err, const char *pat,
                                  va_list *args)
void  Perl_vwarner         (pTHX_ U32 err, const char *pat,
                                  va_list *args)
void       fatal_warner    (      U32 err, const char *pat, ...)
void  Perl_fatal_warner    (pTHX_ U32 err, const char *pat, ...)
void       vfatal_warner   (      U32 err, const char *pat,
                                  va_list *args)
void  Perl_vfatal_warner   (pTHX_ U32 err, const char *pat,
                                  va_list *args)

๐Ÿฆ‹ XS ๐Ÿฆ‹

xsubpp takes your XS code and compiles it into C. That's the whole vibe. Peep "xsubpp" in perlutil for the deets. ๐Ÿซถ

aMY_CXT, aMY_CXT_, _aMY_CXT

Described in perlxs. (Yeah bestie, go read perlxs, that's where the lore lives ๐Ÿ’œ)

ax

A variable that xsubpp sets up for you, and it tells you the stack base offset. It's the thing the ST, XSprePUSH and XSRETURN macros lean on. And heads up: you must call the dMARK macro before you set up the MARK variable. Don't skip that step. ๐Ÿšจ

Stack_off_t  ax

CLASS

A variable that xsubpp sets up to tell you the class name for a C++ XS constructor. It's always a char* type of situation. Go see THIS for the related tea. ๐Ÿ‘‘

char*  CLASS

dAX

Sets up the ax variable. Usually xsubpp just handles this for you automatically by calling dXSARGS, so you don't gotta think about it. Iconic behaviour fr fr.

dAX;

dAXMARK

Sets up the ax variable and the stack marker variable mark. Again, xsubpp normally handles this automatically via dXSARGS.

dAXMARK;

dITEMS

Sets up the items variable. Same deal โ€” usually xsubpp handles it for you automatically by calling dXSARGS.

dITEMS;

dMY_CXT, dMY_CXT_INIT_INTERP*

Described in perlxs. ๐Ÿ“š

dMY_CXT_SV

Now it's just a placeholder that declares literally nothing. A no-op queen. ๐Ÿ’€

dMY_CXT_SV;

dUNDERBAR

Sets up whatever variable the UNDERBAR macro needs. It used to define padoff_du, but as of right now it's a noop. However, it is strongly advised that you still use it anyway, for past-and-future compatibility reasons. Trust the process. ๐Ÿซถ

dUNDERBAR;

dXSARGS

Sets up the stack and mark pointers for an XSUB by calling dSP and dMARK. Then it sets up the ax and items variables by calling dAX and dITEMS. Usually xsubpp handles all of this automatically for you. โœจ

dXSARGS;

dXSI32

Sets up the ix variable for an XSUB that has aliases. Usually xsubpp handles this automatically.

dXSI32;

items

A variable that xsubpp sets up to tell you how many items</color> are chilling on the stack. See "Ellipsis: variable-length parameter lists" in perlxs.

Stack_off_t  items

ix

A variable that xsubpp sets up to indicate which of an XSUB's aliases was used to invoke it. See "The ALIAS: Keyword" in perlxs.

I32  ix

MY_CXT, MY_CXT_CLONE, MY_CXT_INIT, MY_CXT_INIT_INTERP, dMY_CXT_INIT_INTERP, MY_CXT_KEY, pMY_CXT, pMY_CXT_, _pMY_CXT

Described in perlxs. All of them. Every single one. Go look. ๐ŸŽ€

RETVAL

A variable that xsubpp sets up to hold the return value for an XSUB. It's always the proper type for the XSUB, no weird casting needed. See perlxs.

type  RETVAL

ST

Used to access elements on the XSUB's stack. That's it, that's the job bestie. ๐Ÿ’…

SV*  ST(int ix)

START_MY_CXT

Described in perlxs. ๐Ÿฆ‹

THIS

A variable that xsubpp sets up to designate the object in a C++ XSUB. It's always the proper type for the C++ object. See CLASS and "Using XS With C++" in perlxs.

type  THIS

UNDERBAR

The SV* that corresponds to the $_ variable. And the slay part? It works even if there's a lexical $_ in scope. โœจ

XS

Macro to declare an XSUB and its C parameter list. xsubpp handles this one. Note that it's the same as using the more explicit XS_EXTERNAL macro โ€” and honestly, the latter is preferred. Do with that what you will. ๐Ÿ’

XS(name)

XS_EXTERNAL

Macro to declare an XSUB and its C parameter list, explicitly exporting the symbols.

XS_EXTERNAL(name)

XS_INTERNAL

Macro to declare an XSUB and its C parameter list without exporting the symbols. xsubpp handles this, and it's generally preferable over exporting the XSUB symbols unnecessarily. Keep it lowkey. ๐Ÿคซ

XS_INTERNAL(name)

XSPROTO

Macro that XS_INTERNAL and XS_EXTERNAL use to declare a function prototype. You probably shouldn't be using this directly yourself, bestie. Hands off. ๐Ÿ™ˆ

XSPROTO(name)

๐Ÿ™ˆ Undocumented elements ๐Ÿ™ˆ

So listen. The following functions have been flagged as part of the public API, but they're currently undocumented. Use them at your own risk, because those interfaces are subject to change. And the functions that aren't listed in this document? They're not intended for public use, and should NOT be used under any circumstances. Not even once. Not even a little. ๐Ÿšซ

But if you genuinely feel like you need one of these functions, first send an email to perl5-porters@perl.org <mailto:perl5-porters@perl.org>. Maybe there's a good reason it's not documented and it should get yanked off this list. Or maybe nobody just got around to documenting it yet. In that case, you'll be asked to submit a patch documenting the function. And once your patch gets accepted, that means the interface is stable (unless it's explicitly marked otherwise) and usable by you. Glow up. ๐Ÿ’…

  • clone_params_del
  • clone_params_new
  • do_open
  • do_openn

Next up are the API-flagged elements that are considered experimental. Using one of these is even more risky than plain undocumented ones. They're listed here because they should be listed somewhere (so their existence doesn't get lost), and this is the best place for them.

  • apply_attrs_string
  • hv_store_flags
  • thread_locale_init
  • gv_fetchmethod_pv_flags
  • leave_adjust_stacks
  • thread_locale_term
  • gv_fetchmethod_pvn_flags
  • newXS_flags
  • gv_fetchmethod_sv_flags
  • savetmps

And finally, the deprecated undocumented API elements. Do not use any of these for new code. And honestly, go remove every single occurrence of all of them from your existing code. Clean sweep. ๐Ÿงน

There are currently no items of this type. (Winner winner. ๐ŸŽ‰)


๐ŸŽ€ AUTHORS ๐ŸŽ€

Until May 1997, this document was maintained by Jeff Okamoto <okamoto@corp.hp.com>. Now it's maintained as part of Perl itself. Household name energy. ๐Ÿ‘‘

With lots and lots of help and suggestions from Dean Roehrich, Malcolm Beattie, Andreas Koenig, Paul Hudson, Ilya Zakharevich, Paul Marquess, Neil Bowers, Matthew Green, Tim Bunce, Spider Boardman, Ulrich Pfeifer, Stephen McCamant, and Gurusamy Sarathy. A whole squad. ๐Ÿซถ

API Listing originally by Dean Roehrich <roehrich@cray.com>.

Updated to be autogenerated from comments in the source by Benjamin Stuhl. Autogenerated?? Obsessed. โœจ


๐ŸŒˆ SEE ALSO ๐ŸŒˆ

  • config.h
  • perlapio
  • perlcall
  • perlclib
  • perlembed
  • perlfilter
  • perlguts
  • perlhacktips
  • perlintern
  • perlinterp
  • perliol
  • perlmroapi
  • perlreapi
  • perlreguts
  • perlxs

and that's a wrap on the whole thing bestie!! ๐ŸŽ‰๐Ÿ’– this one shipped as perl v5.44.0, dated 2026-10-17, and it's the PERLAPI(1perl) page โ€” you read all of it, which is genuinely main character behaviour, no cap. now go write some XS and hydrate. ๐Ÿ’…๐Ÿฆ‹โœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: perl 5.44.0-1 ยท Artistic-1.0-Perl AND GPL-1.0-or-later
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms