Skip to content

Commit

Permalink
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -2810,10 +2810,12 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode) {
Label l;
Variable readerValue = createTemporaryVariable();
Variable writerValue = createTemporaryVariable();
Node receiver = opAsgnNode.getReceiverNode();
CallType callType = receiver instanceof SelfNode ? CallType.FUNCTIONAL : CallType.NORMAL;

// get attr
Operand v1 = build(opAsgnNode.getReceiverNode());
addInstr(CallInstr.create(scope, readerValue, opAsgnNode.getVariableName(), v1, NO_ARGS, null));
Operand v1 = build(receiver);
addInstr(CallInstr.create(scope, callType, readerValue, opAsgnNode.getVariableName(), v1, NO_ARGS, null));

// Ex: e.val ||= n
// e.val &&= n
@@ -2824,7 +2826,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode) {

// compute value and set it
Operand v2 = build(opAsgnNode.getValueNode());
addInstr(CallInstr.create(scope, writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {v2}, null));
addInstr(CallInstr.create(scope, callType, writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {v2}, null));
// It is readerValue = v2.
// readerValue = writerValue is incorrect because the assignment method
// might return something else other than the value being set!
@@ -2841,7 +2843,7 @@ public Operand buildOpAsgn(OpAsgnNode opAsgnNode) {
addInstr(CallInstr.create(scope, setValue, opAsgnNode.getOperatorName(), readerValue, new Operand[]{v2}, null));

// set attr
addInstr(CallInstr.create(scope, writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {setValue}, null));
addInstr(CallInstr.create(scope, callType, writerValue, opAsgnNode.getVariableNameAsgn(), v1, new Operand[] {setValue}, null));
// Returning writerValue is incorrect becuase the assignment method
// might return something else other than the value being set!
return setValue;
@@ -2914,16 +2916,18 @@ public Operand buildOpElementAsgn(OpElementAsgnNode node) {
}

private Operand buildOpElementAsgnWith(OpElementAsgnNode opElementAsgnNode, Boolean truthy) {
Operand array = buildWithOrder(opElementAsgnNode.getReceiverNode(), opElementAsgnNode.containsVariableAssignment());
Node receiver = opElementAsgnNode.getReceiverNode();
CallType callType = receiver instanceof SelfNode ? CallType.FUNCTIONAL : CallType.NORMAL;
Operand array = buildWithOrder(receiver, opElementAsgnNode.containsVariableAssignment());
Label endLabel = getNewLabel();
Variable elt = createTemporaryVariable();
Operand[] argList = setupCallArgs(opElementAsgnNode.getArgsNode());
addInstr(CallInstr.create(scope, elt, "[]", array, argList, null));
addInstr(CallInstr.create(scope, callType, elt, "[]", array, argList, null));
addInstr(BEQInstr.create(elt, truthy, endLabel));
Operand value = build(opElementAsgnNode.getValueNode());

argList = addArg(argList, value);
addInstr(CallInstr.create(scope, elt, "[]=", array, argList, null));
addInstr(CallInstr.create(scope, callType, elt, "[]=", array, argList, null));
addInstr(new CopyInstr(elt, value));

addInstr(new LabelInstr(endLabel));
@@ -2932,18 +2936,20 @@ private Operand buildOpElementAsgnWith(OpElementAsgnNode opElementAsgnNode, Bool

// a[i] *= n, etc. anything that is not "a[i] &&= .. or a[i] ||= .."
public Operand buildOpElementAsgnWithMethod(OpElementAsgnNode opElementAsgnNode) {
Operand array = buildWithOrder(opElementAsgnNode.getReceiverNode(), opElementAsgnNode.containsVariableAssignment());
Node receiver = opElementAsgnNode.getReceiverNode();
CallType callType = receiver instanceof SelfNode ? CallType.FUNCTIONAL : CallType.NORMAL;
Operand array = buildWithOrder(receiver, opElementAsgnNode.containsVariableAssignment());
Operand[] argList = setupCallArgs(opElementAsgnNode.getArgsNode());
Variable elt = createTemporaryVariable();
addInstr(CallInstr.create(scope, elt, "[]", array, argList, null)); // elt = a[args]
addInstr(CallInstr.create(scope, callType, elt, "[]", array, argList, null)); // elt = a[args]
Operand value = build(opElementAsgnNode.getValueNode()); // Load 'value'
String operation = opElementAsgnNode.getOperatorName();
addInstr(CallInstr.create(scope, elt, operation, elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
addInstr(CallInstr.create(scope, callType, elt, operation, elt, new Operand[] { value }, null)); // elt = elt.OPERATION(value)
// SSS: do not load the call result into 'elt' to eliminate the RAW dependency on the call
// We already know what the result is going be .. we are just storing it back into the array
Variable tmp = createTemporaryVariable();
argList = addArg(argList, elt);
addInstr(CallInstr.create(scope, tmp, "[]=", array, argList, null)); // a[args] = elt
addInstr(CallInstr.create(scope, callType, tmp, "[]=", array, argList, null)); // a[args] = elt
return elt;
}

0 comments on commit 4ff4ad4

Please sign in to comment.