The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

/* In 5.18 and 5.20, intro_my is not exported.  We could just call
   Perl_intro_my, but Windows users might complain, so just copy the
   function here (and tweak it).  */
#ifndef intro_my
#define intro_my() S_intro_my(aTHX)

/* Fortunately these macros are the same in both versions (but different in
   5.22+; fortunately, 5.22 exposes intro_my).  */

#define COP_SEQ_RANGE_LOW_set(sv,val)		\
  STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xlow = (val); } STMT_END
#define COP_SEQ_RANGE_HIGH_set(sv,val)		\
  STMT_START { ((XPVNV*)SvANY(sv))->xnv_u.xpad_cop_seq.xhigh = (val); } STMT_END


static U32
S_intro_my(pTHX)
{
    dVAR;
    SV **svp;
    I32 i;
    U32 seq;

    if (! PL_min_intro_pending)
	return PL_cop_seqmax;

    svp = AvARRAY(PL_comppad_name);
    for (i = PL_min_intro_pending; i <= PL_max_intro_pending; i++) {
	SV * const sv = svp[i];

/* 5.18 uses sv != &PL_sv_undef; 5.20 uses PadnameLEN(sv), defining it
   differently from 5.18.  The main thing is that it is neither
   &PL_sv_undef nor &PL_sv_no.  Checking that the name has length to it is
   the canonical way of deing this, but a simple SvCUR() won’t work on
   &PL_sv_undef, which has no such field.  If it is not &PL_sv_undef, then
   it has a PV and a valid SvCUR field.  */
	if (sv && sv != &PL_sv_undef && SvCUR(sv) && !SvFAKE(sv)
	    && COP_SEQ_RANGE_LOW(sv) == PERL_PADSEQ_INTRO)
	{
	    COP_SEQ_RANGE_HIGH_set(sv, PERL_PADSEQ_INTRO); /* Don't know scope end yet. */
	    COP_SEQ_RANGE_LOW_set(sv, PL_cop_seqmax);
	}
    }
    seq = PL_cop_seqmax;
    PL_cop_seqmax++;
    if (PL_cop_seqmax == PERL_PADSEQ_INTRO) /* not a legal value */
	PL_cop_seqmax++;
    PL_min_intro_pending = 0;
    PL_comppad_name_fill = PL_max_intro_pending; /* Needn't search higher */

    return seq;
}

#endif

/* Copied from XS::APItest::lexical_import.  */

MODULE = constant::lexical	PACKAGE = constant::lexical

void
install_lexical_sub(SV *name, CV *cv)
    CODE:
    {
	PADLIST *pl;
	PADOFFSET off;
	if (!PL_compcv)
	    Perl_croak(aTHX_
		 "install_lexical_sub can only be called at compile time");
	pl = CvPADLIST(PL_compcv);
	ENTER;
	SAVESPTR(PL_comppad_name); PL_comppad_name = PadlistNAMES(pl);
	SAVESPTR(PL_comppad);	   PL_comppad	   = PadlistARRAY(pl)[1];
	SAVESPTR(PL_curpad);	   PL_curpad	   = PadARRAY(PL_comppad);
	off = pad_add_name_sv(sv_2mortal(newSVpvf("&%"SVf,name)),
			      padadd_STATE, 0, 0);
	SvREFCNT_dec(PL_curpad[off]);
	PL_curpad[off] = SvREFCNT_inc(cv);
	intro_my();
	LEAVE;
    }