package org.jruby.ir.instructions;

import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.persistence.IRReaderDecoder;
import org.jruby.ir.persistence.IRWriterEncoder;
import org.jruby.ir.transformations.inlining.CloneInfo;

This instruction toggles a single per thread field which specifies whether an exception being thrown needs to generate backtrace info. At any point after toggling this to be false (no backtrace) you may encounter a nested exception which does require a backtrace. This nested exception will toggle back to needing an exception. In theory, we could restore this field as we unwind frames but largely this optimization only occurs in very simple scenarios. Also important to note this is only requesting for a backtrace or not. If you request no backtrace but the error is not a StandardError exception it will still be required to generate a backtrace.
/** * This instruction toggles a single per thread field which specifies whether an exception * being thrown needs to generate backtrace info. At any point after toggling this to be * false (no backtrace) you may encounter a nested exception which does require a backtrace. * This nested exception will toggle back to needing an exception. * * In theory, we could restore this field as we unwind frames but largely this optimization * only occurs in very simple scenarios. * * Also important to note this is only requesting for a backtrace or not. If you request * no backtrace but the error is not a StandardError exception it will still be required * to generate a backtrace. */
public class ToggleBacktraceInstr extends NoOperandInstr { private final boolean requiresBacktrace; public ToggleBacktraceInstr(boolean requiresBacktrace) { super(Operation.TOGGLE_BACKTRACE); this.requiresBacktrace = requiresBacktrace; } public boolean requiresBacktrace() { return requiresBacktrace; } public String[] toStringNonOperandArgs() { return new String[] { "" + requiresBacktrace }; } @Override public void encode(IRWriterEncoder e) { super.encode(e); e.encode(requiresBacktrace); } public static ToggleBacktraceInstr decode(IRReaderDecoder d) { return d.getCurrentScope().getManager().needsBacktrace(d.decodeBoolean()); } @Override public void visit(IRVisitor visitor) { visitor.ToggleBacktraceInstr(this); } @Override public Instr clone(CloneInfo info) { return this; } }