diff options
author | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2022-12-07 13:01:28 +0000 |
---|---|---|
committer | Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> | 2023-02-10 12:07:02 +0000 |
commit | b40895ae558e0aff0c347785dafeaaff40a01801 (patch) | |
tree | 24173cae7e77cd69d260a1f39a7d6ccddb3cfc4f /pad.c | |
parent | 5d4d8b9fa5103e3bd911bb1ab9e94eb6d8e0ff28 (diff) | |
download | perl-b40895ae558e0aff0c347785dafeaaff40a01801.tar.gz |
Define the concept of a suspended compcv
Diffstat (limited to 'pad.c')
-rw-r--r-- | pad.c | 85 |
1 files changed, 85 insertions, 0 deletions
@@ -2845,5 +2845,90 @@ Perl_padname_dup(pTHX_ PADNAME *src, CLONE_PARAMS *param) #endif /* USE_ITHREADS */ /* +=for apidoc_section $lexer +=for apidoc suspend_compcv + +Implements part of the concept of a "suspended complication CV", which can be +used to pause the parser and compiler during parsing a CV in order to come +back to it later on. + +This function saves the current state of the subroutine under compilation +(C<PL_compcv>) into the supplied buffer. This should be used initially to +create the state in the buffer, as the final thing before a C<LEAVE> within a +block. + + ENTER; + start_subparse(0); + ... + + suspend_compcv(&buffer); + LEAVE; + +Once suspended, the C<resume_compcv> or C<resume_compcv_and_save> function can +later be used to continue the parsing from the point this stopped. + +=cut +*/ + +void +Perl_suspend_compcv(pTHX_ struct suspended_compcv *buffer) +{ + PERL_ARGS_ASSERT_SUSPEND_COMPCV; + + buffer->compcv = PL_compcv; + + buffer->padix = PL_padix; + buffer->constpadix = PL_constpadix; + + buffer->comppad_name_fill = PL_comppad_name_fill; + buffer->min_intro_pending = PL_min_intro_pending; + buffer->max_intro_pending = PL_max_intro_pending; + + buffer->cv_has_eval = PL_cv_has_eval; + buffer->pad_reset_pending = PL_pad_reset_pending; +} + +/* +=for apidoc resume_compcv_final + +Resumes the parser state previously saved using the C<suspend_compcv> function +for a final time before being compiled into a full CV. This should be used +within an C<ENTER>/C<LEAVE> scoped pair. + +=for apidoc resume_compcv_and_save + +Resumes a buffer previously suspended by the C<suspend_compcv> function, 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 C<ENTER>/C<LEAVE> scoped pair. + +=cut +*/ + +void +Perl_resume_compcv(pTHX_ struct suspended_compcv *buffer, bool save) +{ + PERL_ARGS_ASSERT_RESUME_COMPCV; + + SAVESPTR(PL_compcv); + PL_compcv = buffer->compcv; + PAD_SET_CUR(CvPADLIST(PL_compcv), 1); + + SAVESPTR(PL_comppad_name); + PL_comppad_name = PadlistNAMES(CvPADLIST(PL_compcv)); + + SAVESTRLEN(PL_padix); PL_padix = buffer->padix; + SAVESTRLEN(PL_constpadix); PL_constpadix = buffer->constpadix; + SAVESTRLEN(PL_comppad_name_fill); PL_comppad_name_fill = buffer->comppad_name_fill; + SAVESTRLEN(PL_min_intro_pending); PL_min_intro_pending = buffer->min_intro_pending; + SAVESTRLEN(PL_max_intro_pending); PL_max_intro_pending = buffer->max_intro_pending; + + SAVEBOOL(PL_cv_has_eval); PL_cv_has_eval = buffer->cv_has_eval; + SAVEBOOL(PL_pad_reset_pending); PL_pad_reset_pending = buffer->pad_reset_pending; + + if(save) + SAVEDESTRUCTOR_X(&Perl_suspend_compcv, buffer); +} + +/* * ex: set ts=8 sts=4 sw=4 et: */ |