Skip to content
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

The return value of an an empty block, when evaluated, produces an error #158

Closed
p6rt opened this issue Jul 6, 2008 · 7 comments
Closed
Labels

Comments

@p6rt
Copy link

p6rt commented Jul 6, 2008

Migrated from rt.perl.org#56640 (status was 'resolved')

Searchable as RT56640$

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

From @masak

A "Null PMC access" is produced when evaluating the return value from
an empty block. The attached patch fixes the problem.

$ cat undef.pl
sub f { undef }
say f
$ ./perl6 undef.pl

$ cat nothing.pl
sub f { }
say f
$ ./perl6 nothing.pl
Null PMC access in get_string()
current instr.​: 'print' pc 11069 (src/gen_builtins.pir​:7223)
called from Sub 'say' pc 11091 (src/gen_builtins.pir​:7233)
called from Sub '_block11' pc 28 (EVAL_13​:11)
called from Sub 'parrot;PCT​::HLLCompiler;eval' pc 806
(src/PCT/HLLCompiler.pir​:481)
called from Sub 'parrot;PCT​::HLLCompiler;evalfiles' pc 1088
(src/PCT/HLLCompiler.pir​:610)
called from Sub 'parrot;PCT​::HLLCompiler;command_line' pc 1267
(src/PCT/HLLCompiler.pir​:699)
called from Sub 'parrot;Perl6​::Compiler;main' pc 13257 (perl6.pir​:172)
perl6(73490) malloc​: *** error for object 0x28909d0​: double free
*** set a breakpoint in malloc_error_break to debug
Segmentation fault

$ patch -p0 < empty-block.patch ; make perl6
[...]

$ ./perl6 nothing.pl

$

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

From @masak

empty-block.patch
Index: src/parser/actions.pm
===================================================================
--- src/parser/actions.pm	(revision 29090)
+++ src/parser/actions.pm	(working copy)
@@ -73,6 +73,18 @@
     for $<statement> {
         $past.push( $($_) );
     }
+    my $num_statements := +@($<statement>);
+    if $num_statements == 1 {
+        $past.push( PAST::Op.new(
+            :pasttype('callmethod'),
+            :name('new'),
+            :node($/),
+            PAST::Var.new(
+                :name('Failure'),
+                :scope('package')
+            )
+        ));
+    }
     make $past;
 }

@p6rt
Copy link
Author

p6rt commented Jul 6, 2008

@pmichaud - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jul 7, 2008

From @moritz

Carl MXXsak (via RT) wrote​:

# New Ticket Created by "Carl Mäsak"
# Please include the string​: [perl #​56640]
# in the subject line of all future correspondence about this issue.
# <URL​: http://rt.perl.org/rt3/Ticket/Display.html?id=56640 >

A "Null PMC access" is produced when evaluating the return value from
an empty block. The attached patch fixes the problem.

$ cat undef.pl
sub f { undef }
say f
$ ./perl6 undef.pl

$ cat nothing.pl
sub f { }
say f
$ ./perl6 nothing.pl
Null PMC access in get_string()
current instr.​: 'print' pc 11069 (src/gen_builtins.pir​:7223)
called from Sub 'say' pc 11091 (src/gen_builtins.pir​:7233)
called from Sub '_block11' pc 28 (EVAL_13​:11)
called from Sub 'parrot;PCT​::HLLCompiler;eval' pc 806
(src/PCT/HLLCompiler.pir​:481)
called from Sub 'parrot;PCT​::HLLCompiler;evalfiles' pc 1088
(src/PCT/HLLCompiler.pir​:610)
called from Sub 'parrot;PCT​::HLLCompiler;command_line' pc 1267
(src/PCT/HLLCompiler.pir​:699)
called from Sub 'parrot;Perl6​::Compiler;main' pc 13257 (perl6.pir​:172)
perl6(73490) malloc​: *** error for object 0x28909d0​: double free
*** set a breakpoint in malloc_error_break to debug
Segmentation fault

$ patch -p0 < empty-block.patch ; make perl6
[...]

$ ./perl6 nothing.pl

$

Thank you for your patch, but it produces a lot of test failures
spectest_regression.

So the patch needs more work, but I don't feel competent enough for that
right now.

Cheers,
Moritz

--
Moritz Lenz
http://moritz.faui2k3.org/ | http://perl-6.de/

@p6rt
Copy link
Author

p6rt commented Jul 7, 2008

From @bacek

This patch is slightly better, but it still causes problem with code
like 'role C3 {}'.

diff --git a/languages/perl6/src/parser/actions.pm
b/languages/perl6/src/parser/
index e518c70..5d83002 100644
--- a/languages/perl6/src/parser/actions.pm
+++ b/languages/perl6/src/parser/actions.pm
@​@​ -58,6 +58,18 @​@​ method statement_block($/, $key) {
  my $past := @​?BLOCK.shift();
  $?BLOCK := @​?BLOCK[0];
  $past.push($($<statementlist>));
+ my $num_statements := +@​($($<statementlist>));
+ if $num_statements == 0 {
+ $past.push( PAST​::Op.new(
+ :pasttype('callmethod'),
+ :name('new'),
+ :node($/),
+ PAST​::Var.new(
+ :name('Failure'),
+ :scope('package')
+ )
+ ));
+ }
  make $past;
  }
}

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

From @pmichaud

Now fixed in r29135.

The patches contributed in the ticket put the logic at "too low a level"
in the actions -- not every block (parsed by <statement_block>) is a
routine that requires a return value -- some "blocks" are actually hash
composers.

The r29135 patch adds a return value as part of <routine_declarator>,
which makes a bit more sense. There may be other places where we need
to provide an undef return, but this works for now.

Also, we should probably start avoiding the C<< new "Failure" >> meme
for generating Failure objects -- this patch makes a call to the global
'undef' function. Note that we'll also be adding a couple of "fail"
function definitions for other routines to use as well.

Thanks for the bug report and patches!

Pm

@p6rt
Copy link
Author

p6rt commented Jul 8, 2008

@pmichaud - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Jul 8, 2008
@p6rt p6rt added the Bug label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant