Skip to content

Instantly share code, notes, and snippets.

@Mouq
Created June 5, 2015 10:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Mouq/815d79940dd964711e90 to your computer and use it in GitHub Desktop.
Save Mouq/815d79940dd964711e90 to your computer and use it in GitHub Desktop.
diff --git a/src/Perl6/Optimizer.nqp b/src/Perl6/Optimizer.nqp
index 31528a5..735d3b2 100644
--- a/src/Perl6/Optimizer.nqp
+++ b/src/Perl6/Optimizer.nqp
@@ -1371,6 +1371,8 @@ class Perl6::Optimizer {
|| ($op[1].op eq 'hllize'
&& nqp::istype($op[1][0], QAST::Op) && $op[1][0].op eq 'callmethod'))) {
my str $assignop;
+ my $target_var;
+ my $operand;
if $is_var {
my str $sigil := nqp::substr($op[1].name, 0, 1);
@@ -1383,29 +1385,52 @@ class Perl6::Optimizer {
# TODO check what else we need to "copy" from assign_op in Actions
return NQPMu;
}
+
+ # since the optimizer will only ever walk the first
+ # branch of a Want node, we have to make sure to change
+ # the node in place, since it's most likely shared with
+ # the other branch.
+ $op.op($assignop);
+ $target_var := $op[1];
+ $operand := $op[2];
+
+ $op.pop;
+ $op.pop;
+ $op.pop;
+
+ $op.push($target_var);
+ $op.push(QAST::Op.new( :op('call'), :name($metaop[0].name),
+ QAST::Op.new( :op('defor'), :name('&infix:<//>'),
+ $target_var,
+ QAST::Op.new( :op('call'), :name($metaop[0].name) ) ),
+ $operand));
} else {
$assignop := "assign";
+ $op.op($assignop);
+
+ # We want to be careful to only call $foo.bar once,
+ # so we bind to a local var and assign to that.
+ my $lhs_ast := $op[1];
+ my $target_name := QAST::Node.unique('METAOP_assign_');
+ my $bind_ast := QAST::Op.new( :op('bind'),
+ QAST::Var.new(:name($target_name), :scope('local'), :decl('var')),
+ $lhs_ast);
+ $target_var := QAST::Var.new(:name($target_name), :scope('local'));
+
+ $operand := $op[2];
+
+ $op.pop;
+ $op.pop;
+ $op.pop;
+
+ $op.push($bind_ast);
+ $op.push(QAST::Op.new( :op('call'), :name($metaop[0].name),
+ QAST::Op.new( :op('defor'), :name('&infix:<//>'),
+ $target_var,
+ QAST::Op.new( :op('call'), :name($metaop[0].name) ) ),
+ $operand));
}
- # since the optimizer will only ever walk the first
- # branch of a Want node, we have to make sure to change
- # the node in place, since it's most likely shared with
- # the other branch.
- $op.op($assignop);
- my $target_var := $op[1];
- my $operand := $op[2];
-
- $op.pop;
- $op.pop;
- $op.pop;
-
- $op.push($target_var);
- $op.push(QAST::Op.new( :op('call'), :name($metaop[0].name),
- QAST::Op.new( :op('defor'), :name('&infix:<//>'),
- $target_var,
- QAST::Op.new( :op('call'), :name($metaop[0].name) ) ),
- $operand));
-
if $assignop ne 'assign' && nqp::objprimspec($target_var.returns) {
$op.returns($target_var.returns);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment