org.jruby.ir.operands.TemporaryLocalVariable Maven / Gradle / Ivy
package org.jruby.ir.operands;
import org.jruby.ir.IRManager;
import org.jruby.ir.IRVisitor;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
/**
* A set of variables which are only used in a particular scope and never
* visible to Ruby itself.
*/
public class TemporaryLocalVariable extends TemporaryVariable {
public static final String PREFIX = "%v_";
public final int offset;
public TemporaryLocalVariable(int offset) {
super();
this.offset = offset;
}
public String getName() {
return getPrefix() + offset;
}
public int getOffset() {
return offset;
}
@Override
public TemporaryVariableType getType() {
return TemporaryVariableType.LOCAL;
}
public String getPrefix() {
return PREFIX;
}
@Override
public Variable clone(SimpleCloneInfo ii) {
return this;
}
@Override
public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) {
// SSS FIXME: When AddLocalVarLoadStoreInstructions pass is not enabled, we don't need this check.
// We only need these because Ruby code can have local vars used before being defined.
//
// a = 1 if always-false
// p a # should print nil since a is not defined on the else path
//
// Now, when locals are promoted to temps, this local-var behavior gets transferred to tmp-vars as well!
//
// If can canonicalize Ruby code to get rid of use-before-defs, we can get rid of the null checks
// both here and in DynamicScope var lookups. To be done later.
//
// I dont like this at all. This feels ugly!
Object o = temp[offset];
return o == null ? context.nil : o;
}
@Override
public void encode(IRWriterEncoder e) {
super.encode(e);
e.encode((byte) getType().ordinal());
e.encode(offset);
}
public static TemporaryLocalVariable decode(IRReaderDecoder d) {
TemporaryVariableType type = d.decodeTemporaryVariableType();
switch(type) {
case CLOSURE: return TemporaryClosureVariable.decode(d);
case CURRENT_MODULE: return TemporaryCurrentModuleVariable.decode(d);
case CURRENT_SCOPE: return TemporaryCurrentScopeVariable.decode(d);
case FLOAT: return TemporaryFloatVariable.decode(d);
case FIXNUM: return TemporaryFixnumVariable.decode(d);
case BOOLEAN: return TemporaryBooleanVariable.decode(d);
case LOCAL: return d.getCurrentScope().getManager().newTemporaryLocalVariable(d.decodeInt());
}
return null; // Should not reach here.
}
@Override
public void visit(IRVisitor visitor) {
visitor.TemporaryLocalVariable(this);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy