package org.jruby.ir.operands;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRVisitor;
import org.jruby.ir.instructions.CopyInstr;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.*;
import org.jruby.runtime.builtin.IRubyObject;
import java.util.List;
import java.util.Map;
public class WrappedIRClosure extends Operand {
private final Variable self;
private final IRClosure closure;
public WrappedIRClosure(Variable self, IRClosure closure) {
super();
this.self = self;
this.closure = closure;
}
@Override
public OperandType getOperandType() {
return OperandType.WRAPPED_IR_CLOSURE;
}
@Override
public void addUsedVariables(List<Variable> l) {
l.add(self);
}
public Variable getSelf() {
return self;
}
public IRClosure getClosure() {
return closure;
}
@Override
public boolean canCopyPropagate() {
return true;
}
@Override
public String toString() {
return self + ":" + closure.toString();
}
@Override
public Operand getSimplifiedOperand(Map<Operand, Operand> valueMap, boolean force) {
Operand newSelf = self.getSimplifiedOperand(valueMap, force);
return newSelf == self ? this : new WrappedIRClosure((Variable)newSelf, closure);
}
@Override
public Operand cloneForInlining(CloneInfo info) {
if (info instanceof SimpleCloneInfo && !((SimpleCloneInfo) info).isEnsureBlockCloneMode()) {
return new WrappedIRClosure(info.getRenamedVariable(self), closure);
}
return new WrappedIRClosure(info.getRenamedVariable(self), closure.cloneForInlining(info));
}
@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
BlockBody body = closure.getBlockBody();
closure.getStaticScope().determineModule();
IRubyObject selfVal = (this.self instanceof Self) ? self : (IRubyObject)this.self.retrieve(context, self, currScope, currDynScope, temp);
Binding binding = context.currentBinding(selfVal, currDynScope);
return new Block(body, binding);
}
@Override
public void encode(IRWriterEncoder e) {
super.encode(e);
e.encode(self);
e.encode(closure);
}
public static WrappedIRClosure decode(IRReaderDecoder d) {
return new WrappedIRClosure(d.decodeVariable(), (IRClosure) d.decodeScope());
}
@Override
public void visit(IRVisitor visitor) {
visitor.WrappedIRClosure(this);
}
}