forked from schacon/perl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
op.c
10159 lines (9002 loc) · 260 KB
/
op.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#line 2 "op.c"
/* op.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
* 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
/*
* 'You see: Mr. Drogo, he married poor Miss Primula Brandybuck. She was
* our Mr. Bilbo's first cousin on the mother's side (her mother being the
* youngest of the Old Took's daughters); and Mr. Drogo was his second
* cousin. So Mr. Frodo is his first *and* second cousin, once removed
* either way, as the saying is, if you follow me.' --the Gaffer
*
* [p.23 of _The Lord of the Rings_, I/i: "A Long-Expected Party"]
*/
/* This file contains the functions that create, manipulate and optimize
* the OP structures that hold a compiled perl program.
*
* A Perl program is compiled into a tree of OPs. Each op contains
* structural pointers (eg to its siblings and the next op in the
* execution sequence), a pointer to the function that would execute the
* op, plus any data specific to that op. For example, an OP_CONST op
* points to the pp_const() function and to an SV containing the constant
* value. When pp_const() is executed, its job is to push that SV onto the
* stack.
*
* OPs are mainly created by the newFOO() functions, which are mainly
* called from the parser (in perly.y) as the code is parsed. For example
* the Perl code $a + $b * $c would cause the equivalent of the following
* to be called (oversimplifying a bit):
*
* newBINOP(OP_ADD, flags,
* newSVREF($a),
* newBINOP(OP_MULTIPLY, flags, newSVREF($b), newSVREF($c))
* )
*
* Note that during the build of miniperl, a temporary copy of this file
* is made, called opmini.c.
*/
/*
Perl's compiler is essentially a 3-pass compiler with interleaved phases:
A bottom-up pass
A top-down pass
An execution-order pass
The bottom-up pass is represented by all the "newOP" routines and
the ck_ routines. The bottom-upness is actually driven by yacc.
So at the point that a ck_ routine fires, we have no idea what the
context is, either upward in the syntax tree, or either forward or
backward in the execution order. (The bottom-up parser builds that
part of the execution order it knows about, but if you follow the "next"
links around, you'll find it's actually a closed loop through the
top level node.)
Whenever the bottom-up parser gets to a node that supplies context to
its components, it invokes that portion of the top-down pass that applies
to that part of the subtree (and marks the top node as processed, so
if a node further up supplies context, it doesn't have to take the
plunge again). As a particular subcase of this, as the new node is
built, it takes all the closed execution loops of its subcomponents
and links them into a new closed loop for the higher level node. But
it's still not the real execution order.
The actual execution order is not known till we get a grammar reduction
to a top-level unit like a subroutine or file that will be called by
"name" rather than via a "next" pointer. At that point, we can call
into peep() to do that code's portion of the 3rd pass. It has to be
recursive, but it's recursive on basic blocks, not on tree nodes.
*/
/* To implement user lexical pragmas, there needs to be a way at run time to
get the compile time state of %^H for that block. Storing %^H in every
block (or even COP) would be very expensive, so a different approach is
taken. The (running) state of %^H is serialised into a tree of HE-like
structs. Stores into %^H are chained onto the current leaf as a struct
refcounted_he * with the key and the value. Deletes from %^H are saved
with a value of PL_sv_placeholder. The state of %^H at any point can be
turned back into a regular HV by walking back up the tree from that point's
leaf, ignoring any key you've already seen (placeholder or not), storing
the rest into the HV structure, then removing the placeholders. Hence
memory is only used to store the %^H deltas from the enclosing COP, rather
than the entire %^H on each COP.
To cause actions on %^H to write out the serialisation records, it has
magic type 'H'. This magic (itself) does nothing, but its presence causes
the values to gain magic type 'h', which has entries for set and clear.
C<Perl_magic_sethint> updates C<PL_compiling.cop_hints_hash> with a store
record, with deletes written by C<Perl_magic_clearhint>. C<SAVEHINTS>
saves the current C<PL_compiling.cop_hints_hash> on the save stack, so that
it will be correctly restored when any inner compiling scope is exited.
*/
#include "EXTERN.h"
#define PERL_IN_OP_C
#include "perl.h"
#include "keywords.h"
#define CALL_PEEP(o) PL_peepp(aTHX_ o)
#define CALL_RPEEP(o) PL_rpeepp(aTHX_ o)
#define CALL_OPFREEHOOK(o) if (PL_opfreehook) PL_opfreehook(aTHX_ o)
#if defined(PL_OP_SLAB_ALLOC)
#ifdef PERL_DEBUG_READONLY_OPS
# define PERL_SLAB_SIZE 4096
# include <sys/mman.h>
#endif
#ifndef PERL_SLAB_SIZE
#define PERL_SLAB_SIZE 2048
#endif
void *
Perl_Slab_Alloc(pTHX_ size_t sz)
{
dVAR;
/*
* To make incrementing use count easy PL_OpSlab is an I32 *
* To make inserting the link to slab PL_OpPtr is I32 **
* So compute size in units of sizeof(I32 *) as that is how Pl_OpPtr increments
* Add an overhead for pointer to slab and round up as a number of pointers
*/
sz = (sz + 2*sizeof(I32 *) -1)/sizeof(I32 *);
if ((PL_OpSpace -= sz) < 0) {
#ifdef PERL_DEBUG_READONLY_OPS
/* We need to allocate chunk by chunk so that we can control the VM
mapping */
PL_OpPtr = (I32**) mmap(0, PERL_SLAB_SIZE*sizeof(I32*), PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, -1, 0);
DEBUG_m(PerlIO_printf(Perl_debug_log, "mapped %lu at %p\n",
(unsigned long) PERL_SLAB_SIZE*sizeof(I32*),
PL_OpPtr));
if(PL_OpPtr == MAP_FAILED) {
perror("mmap failed");
abort();
}
#else
PL_OpPtr = (I32 **) PerlMemShared_calloc(PERL_SLAB_SIZE,sizeof(I32*));
#endif
if (!PL_OpPtr) {
return NULL;
}
/* We reserve the 0'th I32 sized chunk as a use count */
PL_OpSlab = (I32 *) PL_OpPtr;
/* Reduce size by the use count word, and by the size we need.
* Latter is to mimic the '-=' in the if() above
*/
PL_OpSpace = PERL_SLAB_SIZE - (sizeof(I32)+sizeof(I32 **)-1)/sizeof(I32 **) - sz;
/* Allocation pointer starts at the top.
Theory: because we build leaves before trunk allocating at end
means that at run time access is cache friendly upward
*/
PL_OpPtr += PERL_SLAB_SIZE;
#ifdef PERL_DEBUG_READONLY_OPS
/* We remember this slab. */
/* This implementation isn't efficient, but it is simple. */
PL_slabs = (I32**) realloc(PL_slabs, sizeof(I32**) * (PL_slab_count + 1));
PL_slabs[PL_slab_count++] = PL_OpSlab;
DEBUG_m(PerlIO_printf(Perl_debug_log, "Allocate %p\n", PL_OpSlab));
#endif
}
assert( PL_OpSpace >= 0 );
/* Move the allocation pointer down */
PL_OpPtr -= sz;
assert( PL_OpPtr > (I32 **) PL_OpSlab );
*PL_OpPtr = PL_OpSlab; /* Note which slab it belongs to */
(*PL_OpSlab)++; /* Increment use count of slab */
assert( PL_OpPtr+sz <= ((I32 **) PL_OpSlab + PERL_SLAB_SIZE) );
assert( *PL_OpSlab > 0 );
return (void *)(PL_OpPtr + 1);
}
#ifdef PERL_DEBUG_READONLY_OPS
void
Perl_pending_Slabs_to_ro(pTHX) {
/* Turn all the allocated op slabs read only. */
U32 count = PL_slab_count;
I32 **const slabs = PL_slabs;
/* Reset the array of pending OP slabs, as we're about to turn this lot
read only. Also, do it ahead of the loop in case the warn triggers,
and a warn handler has an eval */
PL_slabs = NULL;
PL_slab_count = 0;
/* Force a new slab for any further allocation. */
PL_OpSpace = 0;
while (count--) {
void *const start = slabs[count];
const size_t size = PERL_SLAB_SIZE* sizeof(I32*);
if(mprotect(start, size, PROT_READ)) {
Perl_warn(aTHX_ "mprotect for %p %lu failed with %d",
start, (unsigned long) size, errno);
}
}
free(slabs);
}
STATIC void
S_Slab_to_rw(pTHX_ void *op)
{
I32 * const * const ptr = (I32 **) op;
I32 * const slab = ptr[-1];
PERL_ARGS_ASSERT_SLAB_TO_RW;
assert( ptr-1 > (I32 **) slab );
assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
assert( *slab > 0 );
if(mprotect(slab, PERL_SLAB_SIZE*sizeof(I32*), PROT_READ|PROT_WRITE)) {
Perl_warn(aTHX_ "mprotect RW for %p %lu failed with %d",
slab, (unsigned long) PERL_SLAB_SIZE*sizeof(I32*), errno);
}
}
OP *
Perl_op_refcnt_inc(pTHX_ OP *o)
{
if(o) {
Slab_to_rw(o);
++o->op_targ;
}
return o;
}
PADOFFSET
Perl_op_refcnt_dec(pTHX_ OP *o)
{
PERL_ARGS_ASSERT_OP_REFCNT_DEC;
Slab_to_rw(o);
return --o->op_targ;
}
#else
# define Slab_to_rw(op)
#endif
void
Perl_Slab_Free(pTHX_ void *op)
{
I32 * const * const ptr = (I32 **) op;
I32 * const slab = ptr[-1];
PERL_ARGS_ASSERT_SLAB_FREE;
assert( ptr-1 > (I32 **) slab );
assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
assert( *slab > 0 );
Slab_to_rw(op);
if (--(*slab) == 0) {
# ifdef NETWARE
# define PerlMemShared PerlMem
# endif
#ifdef PERL_DEBUG_READONLY_OPS
U32 count = PL_slab_count;
/* Need to remove this slab from our list of slabs */
if (count) {
while (count--) {
if (PL_slabs[count] == slab) {
dVAR;
/* Found it. Move the entry at the end to overwrite it. */
DEBUG_m(PerlIO_printf(Perl_debug_log,
"Deallocate %p by moving %p from %lu to %lu\n",
PL_OpSlab,
PL_slabs[PL_slab_count - 1],
PL_slab_count, count));
PL_slabs[count] = PL_slabs[--PL_slab_count];
/* Could realloc smaller at this point, but probably not
worth it. */
if(munmap(slab, PERL_SLAB_SIZE*sizeof(I32*))) {
perror("munmap failed");
abort();
}
break;
}
}
}
#else
PerlMemShared_free(slab);
#endif
if (slab == PL_OpSlab) {
PL_OpSpace = 0;
}
}
}
#endif
/*
* In the following definition, the ", (OP*)0" is just to make the compiler
* think the expression is of the right type: croak actually does a Siglongjmp.
*/
#define CHECKOP(type,o) \
((PL_op_mask && PL_op_mask[type]) \
? ( op_free((OP*)o), \
Perl_croak(aTHX_ "'%s' trapped by operation mask", PL_op_desc[type]), \
(OP*)0 ) \
: PL_check[type](aTHX_ (OP*)o))
#define RETURN_UNLIMITED_NUMBER (PERL_INT_MAX / 2)
#define CHANGE_TYPE(o,type) \
STMT_START { \
o->op_type = (OPCODE)type; \
o->op_ppaddr = PL_ppaddr[type]; \
} STMT_END
STATIC const char*
S_gv_ename(pTHX_ GV *gv)
{
SV* const tmpsv = sv_newmortal();
PERL_ARGS_ASSERT_GV_ENAME;
gv_efullname3(tmpsv, gv, NULL);
return SvPV_nolen_const(tmpsv);
}
STATIC OP *
S_no_fh_allowed(pTHX_ OP *o)
{
PERL_ARGS_ASSERT_NO_FH_ALLOWED;
yyerror(Perl_form(aTHX_ "Missing comma after first argument to %s function",
OP_DESC(o)));
return o;
}
STATIC OP *
S_too_few_arguments(pTHX_ OP *o, const char *name)
{
PERL_ARGS_ASSERT_TOO_FEW_ARGUMENTS;
yyerror(Perl_form(aTHX_ "Not enough arguments for %s", name));
return o;
}
STATIC OP *
S_too_many_arguments(pTHX_ OP *o, const char *name)
{
PERL_ARGS_ASSERT_TOO_MANY_ARGUMENTS;
yyerror(Perl_form(aTHX_ "Too many arguments for %s", name));
return o;
}
STATIC void
S_bad_type(pTHX_ I32 n, const char *t, const char *name, const OP *kid)
{
PERL_ARGS_ASSERT_BAD_TYPE;
yyerror(Perl_form(aTHX_ "Type of arg %d to %s must be %s (not %s)",
(int)n, name, t, OP_DESC(kid)));
}
STATIC void
S_no_bareword_allowed(pTHX_ const OP *o)
{
PERL_ARGS_ASSERT_NO_BAREWORD_ALLOWED;
if (PL_madskills)
return; /* various ok barewords are hidden in extra OP_NULL */
qerror(Perl_mess(aTHX_
"Bareword \"%"SVf"\" not allowed while \"strict subs\" in use",
SVfARG(cSVOPo_sv)));
}
/* "register" allocation */
PADOFFSET
Perl_allocmy(pTHX_ const char *const name, const STRLEN len, const U32 flags)
{
dVAR;
PADOFFSET off;
const bool is_our = (PL_parser->in_my == KEY_our);
PERL_ARGS_ASSERT_ALLOCMY;
if (flags)
Perl_croak(aTHX_ "panic: allocmy illegal flag bits 0x%" UVxf,
(UV)flags);
/* Until we're using the length for real, cross check that we're being
told the truth. */
assert(strlen(name) == len);
/* complain about "my $<special_var>" etc etc */
if (len &&
!(is_our ||
isALPHA(name[1]) ||
(USE_UTF8_IN_NAMES && UTF8_IS_START(name[1])) ||
(name[1] == '_' && (*name == '$' || len > 2))))
{
/* name[2] is true if strlen(name) > 2 */
if (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1])) {
yyerror(Perl_form(aTHX_ "Can't use global %c^%c%.*s in \"%s\"",
name[0], toCTRL(name[1]), (int)(len - 2), name + 2,
PL_parser->in_my == KEY_state ? "state" : "my"));
} else {
yyerror(Perl_form(aTHX_ "Can't use global %.*s in \"%s\"", (int) len, name,
PL_parser->in_my == KEY_state ? "state" : "my"));
}
}
/* allocate a spare slot and store the name in that slot */
off = pad_add_name(name, len,
is_our ? padadd_OUR :
PL_parser->in_my == KEY_state ? padadd_STATE : 0,
PL_parser->in_my_stash,
(is_our
/* $_ is always in main::, even with our */
? (PL_curstash && !strEQ(name,"$_") ? PL_curstash : PL_defstash)
: NULL
)
);
/* anon sub prototypes contains state vars should always be cloned,
* otherwise the state var would be shared between anon subs */
if (PL_parser->in_my == KEY_state && CvANON(PL_compcv))
CvCLONE_on(PL_compcv);
return off;
}
/* free the body of an op without examining its contents.
* Always use this rather than FreeOp directly */
static void
S_op_destroy(pTHX_ OP *o)
{
if (o->op_latefree) {
o->op_latefreed = 1;
return;
}
FreeOp(o);
}
#ifdef USE_ITHREADS
# define forget_pmop(a,b) S_forget_pmop(aTHX_ a,b)
#else
# define forget_pmop(a,b) S_forget_pmop(aTHX_ a)
#endif
/* Destructor */
void
Perl_op_free(pTHX_ OP *o)
{
dVAR;
OPCODE type;
if (!o)
return;
if (o->op_latefreed) {
if (o->op_latefree)
return;
goto do_free;
}
type = o->op_type;
if (o->op_private & OPpREFCOUNTED) {
switch (type) {
case OP_LEAVESUB:
case OP_LEAVESUBLV:
case OP_LEAVEEVAL:
case OP_LEAVE:
case OP_SCOPE:
case OP_LEAVEWRITE:
{
PADOFFSET refcnt;
OP_REFCNT_LOCK;
refcnt = OpREFCNT_dec(o);
OP_REFCNT_UNLOCK;
if (refcnt) {
/* Need to find and remove any pattern match ops from the list
we maintain for reset(). */
find_and_forget_pmops(o);
return;
}
}
break;
default:
break;
}
}
/* Call the op_free hook if it has been set. Do it now so that it's called
* at the right time for refcounted ops, but still before all of the kids
* are freed. */
CALL_OPFREEHOOK(o);
if (o->op_flags & OPf_KIDS) {
register OP *kid, *nextkid;
for (kid = cUNOPo->op_first; kid; kid = nextkid) {
nextkid = kid->op_sibling; /* Get before next freeing kid */
op_free(kid);
}
}
#ifdef PERL_DEBUG_READONLY_OPS
Slab_to_rw(o);
#endif
/* COP* is not cleared by op_clear() so that we may track line
* numbers etc even after null() */
if (type == OP_NEXTSTATE || type == OP_DBSTATE
|| (type == OP_NULL /* the COP might have been null'ed */
&& ((OPCODE)o->op_targ == OP_NEXTSTATE
|| (OPCODE)o->op_targ == OP_DBSTATE))) {
cop_free((COP*)o);
}
if (type == OP_NULL)
type = (OPCODE)o->op_targ;
op_clear(o);
if (o->op_latefree) {
o->op_latefreed = 1;
return;
}
do_free:
FreeOp(o);
#ifdef DEBUG_LEAKING_SCALARS
if (PL_op == o)
PL_op = NULL;
#endif
}
void
Perl_op_clear(pTHX_ OP *o)
{
dVAR;
PERL_ARGS_ASSERT_OP_CLEAR;
#ifdef PERL_MAD
/* if (o->op_madprop && o->op_madprop->mad_next)
abort(); */
/* FIXME for MAD - if I uncomment these two lines t/op/pack.t fails with
"modification of a read only value" for a reason I can't fathom why.
It's the "" stringification of $_, where $_ was set to '' in a foreach
loop, but it defies simplification into a small test case.
However, commenting them out has caused ext/List/Util/t/weak.t to fail
the last test. */
/*
mad_free(o->op_madprop);
o->op_madprop = 0;
*/
#endif
retry:
switch (o->op_type) {
case OP_NULL: /* Was holding old type, if any. */
if (PL_madskills && o->op_targ != OP_NULL) {
o->op_type = (Optype)o->op_targ;
o->op_targ = 0;
goto retry;
}
case OP_ENTERTRY:
case OP_ENTEREVAL: /* Was holding hints. */
o->op_targ = 0;
break;
default:
if (!(o->op_flags & OPf_REF)
|| (PL_check[o->op_type] != Perl_ck_ftst))
break;
/* FALL THROUGH */
case OP_GVSV:
case OP_GV:
case OP_AELEMFAST:
if (! (o->op_type == OP_AELEMFAST && o->op_flags & OPf_SPECIAL)) {
/* not an OP_PADAV replacement */
GV *gv = (o->op_type == OP_GV || o->op_type == OP_GVSV)
#ifdef USE_ITHREADS
&& PL_curpad
#endif
? cGVOPo_gv : NULL;
/* It's possible during global destruction that the GV is freed
before the optree. Whilst the SvREFCNT_inc is happy to bump from
0 to 1 on a freed SV, the corresponding SvREFCNT_dec from 1 to 0
will trigger an assertion failure, because the entry to sv_clear
checks that the scalar is not already freed. A check of for
!SvIS_FREED(gv) turns out to be invalid, because during global
destruction the reference count can be forced down to zero
(with SVf_BREAK set). In which case raising to 1 and then
dropping to 0 triggers cleanup before it should happen. I
*think* that this might actually be a general, systematic,
weakness of the whole idea of SVf_BREAK, in that code *is*
allowed to raise and lower references during global destruction,
so any *valid* code that happens to do this during global
destruction might well trigger premature cleanup. */
bool still_valid = gv && SvREFCNT(gv);
if (still_valid)
SvREFCNT_inc_simple_void(gv);
#ifdef USE_ITHREADS
if (cPADOPo->op_padix > 0) {
/* No GvIN_PAD_off(cGVOPo_gv) here, because other references
* may still exist on the pad */
pad_swipe(cPADOPo->op_padix, TRUE);
cPADOPo->op_padix = 0;
}
#else
SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = NULL;
#endif
if (still_valid) {
int try_downgrade = SvREFCNT(gv) == 2;
SvREFCNT_dec(gv);
if (try_downgrade)
gv_try_downgrade(gv);
}
}
break;
case OP_METHOD_NAMED:
case OP_CONST:
case OP_HINTSEVAL:
SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = NULL;
#ifdef USE_ITHREADS
/** Bug #15654
Even if op_clear does a pad_free for the target of the op,
pad_free doesn't actually remove the sv that exists in the pad;
instead it lives on. This results in that it could be reused as
a target later on when the pad was reallocated.
**/
if(o->op_targ) {
pad_swipe(o->op_targ,1);
o->op_targ = 0;
}
#endif
break;
case OP_GOTO:
case OP_NEXT:
case OP_LAST:
case OP_REDO:
if (o->op_flags & (OPf_SPECIAL|OPf_STACKED|OPf_KIDS))
break;
/* FALL THROUGH */
case OP_TRANS:
case OP_TRANSR:
if (o->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) {
#ifdef USE_ITHREADS
if (cPADOPo->op_padix > 0) {
pad_swipe(cPADOPo->op_padix, TRUE);
cPADOPo->op_padix = 0;
}
#else
SvREFCNT_dec(cSVOPo->op_sv);
cSVOPo->op_sv = NULL;
#endif
}
else {
PerlMemShared_free(cPVOPo->op_pv);
cPVOPo->op_pv = NULL;
}
break;
case OP_SUBST:
op_free(cPMOPo->op_pmreplrootu.op_pmreplroot);
goto clear_pmop;
case OP_PUSHRE:
#ifdef USE_ITHREADS
if (cPMOPo->op_pmreplrootu.op_pmtargetoff) {
/* No GvIN_PAD_off here, because other references may still
* exist on the pad */
pad_swipe(cPMOPo->op_pmreplrootu.op_pmtargetoff, TRUE);
}
#else
SvREFCNT_dec(MUTABLE_SV(cPMOPo->op_pmreplrootu.op_pmtargetgv));
#endif
/* FALL THROUGH */
case OP_MATCH:
case OP_QR:
clear_pmop:
forget_pmop(cPMOPo, 1);
cPMOPo->op_pmreplrootu.op_pmreplroot = NULL;
/* we use the same protection as the "SAFE" version of the PM_ macros
* here since sv_clean_all might release some PMOPs
* after PL_regex_padav has been cleared
* and the clearing of PL_regex_padav needs to
* happen before sv_clean_all
*/
#ifdef USE_ITHREADS
if(PL_regex_pad) { /* We could be in destruction */
const IV offset = (cPMOPo)->op_pmoffset;
ReREFCNT_dec(PM_GETRE(cPMOPo));
PL_regex_pad[offset] = &PL_sv_undef;
sv_catpvn_nomg(PL_regex_pad[0], (const char *)&offset,
sizeof(offset));
}
#else
ReREFCNT_dec(PM_GETRE(cPMOPo));
PM_SETRE(cPMOPo, NULL);
#endif
break;
}
if (o->op_targ > 0) {
pad_free(o->op_targ);
o->op_targ = 0;
}
}
STATIC void
S_cop_free(pTHX_ COP* cop)
{
PERL_ARGS_ASSERT_COP_FREE;
CopFILE_free(cop);
CopSTASH_free(cop);
if (! specialWARN(cop->cop_warnings))
PerlMemShared_free(cop->cop_warnings);
cophh_free(CopHINTHASH_get(cop));
}
STATIC void
S_forget_pmop(pTHX_ PMOP *const o
#ifdef USE_ITHREADS
, U32 flags
#endif
)
{
HV * const pmstash = PmopSTASH(o);
PERL_ARGS_ASSERT_FORGET_PMOP;
if (pmstash && !SvIS_FREED(pmstash)) {
MAGIC * const mg = mg_find((const 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 (PL_curpm == o)
PL_curpm = NULL;
#ifdef USE_ITHREADS
if (flags)
PmopSTASH_free(o);
#endif
}
STATIC void
S_find_and_forget_pmops(pTHX_ OP *o)
{
PERL_ARGS_ASSERT_FIND_AND_FORGET_PMOPS;
if (o->op_flags & OPf_KIDS) {
OP *kid = cUNOPo->op_first;
while (kid) {
switch (kid->op_type) {
case OP_SUBST:
case OP_PUSHRE:
case OP_MATCH:
case OP_QR:
forget_pmop((PMOP*)kid, 0);
}
find_and_forget_pmops(kid);
kid = kid->op_sibling;
}
}
}
void
Perl_op_null(pTHX_ OP *o)
{
dVAR;
PERL_ARGS_ASSERT_OP_NULL;
if (o->op_type == OP_NULL)
return;
if (!PL_madskills)
op_clear(o);
o->op_targ = o->op_type;
o->op_type = OP_NULL;
o->op_ppaddr = PL_ppaddr[OP_NULL];
}
void
Perl_op_refcnt_lock(pTHX)
{
dVAR;
PERL_UNUSED_CONTEXT;
OP_REFCNT_LOCK;
}
void
Perl_op_refcnt_unlock(pTHX)
{
dVAR;
PERL_UNUSED_CONTEXT;
OP_REFCNT_UNLOCK;
}
/* Contextualizers */
/*
=for apidoc Am|OP *|op_contextualize|OP *o|I32 context
Applies a syntactic context to an op tree representing an expression.
I<o> is the op tree, and I<context> must be C<G_SCALAR>, C<G_ARRAY>,
or C<G_VOID> to specify the context to apply. The modified op tree
is returned.
=cut
*/
OP *
Perl_op_contextualize(pTHX_ OP *o, I32 context)
{
PERL_ARGS_ASSERT_OP_CONTEXTUALIZE;
switch (context) {
case G_SCALAR: return scalar(o);
case G_ARRAY: return list(o);
case G_VOID: return scalarvoid(o);
default:
Perl_croak(aTHX_ "panic: op_contextualize bad context");
return o;
}
}
/*
=head1 Optree Manipulation Functions
=for apidoc Am|OP*|op_linklist|OP *o
This function is the implementation of the L</LINKLIST> macro. It should
not be called directly.
=cut
*/
OP *
Perl_op_linklist(pTHX_ OP *o)
{
OP *first;
PERL_ARGS_ASSERT_OP_LINKLIST;
if (o->op_next)
return o->op_next;
/* establish postfix order */
first = cUNOPo->op_first;
if (first) {
register OP *kid;
o->op_next = LINKLIST(first);
kid = first;
for (;;) {
if (kid->op_sibling) {
kid->op_next = LINKLIST(kid->op_sibling);
kid = kid->op_sibling;
} else {
kid->op_next = o;
break;
}
}
}
else
o->op_next = o;
return o->op_next;
}
static OP *
S_scalarkids(pTHX_ OP *o)
{
if (o && o->op_flags & OPf_KIDS) {
OP *kid;
for (kid = cLISTOPo->op_first; kid; kid = kid->op_sibling)
scalar(kid);
}
return o;
}
STATIC OP *
S_scalarboolean(pTHX_ OP *o)
{
dVAR;
PERL_ARGS_ASSERT_SCALARBOOLEAN;
if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST
&& !(cBINOPo->op_first->op_flags & OPf_SPECIAL)) {
if (ckWARN(WARN_SYNTAX)) {
const line_t oldline = CopLINE(PL_curcop);
if (PL_parser && PL_parser->copline != NOLINE)
CopLINE_set(PL_curcop, PL_parser->copline);
Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Found = in conditional, should be ==");
CopLINE_set(PL_curcop, oldline);
}
}
return scalar(o);
}
OP *
Perl_scalar(pTHX_ OP *o)
{
dVAR;
OP *kid;
/* assumes no premature commitment */
if (!o || (PL_parser && PL_parser->error_count)
|| (o->op_flags & OPf_WANT)
|| o->op_type == OP_RETURN)
{
return o;
}
o->op_flags = (o->op_flags & ~OPf_WANT) | OPf_WANT_SCALAR;
switch (o->op_type) {
case OP_REPEAT:
scalar(cBINOPo->op_first);
break;
case OP_OR:
case OP_AND:
case OP_COND_EXPR:
for (kid = cUNOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
scalar(kid);
break;
/* FALL THROUGH */
case OP_SPLIT:
case OP_MATCH:
case OP_QR:
case OP_SUBST:
case OP_NULL:
default:
if (o->op_flags & OPf_KIDS) {
for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling)
scalar(kid);
}
break;
case OP_LEAVE:
case OP_LEAVETRY:
kid = cLISTOPo->op_first;
scalar(kid);
kid = kid->op_sibling;
do_kids:
while (kid) {
OP *sib = kid->op_sibling;
if (sib && kid->op_type != OP_LEAVEWHEN) {
if (sib->op_type == OP_BREAK && sib->op_flags & OPf_SPECIAL) {
scalar(kid);
scalarvoid(sib);
break;
} else
scalarvoid(kid);
} else
scalar(kid);
kid = sib;
}
PL_curcop = &PL_compiling;
break;
case OP_SCOPE:
case OP_LINESEQ:
case OP_LIST:
kid = cLISTOPo->op_first;
goto do_kids;
case OP_SORT:
Perl_ck_warner(aTHX_ packWARN(WARN_VOID), "Useless use of sort in scalar context");
break;
}
return o;
}
OP *
Perl_scalarvoid(pTHX_ OP *o)
{