package org.jruby.ir.instructions;

import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.InlineCloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

public class ReceiveOptArgInstr extends ReceiveArgBase implements FixedArityInstr {
    
opt args follow pre args
/** opt args follow pre args **/
public final int preArgs;
total number of required args (pre + post)
/** total number of required args (pre + post) **/
public final int requiredArgs; public ReceiveOptArgInstr(Variable result, int requiredArgs, int preArgs, int optArgIndex) { super(Operation.RECV_OPT_ARG, result, optArgIndex); this.preArgs = preArgs; this.requiredArgs = requiredArgs; } @Override public String[] toStringNonOperandArgs() { return new String[] {"index:" + getArgIndex(), "req: " + requiredArgs, "pre: " + preArgs}; } public int getPreArgs() { return preArgs; } public int getRequiredArgs() { return requiredArgs; } @Override public Instr clone(CloneInfo info) { int optArgIndex = this.argIndex; if (info instanceof SimpleCloneInfo) return new ReceiveOptArgInstr(info.getRenamedVariable(result), requiredArgs, preArgs, optArgIndex); InlineCloneInfo ii = (InlineCloneInfo) info; // SSS FIXME: Need to add kwArgLoss information in InlinerInfo // Added this copy for code clarity // argIndex is relative to start of opt args and not the start of arg array int minReqdArgs = optArgIndex + requiredArgs; if (ii.canMapArgsStatically()) { int n = ii.getArgsCount(); return new CopyInstr(ii.getRenamedVariable(result), minReqdArgs < n ? ii.getArg(preArgs + optArgIndex) : UndefinedValue.UNDEFINED); } return new OptArgMultipleAsgnInstr(ii.getRenamedVariable(result), ii.getArgs(), preArgs + optArgIndex, minReqdArgs); } @Override public void encode(IRWriterEncoder e) { super.encode(e); e.encode(requiredArgs); e.encode(getPreArgs()); e.encode(getArgIndex()); } public static ReceiveOptArgInstr decode(IRReaderDecoder d) { return new ReceiveOptArgInstr(d.decodeVariable(), d.decodeInt(), d.decodeInt(), d.decodeInt()); } @Override public IRubyObject receiveArg(ThreadContext context, IRubyObject[] args, boolean acceptsKeywordArgument) { return IRRuntimeHelpers.receiveOptArg(context, args, requiredArgs, preArgs, argIndex, acceptsKeywordArgument); } @Override public void visit(IRVisitor visitor) { visitor.ReceiveOptArgInstr(this); } }