Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/about/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ priorities and future plans.

## Work in progress

- Avoid allocating discarded old-value scalars for postfix increment and
decrement in JVM-compiled void context.

- Restore `local` compatibility for tied hash and array elements, sparse
arrays, magic stashes, implicit `$_` foreach aliases (including early
return), and localized regex captures on both execution backends.
Expand Down
12 changes: 10 additions & 2 deletions src/main/java/org/perlonjava/backend/jvm/EmitOperatorNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.perlonjava.frontend.astnode.OperatorNode;
import org.perlonjava.runtime.perlmodule.Strict;
import org.perlonjava.runtime.runtimetypes.PerlCompilerException;
import org.perlonjava.runtime.runtimetypes.RuntimeContextType;

/**
* Handles the bytecode emission for Perl operator nodes during compilation.
Expand Down Expand Up @@ -121,8 +122,15 @@ public static void emitOperatorNode(EmitterVisitor emitterVisitor, OperatorNode
// Auto-increment/decrement operators
case "++" -> EmitOperator.handleUnaryDefaultCase(node, "preAutoIncrement", emitterVisitor);
case "--" -> EmitOperator.handleUnaryDefaultCase(node, "preAutoDecrement", emitterVisitor);
case "++postfix" -> EmitOperator.handleUnaryDefaultCase(node, "postAutoIncrement", emitterVisitor);
case "--postfix" -> EmitOperator.handleUnaryDefaultCase(node, "postAutoDecrement", emitterVisitor);
// In void context no caller can observe postfix's old-value result.
// Use the equivalent prefix mutator so ordinary discarded postfix
// operations do not allocate a temporary scalar just to POP it.
case "++postfix" -> EmitOperator.handleUnaryDefaultCase(node,
emitterVisitor.ctx.contextType == RuntimeContextType.VOID
? "preAutoIncrement" : "postAutoIncrement", emitterVisitor);
case "--postfix" -> EmitOperator.handleUnaryDefaultCase(node,
emitterVisitor.ctx.contextType == RuntimeContextType.VOID
? "preAutoDecrement" : "postAutoDecrement", emitterVisitor);

// Special case for length under "use bytes"
case "length" -> EmitOperator.handleLengthOperator(node, emitterVisitor);
Expand Down
47 changes: 47 additions & 0 deletions src/test/resources/unit/void_postfix_increment.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use strict;
use warnings;
use Test::More tests => 10;

my $integer = 4;
$integer++;
is($integer, 5, 'void postfix increment mutates an integer');

my $string = 'az';
$string++;
is($string, 'ba', 'void postfix increment retains string increment semantics');

my $undef;
$undef++;
is($undef, 1, 'void postfix increment coerces undef to one');

my $decrement = 4;
$decrement--;
is($decrement, 3, 'void postfix decrement mutates an integer');

{
package VoidPostfixTie;
sub TIESCALAR { bless { value => $_[1], fetches => 0, stores => 0 }, $_[0] }
sub FETCH { $_[0]{fetches}++; return $_[0]{value} }
sub STORE { $_[0]{stores}++; $_[0]{value} = $_[1] }
}

my $tied = tie my $tied_value, 'VoidPostfixTie', 7;
$tied_value++;
is($tied->{value}, 8, 'void postfix increment stores through a tied scalar');
is($tied->{fetches}, 1, 'void postfix increment fetches a tied scalar once');
is($tied->{stores}, 1, 'void postfix increment stores a tied scalar once');

{
package VoidPostfixOverload;
use overload '++' => sub { $_[0]{count}++; return $_[0] }, fallback => 1;
}

my $object = bless { count => 0 }, 'VoidPostfixOverload';
$object++;
is($object->{count}, 1, 'void postfix increment dispatches overload');

is(ref($object), 'VoidPostfixOverload', 'void postfix increment preserves overloaded object identity');

my $postfix_value = 9;
my $old = $postfix_value++;
is($old, 9, 'value context retains the original postfix result');
Loading