Skip to content

Commit

Permalink
Fixes #4342. zsuper does not cope with n repeated _ well.
Browse files Browse the repository at this point in the history
Basically all recv_* instrs will now check to see if they are assigning
to _ or not.  On first occurrence of _ we will actually assign to it like
an ordinary lvar.  On any additional parameter which uses the name we will
assign it to a temporary variable.  If that scope happens to have a zsuper
then those additional occurrences are not dead.  If not they fall out as
we optimize.
  • Loading branch information
enebo committed Nov 28, 2016
1 parent a6a0479 commit a416abe
Showing 1 changed file with 24 additions and 12 deletions.
36 changes: 24 additions & 12 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -280,6 +280,8 @@ public void cloneIntoHostScope(IRBuilder builder) {

private int _lastProcessedLineNum = -1;

public boolean underscoreVariableSeen = false;

public IRLoop getCurrentLoop() {
return loopStack.isEmpty() ? null : loopStack.peek();
}
Expand Down Expand Up @@ -1985,17 +1987,27 @@ private void addArgReceiveInstr(Variable v, int argIndex, boolean post, int numP
}
}

/* '_' can be seen as a variable only by its first assignment as a local variable. For any additional
* '_' we create temporary variables in the case the scope has a zsuper in it. If so, then the zsuper
* call will slurp those temps up as it's parameters so it can properly set up the call.
*/
private Variable argumentResult(String name) {
if (name.equals("_") && underscoreVariableSeen) {
return createTemporaryVariable();
} else {
underscoreVariableSeen = true;
return getNewLocalVariable(name, 0);
}
}

public void receiveRequiredArg(Node node, int argIndex, boolean post, int numPreReqd, int numPostRead) {
switch (node.getNodeType()) {
case ARGUMENTNODE: {
ArgumentNode a = (ArgumentNode)node;
String argName = a.getName();
String argName = ((ArgumentNode)node).getName();

if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.req, argName);
// Ignore duplicate "_" args in blocks
// (duplicate _ args are named "_$0")
if (!argName.equals("_$0")) {
addArgReceiveInstr(getNewLocalVariable(argName, 0), argIndex, post, numPreReqd, numPostRead);
}

addArgReceiveInstr(argumentResult(argName), argIndex, post, numPreReqd, numPostRead);
break;
}
case MULTIPLEASGNNODE: {
Expand Down Expand Up @@ -2054,7 +2066,7 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
Label variableAssigned = getNewLabel();
OptArgNode optArg = (OptArgNode)args[optIndex + j];
String argName = optArg.getName();
Variable argVar = getNewLocalVariable(argName, 0);
Variable argVar = argumentResult(argName);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.opt, argName);
// You need at least required+j+1 incoming args for this opt arg to get an arg at all
addInstr(new ReceiveOptArgInstr(argVar, signature.required(), signature.pre(), j));
Expand Down Expand Up @@ -2085,7 +2097,7 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
// You need at least required+opt+1 incoming args for the rest arg to get any args at all
// If it is going to get something, then it should ignore required+opt args from the beginning
// because they have been accounted for already.
addInstr(new ReceiveRestArgInstr(getNewLocalVariable(argName, 0), signature.required() + opt, argIndex));
addInstr(new ReceiveRestArgInstr(argumentResult(argName), signature.required() + opt, argIndex));
}

// Post(-opt and rest) required args
Expand All @@ -2106,9 +2118,9 @@ protected void receiveBlockArg(final ArgsNode argsNode) {
// reify to Proc if we have a block arg
BlockArgNode blockArg = argsNode.getBlock();
if (blockArg != null) {
String blockArgName = blockArg.getName();
Variable blockVar = getLocalVariable(blockArgName, 0);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.block, blockArgName);
String argName = blockArg.getName();
Variable blockVar = argumentResult(argName);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.block, argName);
Variable tmp = createTemporaryVariable();
addInstr(new LoadImplicitClosureInstr(tmp));
addInstr(new ReifyClosureInstr(blockVar, tmp));
Expand Down

0 comments on commit a416abe

Please sign in to comment.