New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
B::Deparse puts 'no overloading' in the wrong place #10578
Comments
From @nwc10Created by @nwc10B::Deparse is getting the positioning of no overloading wrong: $ ./perl -Ilib -MO=Deparse -e 'print; { no overloading; $a + $b}; print' In both cases, it should be inside the block. Nicholas Clark Perl Info
|
From @tonycozOn Thu, Aug 26, 2010 at 06:51:35AM -0700, Nicholas Clark wrote:
This is a problem for all BEGIN blocks - it cheats for strict, Tony |
The RT System itself - Status changed from 'new' to 'open' |
From @cpansproutOn Thu Aug 26 17:25:02 2010, tonyc wrote:
I’m trying to understand how this works. I would appreciate some hints. Every BEGIN block has a sequence number associated with it. That number The problem is that this code in perly.y: fullstmt: barestmt creates the nextstate op (the control op) *after* the block has been (See the B::Concise output for {{;}}: 9 <@> leave[1 ref] vKP/REFC ->(end) Notice how the first nextstate has a 3 after main; the second one has a 2.) That makes it impossible to distinguish between { and BEGIN {} So, what I’m wondering is: How does the nextstate op for the outer block Is it possible to store in the BEGIN block, not only the cop_seq, but Another idea has just popped into my head: Is there any way to emit a |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
An obvious possible solution is to emit a null statement, with nextstate $ perl5.10.1 -MO=Deparse -e 'print; { 1; no overloading; $a + $b}; print' However, there's a tension between deparse correctness and runtime
PL_compiling is a static COP-shaped buffer, where the current COP-relevant PL_curcop has a dual use. During compilation, it points at PL_compiling,
I'm dubious about building another nesting concept into the op tree,
The lexically-scoped items within the PL_compiling buffer are saved,
A sequence number could be allocated specially for this purpose, I -zefram |
From @cpansproutOn Mon May 23 04:13:41 2011, zefram@fysh.org wrote:
Thank you for your very clear explanations. Attached is an attempt at renumbering ops. It doesn’t quite work yet. I have another question. intro_my begins like this: U32 ASSERT_CURPAD_ACTIVE("intro_my"); That means that when PL_min_intro_pending is 0 the same sequence number |
From @cpansproutInline Patchdiff --git a/op.c b/op.c
index 0d4e1e6..5abb7c0 100644
--- a/op.c
+++ b/op.c
@@ -2387,11 +2387,16 @@ Perl_block_start(pTHX_ int full)
dVAR;
const int retval = PL_savestack_ix;
+ PL_compiling.cop_seq = PL_cop_seqmax++;
+ if (PL_cop_seqmax == PERL_PADSEQ_INTRO) /* not a legal value */
+ PL_cop_seqmax++;
pad_block_start(full);
SAVEHINTS();
PL_hints &= ~HINT_BLOCK_SCOPE;
SAVECOMPILEWARNINGS();
PL_compiling.cop_warnings = DUP_WARNINGS(PL_compiling.cop_warnings);
+ SAVEI32(PL_compiling.cop_seq);
+ PL_compiling.cop_seq = 0;
CALL_BLOCK_HOOKS(bhk_start, full);
@@ -4848,9 +4853,14 @@ OP *
Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
{
dVAR;
- const U32 seq = intro_my();
+ const U32 seq =
+ PL_compiling.cop_seq
+ ? (intro_my(), PL_compiling.cop_seq)
+ : intro_my();
register COP *cop;
+/*Perl_warn(aTHX_ "%d",seq);*/
+ PL_compiling.cop_seq = 0;
NewOp(1101, cop, 1, COP);
if (PERLDB_LINE && CopLINE(PL_curcop) && PL_curstash != PL_debstash) {
cop->op_type = OP_DBSTATE; |
From @cpansproutOn Sun May 29 15:56:58 2011, sprout wrote:
For future readers, I now know enough to answer my own question: Sequence numbers are primarily for lexical variables, to keep track of which variables are in scope for each statement. If multiple statements in a row contain no lexical declarations, then there is no need to increment the sequence number. For BEGIN blocks, however, the sequence number is incremented, even if no lexicals are declared around it, for the sake of B modules. The cost is infinitesimal. -- Father Chrysostomos |
From @cpansproutOn Sun May 29 15:56:58 2011, sprout wrote:
It was on the right track. It’s cleaner to have intro_my return the pending seq number itself, in case it starts being called from elsewhere. I applied something based on it as 8635e3c. -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'pending release' |
From @cpansproutOn Thu Nov 06 22:23:09 2014, sprout wrote:
And, in doing so, restored all those nice semicolons in perly.act. :-) -- Father Chrysostomos |
From @cpansproutOn Thu Nov 06 22:23:09 2014, sprout wrote:
I need to reopen this ticket, because we still have the problem of BEGIN blocks falling out of the enclosing block: $ ./perl -Ilib -MO=Deparse -e '{ ...; no overloading } ...' In fact, I think 8635e3c introduced that bug. So now we have a regression that needs to be fixed before 5.22. -- Father Chrysostomos |
@cpansprout - Status changed from 'pending release' to 'open' |
From @cpansproutOn Fri Nov 14 13:14:52 2014, sprout wrote:
I’ve just fixed it in 34b5495. I did so by adding an extra null cop to the end of a block if the last thing in the block is a subroutine definition or use/no statement. Another, failed, approach is attached here, in case future readers find it interesting. -- Father Chrysostomos |
From @cpansproutFrom 70c40eb Mon Sep 17 00:00:00 2001 This means that, in code like: my $x; The sequence numbers for the statements are reset when foo finishes This will allow the differences between sequence numbers to become It doesn’t matter that we end up with unrelated, non-sequential state- This should not affect B::Deparse either (which uses sequence numbers Nevertheless, localising the sequence number does mean that we have to ext/B/B/Concise.pm | 2 +- Inline Patchdiff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm
index 406327f..6cc3ce9 100644
--- a/ext/B/B/Concise.pm
+++ b/ext/B/B/Concise.pm
@@ -1039,7 +1039,7 @@ sub tree {
# to update the corresponding magic number in the next line.
# Remember, this needs to stay the last things in the module.
-my $cop_seq_mnum = 16;
+my $cop_seq_mnum = -411;
$cop_seq_base = svref_2object(eval 'sub{0;}')->START->cop_seq + $cop_seq_mnum;
1;
diff --git a/op.c b/op.c
index 00c1255..fd0e524 100644
--- a/op.c
+++ b/op.c
@@ -5888,7 +5888,6 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
PL_hints |= HINT_BLOCK_SCOPE;
PL_parser->copline = NOLINE;
- COP_SEQMAX_INC; /* Purely for B::*'s benefit */
}
/*
@@ -8166,6 +8165,7 @@ Perl_newMYSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
if (PL_parser)
PL_parser->copline = NOLINE;
LEAVE_SCOPE(floor);
+ COP_SEQMAX_INC; /* Purely for B::*'s benefit */
#ifdef PERL_DEBUG_READONLY_OPS
if (slab)
Slab_to_ro(slab);
@@ -8618,6 +8618,7 @@ Perl_newATTRSUB_x(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs,
if (PL_parser)
PL_parser->copline = NOLINE;
LEAVE_SCOPE(floor);
+ COP_SEQMAX_INC; /* Purely for B::*'s benefit */
#ifdef PERL_DEBUG_READONLY_OPS
/* Watch out for BEGIN blocks */
if (!special && slab)
diff --git a/toke.c b/toke.c
index b6da013..63ce10f 100644
--- a/toke.c
+++ b/toke.c
@@ -10542,6 +10542,7 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags)
SAVEI32(PL_subline);
save_item(PL_subname);
SAVESPTR(PL_compcv);
+ SAVEI32(PL_cop_seqmax);
PL_compcv = MUTABLE_CV(newSV_type(is_format ? SVt_PVFM : SVt_PVCV));
CvFLAGS(PL_compcv) |= flags;
--
From d96f97d Mon Sep 17 00:00:00 2001 This patch was trying to solve the problem of { foo(); BEGIN {} } deparsing When I realised how fragile this approach was, I stopped writing the lib/B/Deparse.pm | 15 ++++++++++++--- Inline Patchdiff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index 1e42ef1..537ca0d 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -1352,7 +1352,7 @@ sub lineseq {
my $body = join($sep, grep {length} @exprs);
my $subs = "";
if (defined $root && defined $limit_seq && !$self->{'in_format'}) {
- $subs = join "\n", $self->seq_subs($limit_seq);
+ $subs = join "\n", $self->seq_subs($limit_seq, 1);
}
return join($sep, grep {length} $body, $subs);
}
@@ -1640,14 +1640,22 @@ sub cop_subs {
}
sub seq_subs {
- my ($self, $seq) = @_;
+ my ($self, $seq, $is_block_end) = @_;
my @text;
#push @text, "# ($seq)\n";
return "" if !defined $seq;
my @pending;
+ my($prev_seq, $this_seq) = $seq;
while (scalar(@{$self->{'subs_todo'}})
- and $seq > $self->{'subs_todo'}[0][0]) {
+ and $seq > ($this_seq = $self->{'subs_todo'}[0][0])
+ # At the end of a block, we may have subs with sequence numbers
+ # exceeding the target sequence number ($seq), but in incre-
+ # ments of less that 10. (Theoretically only increments
+ # of 1, but we allow anything < 10 to be on the safe side.
+ # op.c:block_end ensures that the next statement has a sequence
+ # number at least 10 higher.)
+ || ($is_block_end and $this_seq - $prev_seq < 10)) {
my $cv = $self->{'subs_todo'}[0][1];
my $outside = $cv && $cv->OUTSIDE;
if ($cv and ${$cv->OUTSIDE || \0} != ${$self->{'curcv'}}) {
@@ -1655,6 +1663,7 @@ sub seq_subs {
next;
}
push @text, $self->next_todo;
+ $prev_seq = $this_seq;
}
unshift @{$self->{'subs_todo'}}, @pending;
return @text;
diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t
index 5b7d9cd..f160a14 100644
--- a/lib/B/Deparse.t
+++ b/lib/B/Deparse.t
@@ -13,7 +13,7 @@ BEGIN {
use warnings;
use strict;
-my $tests = 28; # not counting those in the __DATA__ section
+my $tests = 29; # not counting those in the __DATA__ section
use B::Deparse;
my $deparse = B::Deparse->new();
@@ -362,6 +362,31 @@ sub BEGIN {
}
EOCODJ
}
+is runperl(stderr => 1, switches => [ '-MO=-qq,Deparse', $path ], prog => '
+ {
+ {
+ die;
+ BEGIN { pop }
+ }
+ BEGIN { pop }
+ }
+ BEGIN { pop }
+ '), <<'EOCODL', 'BEGIN blocks at the end of their enclosing blocks';
+{
+ {
+ die;
+ sub BEGIN {
+ pop @ARGV;
+ }
+ }
+ sub BEGIN {
+ pop @ARGV;
+ }
+}
+sub BEGIN {
+ pop @ARGV;
+}
+EOCODL
# [perl #115066]
my $prog = 'use constant FOO => do { 1 }; no overloading; die';
diff --git a/pad.c b/pad.c
index c9e16e5..379828c 100644
--- a/pad.c
+++ b/pad.c
@@ -1629,6 +1629,7 @@ Perl_pad_leavemy(pTHX)
}
}
}
+ PL_cop_seqmax += 8;
COP_SEQMAX_INC;
DEBUG_Xv(PerlIO_printf(Perl_debug_log,
"Pad leavemy: seq = %ld\n", (long)PL_cop_seqmax));
--
1.7.12.4 (Apple Git-37) |
@cpansprout - Status changed from 'open' to 'pending release' |
From @khwilliamsonThanks for submitting this ticket The issue should be resolved with the release today of Perl v5.22. If you find that the problem persists, feel free to reopen this ticket -- |
@khwilliamson - Status changed from 'pending release' to 'resolved' |
Migrated from rt.perl.org#77452 (status was 'resolved')
Searchable as RT77452$
The text was updated successfully, but these errors were encountered: