org.jruby.ir.operands.CompoundArray Maven / Gradle / Ivy
package org.jruby.ir.operands;
import org.jruby.RubyArray;
import org.jruby.ir.IRVisitor;
import org.jruby.ir.transformations.inlining.InlinerInfo;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import java.util.List;
import java.util.Map;
// This represents an array that is used solely during arguments construction
// * Array + Splat ([1,2,3], *[5,6,7])
// This is a side-effect free operation, hence an operand
//
// NOTE: This operand is only used in the initial stages of optimization.
// Further down the line, this might get built into an actual array object.
public class CompoundArray extends Operand {
final private Operand a1;
final private Operand a2;
private boolean isArgsPush;
public CompoundArray(Operand a1, Operand a2) {
this(a1, a2, false);
}
public CompoundArray(Operand a1, Operand a2, boolean isArgsPush) {
this.a1 = a1;
this.a2 = a2;
this.isArgsPush = isArgsPush;
}
public boolean hasKnownValue() { return false; /*return a1.isConstant() && a2.isConstant();*/ }
public String toString() { return (isArgsPush ? "ArgsPush:[" : "ArgsCat:[") + a1 + ", " + a2 + "]"; }
public Operand getAppendingArg() { return a1; }
public Operand getAppendedArg() { return a2; }
public boolean isArgsPush() { return isArgsPush; }
public Operand getSimplifiedOperand(Map valueMap, boolean force) {
Operand newA1 = a1.getSimplifiedOperand(valueMap, force);
Operand newA2 = a2.getSimplifiedOperand(valueMap, force);
/*
* SSS FIXME: Cannot convert this to an Array operand!
*
// For simplification, get the target value, even if compound
Operand p1 = a1;
if (p1 instanceof Variable)
p1 = ((Variable)p1).getValue(valueMap);
// For simplification, get the target value, even if compound
Operand p2 = a2;
if (p2 instanceof Variable)
p2 = ((Variable)p2).getValue(valueMap);
if ((p1 instanceof Array) && (p2 instanceof Array)) {
// SSS FIXME: Move this code to some utils area .. or probably there is already a method for this in some jruby utils class
// Holy cow! Just to append two darned arrays!
Operand[] p1Elts = ((Array)p1).elts;
Operand[] p2Elts = ((Array)p2).elts;
Operand[] newElts = new Operand[p1Elts.length + p2Elts.length];
System.arraycopy(p1Elts, 0, newElts, 0, p1Elts.length);
System.arraycopy(p2Elts, 0, newElts, p1Elts.length, p2Elts.length);
return new Array(newElts);
}
else {
return this;
}
*/
return (a1 == newA1 && a2 == newA2) ? this : new CompoundArray(newA1, newA2, isArgsPush);
}
/** Append the list of variables used in this operand to the input list */
@Override
public void addUsedVariables(List l) {
a1.addUsedVariables(l);
a2.addUsedVariables(l);
}
@Override
public Operand cloneForInlining(InlinerInfo ii) {
return hasKnownValue() ? this : new CompoundArray(a1.cloneForInlining(ii), a2.cloneForInlining(ii), isArgsPush);
}
@Override
public Object retrieve(ThreadContext context, IRubyObject self, DynamicScope currDynScope, Object[] temp) {
IRubyObject v1 = (IRubyObject)a1.retrieve(context, self, currDynScope, temp);
IRubyObject v2 = (IRubyObject)a2.retrieve(context, self, currDynScope, temp);
return isArgsPush ? Helpers.argsPush((RubyArray) v1, v2) : Helpers.argsCat(v1, v2);
}
@Override
public void visit(IRVisitor visitor) {
visitor.CompoundArray(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy