#define ck_unpack Perl_ck_unpack
#define is_handle_constructor S_is_handle_constructor
#define is_list_assignment S_is_list_assignment
+#define forget_pmop S_forget_pmop
#define cop_free S_cop_free
#define modkids S_modkids
#define scalarboolean S_scalarboolean
#define ck_unpack(a) Perl_ck_unpack(aTHX_ a)
#define is_handle_constructor S_is_handle_constructor
#define is_list_assignment(a) S_is_list_assignment(aTHX_ a)
+#define forget_pmop(a,b) S_forget_pmop(aTHX_ a,b)
#define cop_free(a) S_cop_free(aTHX_ a)
#define modkids(a,b) S_modkids(aTHX_ a,b)
#define scalarboolean(a) S_scalarboolean(aTHX_ a)
case OP_MATCH:
case OP_QR:
clear_pmop:
- {
- HV * const pmstash = PmopSTASH(cPMOPo);
- if (pmstash && !SvIS_FREED(pmstash)) {
- MAGIC * const mg = mg_find((SV*)pmstash, PERL_MAGIC_symtab);
- if (mg) {
- PMOP *pmop = (PMOP*) mg->mg_obj;
- PMOP *lastpmop = NULL;
- while (pmop) {
- if (cPMOPo == pmop) {
- if (lastpmop)
- lastpmop->op_pmnext = pmop->op_pmnext;
- else
- mg->mg_obj = (SV*) pmop->op_pmnext;
- break;
- }
- lastpmop = pmop;
- pmop = pmop->op_pmnext;
- }
- }
- }
- PmopSTASH_free(cPMOPo);
- }
+ forget_pmop(cPMOPo, 1);
cPMOPo->op_pmreplroot = NULL;
/* we use the "SAFE" version of the PM_ macros here
* since sv_clean_all might release some PMOPs
Perl_refcounted_he_free(aTHX_ cop->cop_hints_hash);
}
+STATIC void
+S_forget_pmop(pTHX_ PMOP *const o, U32 flags)
+{
+ HV * const pmstash = PmopSTASH(o);
+ if (pmstash && !SvIS_FREED(pmstash)) {
+ MAGIC * const mg = mg_find((SV*)pmstash, PERL_MAGIC_symtab);
+ if (mg) {
+ PMOP **const array = (PMOP**) mg->mg_ptr;
+ U32 count = mg->mg_len / sizeof(PMOP**);
+ U32 i = count;
+
+ while (i--) {
+ if (array[i] == o) {
+ /* Found it. Move the entry at the end to overwrite it. */
+ array[i] = array[--count];
+ mg->mg_len = count * sizeof(PMOP**);
+ /* Could realloc smaller at this point always, but probably
+ not worth it. Probably worth free()ing if we're the
+ last. */
+ if(!count) {
+ Safefree(mg->mg_ptr);
+ mg->mg_ptr = NULL;
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (flags)
+ PmopSTASH_free(o);
+}
+
void
Perl_op_null(pTHX_ OP *o)
{
}
#endif
- /* link into pm list */
+ /* append to pm list */
if (type != OP_TRANS && PL_curstash) {
MAGIC *mg = mg_find((SV*)PL_curstash, PERL_MAGIC_symtab);
-
+ U32 elements;
if (!mg) {
mg = sv_magicext((SV*)PL_curstash, 0, PERL_MAGIC_symtab, 0, 0, 0);
}
- pmop->op_pmnext = (PMOP*)mg->mg_obj;
- mg->mg_obj = (SV*)pmop;
+ elements = mg->mg_len / sizeof(PMOP**);
+ Renewc(mg->mg_ptr, elements + 1, PMOP*, char);
+ ((PMOP**)mg->mg_ptr) [elements++] = pmop;
+ mg->mg_len = elements * sizeof(PMOP**);
PmopSTASH_set(pmop,PL_curstash);
}
if (!*s) { /* reset ?? searches */
MAGIC * const mg = mg_find((SV *)stash, PERL_MAGIC_symtab);
if (mg) {
- PMOP *pm = (PMOP *) mg->mg_obj;
- while (pm) {
+ const U32 count = mg->mg_len / sizeof(PMOP**);
+ PMOP **pmp = (PMOP**) mg->mg_ptr;
+ PMOP *const *const end = pmp + count;
+
+ while (pmp < end) {
#ifdef USE_ITHREADS
- SvREADONLY_off(PL_regex_pad[pm->op_pmoffset]);
+ SvREADONLY_off(PL_regex_pad[(*pmp)->op_pmoffset]);
#else
- pm->op_pmflags &= ~PMf_USED;
+ (*pmp)->op_pmflags &= ~PMf_USED;
#endif
- pm = pm->op_pmnext;
+ ++pmp;
}
}
return;
1. */
nmg->mg_obj = SvREFCNT_inc(av_dup_inc((AV*) mg->mg_obj, param));
}
- else if (mg->mg_type == PERL_MAGIC_symtab) {
- nmg->mg_obj = mg->mg_obj;
- }
else {
nmg->mg_obj = (mg->mg_flags & MGf_REFCOUNTED)
? sv_dup_inc(mg->mg_obj, param)