/** * Catch a {@code break} from a call with a block containing a break or inside a while/until loop. */ public class CatchBreakNode extends RubyNode { @Child private RubyNode body; private final BreakID breakID; private final BranchProfile breakProfile = BranchProfile.create(); private final ConditionProfile matchingBreakProfile = ConditionProfile.createCountingProfile(); public CatchBreakNode( RubyContext context, SourceSection sourceSection, RubyNode body, BreakID breakID) { super(context, sourceSection); this.body = body; this.breakID = breakID; } @Override public Object execute(VirtualFrame frame) { try { return body.execute(frame); } catch (BreakException e) { breakProfile.enter(); if (matchingBreakProfile.profile(e.getBreakID() == breakID)) { return e.getResult(); } else { throw e; } } } }
@NodeChildren({ @NodeChild(value = "array", type = RubyNode.class), @NodeChild(value = "requiredCapacity", type = RubyNode.class) }) @ImportStatic(ArrayGuards.class) public abstract class EnsureCapacityArrayNode extends RubyNode { private final ConditionProfile allocateProfile = ConditionProfile.createCountingProfile(); public EnsureCapacityArrayNode(RubyContext context, SourceSection sourceSection) { super(context, sourceSection); } public abstract Object executeEnsureCapacity( VirtualFrame frame, RubyBasicObject array, int requiredCapacity); @Specialization(guards = {"isRubyArray(array)", "isIntArray(array)"}) public boolean ensureCapacityInt(RubyBasicObject array, int requiredCapacity) { final int[] store = (int[]) ArrayNodes.getStore(array); if (allocateProfile.profile(store.length < requiredCapacity)) { ArrayNodes.setStore( array, Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), ArrayNodes.getSize(array)); return true; } else { return false; } } @Specialization(guards = {"isRubyArray(array)", "isLongArray(array)"}) public boolean ensureCapacityLong(RubyBasicObject array, int requiredCapacity) { final long[] store = (long[]) ArrayNodes.getStore(array); if (allocateProfile.profile(store.length < requiredCapacity)) { ArrayNodes.setStore( array, Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), ArrayNodes.getSize(array)); return true; } else { return false; } } @Specialization(guards = {"isRubyArray(array)", "isDoubleArray(array)"}) public boolean ensureCapacityDouble(RubyBasicObject array, int requiredCapacity) { final double[] store = (double[]) ArrayNodes.getStore(array); if (allocateProfile.profile(store.length < requiredCapacity)) { ArrayNodes.setStore( array, Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), ArrayNodes.getSize(array)); return true; } else { return false; } } @Specialization(guards = {"isRubyArray(array)", "isObjectArray(array)"}) public boolean ensureCapacityObject(RubyBasicObject array, int requiredCapacity) { final Object[] store = (Object[]) ArrayNodes.getStore(array); if (allocateProfile.profile(store.length < requiredCapacity)) { ArrayNodes.setStore( array, Arrays.copyOf(store, ArrayUtils.capacity(store.length, requiredCapacity)), ArrayNodes.getSize(array)); return true; } else { return false; } } }