Skip to content

Commit

Permalink
[Truffle] Fixed a bunch of specs for 64-bit ropes.
Browse files Browse the repository at this point in the history
nirvdrum committed Apr 8, 2016
1 parent 4710381 commit c240e8c
Showing 17 changed files with 184 additions and 57 deletions.
Original file line number Diff line number Diff line change
@@ -17,8 +17,8 @@ public class FormatFrameDescriptor {

public static final FrameDescriptor FRAME_DESCRIPTOR = new FrameDescriptor();
public static final FrameSlot SOURCE_SLOT = FRAME_DESCRIPTOR.addFrameSlot("source", FrameSlotKind.Object);
public static final FrameSlot SOURCE_LENGTH_SLOT = FRAME_DESCRIPTOR.addFrameSlot("source-length", FrameSlotKind.Int);
public static final FrameSlot SOURCE_POSITION_SLOT = FRAME_DESCRIPTOR.addFrameSlot("source-position", FrameSlotKind.Int);
public static final FrameSlot SOURCE_LENGTH_SLOT = FRAME_DESCRIPTOR.addFrameSlot("source-length", FrameSlotKind.Long);
public static final FrameSlot SOURCE_POSITION_SLOT = FRAME_DESCRIPTOR.addFrameSlot("source-position", FrameSlotKind.Long);
public static final FrameSlot OUTPUT_SLOT = FRAME_DESCRIPTOR.addFrameSlot("output", FrameSlotKind.Object);
public static final FrameSlot OUTPUT_POSITION_SLOT = FRAME_DESCRIPTOR.addFrameSlot("output-position", FrameSlotKind.Int);
public static final FrameSlot STRING_LENGTH_SLOT = FRAME_DESCRIPTOR.addFrameSlot("string-length", FrameSlotKind.Int);
34 changes: 23 additions & 11 deletions truffle/src/main/java/org/jruby/truffle/core/format/FormatNode.java
Original file line number Diff line number Diff line change
@@ -17,9 +17,11 @@
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.array.ArrayUtils;
import org.jruby.truffle.core.format.exceptions.TooFewArgumentsException;
import org.jruby.truffle.core.rope.CodeRange;
import org.jruby.truffle.core.rope.RopeTooLongException;

import java.util.Arrays;

@@ -39,50 +41,55 @@ public FormatNode(RubyContext context) {

public abstract Object execute(VirtualFrame frame);

public int getSourceLength(VirtualFrame frame) {
public long getSourceLength(VirtualFrame frame) {
try {
return frame.getInt(FormatFrameDescriptor.SOURCE_LENGTH_SLOT);
return frame.getLong(FormatFrameDescriptor.SOURCE_LENGTH_SLOT);
} catch (FrameSlotTypeException e) {
throw new IllegalStateException(e);
}
}

protected int getSourcePosition(VirtualFrame frame) {
protected long getSourcePosition(VirtualFrame frame) {
try {
return frame.getInt(FormatFrameDescriptor.SOURCE_POSITION_SLOT);
return frame.getLong(FormatFrameDescriptor.SOURCE_POSITION_SLOT);
} catch (FrameSlotTypeException e) {
throw new IllegalStateException(e);
}
}

protected void setSourcePosition(VirtualFrame frame, int position) {
frame.setInt(FormatFrameDescriptor.SOURCE_POSITION_SLOT, position);
protected void setSourcePosition(VirtualFrame frame, long position) {
frame.setLong(FormatFrameDescriptor.SOURCE_POSITION_SLOT, position);
}

protected int advanceSourcePosition(VirtualFrame frame) {
return advanceSourcePosition(frame, 1);
}

protected int advanceSourcePosition(VirtualFrame frame, int count) {
final int sourcePosition = getSourcePosition(frame);
final long sourcePosition = getSourcePosition(frame);

if (tooFewArgumentsProfile.profile(sourcePosition + count > getSourceLength(frame))) {
throw new TooFewArgumentsException();
}

setSourcePosition(frame, sourcePosition + count);

return sourcePosition;
if (!CoreLibrary.fitsIntoInteger(sourcePosition)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

return (int) sourcePosition;
}

protected int advanceSourcePositionNoThrow(VirtualFrame frame) {
return advanceSourcePositionNoThrow(frame, 1, false);
}

protected int advanceSourcePositionNoThrow(VirtualFrame frame, int count, boolean consumePartial) {
final int sourcePosition = getSourcePosition(frame);
final long sourcePosition = getSourcePosition(frame);

final int sourceLength = getSourceLength(frame);
final long sourceLength = getSourceLength(frame);

if (sourceRangeProfile.profile(sourcePosition + count > sourceLength)) {
if (consumePartial) {
@@ -94,7 +101,12 @@ protected int advanceSourcePositionNoThrow(VirtualFrame frame, int count, boolea

setSourcePosition(frame, sourcePosition + count);

return sourcePosition;
if (!CoreLibrary.fitsIntoInteger(sourcePosition)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

return (int) sourcePosition;
}

protected Object getOutput(VirtualFrame frame) {
Original file line number Diff line number Diff line change
@@ -42,14 +42,19 @@ public FormatRootNode(String description, FormatEncoding encoding, FormatNode ch
@Override
public Object execute(VirtualFrame frame) {
frame.setObject(FormatFrameDescriptor.SOURCE_SLOT, frame.getArguments()[0]);
frame.setInt(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (int) frame.getArguments()[1]);
frame.setInt(FormatFrameDescriptor.SOURCE_POSITION_SLOT, 0);
frame.setLong(FormatFrameDescriptor.SOURCE_POSITION_SLOT, 0L);
frame.setObject(FormatFrameDescriptor.OUTPUT_SLOT, new byte[expectedLength]);
frame.setInt(FormatFrameDescriptor.OUTPUT_POSITION_SLOT, 0);
frame.setInt(FormatFrameDescriptor.STRING_LENGTH_SLOT, 0);
frame.setInt(FormatFrameDescriptor.STRING_CODE_RANGE_SLOT, StringSupport.CR_UNKNOWN);
frame.setBoolean(FormatFrameDescriptor.TAINT_SLOT, false);

if (frame.getArguments()[1] instanceof Integer) {
frame.setLong(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (long)(int) frame.getArguments()[1]);
} else {
frame.setLong(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (long) frame.getArguments()[1]);
}

child.execute(frame);

final int outputLength;
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ public Object execute(VirtualFrame frame) {
if (toEnd) {
setSourcePosition(frame, getSourceLength(frame));
} else {
final int position = getSourcePosition(frame);
final long position = getSourcePosition(frame);

if (rangeProfile.profile(position + 1 > getSourceLength(frame))) {
throw new OutsideOfStringException();
Original file line number Diff line number Diff line change
@@ -28,12 +28,12 @@ public ReverseSourcePositionNode(RubyContext context, boolean star) {

@Override
public Object execute(VirtualFrame frame) {
final int position = getSourcePosition(frame);
final long position = getSourcePosition(frame);

if (star) {
final int remaining = getSourceLength(frame) - position;
final long remaining = getSourceLength(frame) - position;

final int target = position - remaining;
final long target = position - remaining;

if (rangeProfile.profile(target < 0)) {
throw new OutsideOfStringException();
Original file line number Diff line number Diff line change
@@ -45,16 +45,19 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.numeric.FixnumOrBignumNode;
import org.jruby.truffle.core.rope.RopeTooLongException;

import java.math.BigInteger;
import java.nio.ByteBuffer;
@@ -78,10 +81,20 @@ public ReadBERNode(RubyContext context) {

@Specialization
protected Object encode(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final int length = getSourceLength(frame);
final long position = getSourcePosition(frame);
final long length = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, length - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(length)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (length - position));
int pos = encode.position();

final long ul = encode.get(pos) & 0x7f;
Original file line number Diff line number Diff line change
@@ -45,18 +45,21 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jcodings.specific.ASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.exceptions.InvalidFormatException;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;
import org.jruby.util.Pack;

import java.nio.ByteBuffer;
@@ -73,10 +76,20 @@ public ReadBase64StringNode(RubyContext context) {

@Specialization
public Object read(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final int length = getSourceLength(frame);
final long position = getSourcePosition(frame);
final long length = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, length - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(length)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (length - position));

final byte[] result = read(encode);

Original file line number Diff line number Diff line change
@@ -17,10 +17,12 @@
import com.oracle.truffle.api.object.DynamicObject;
import org.jcodings.specific.ASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;

import java.util.Arrays;

@@ -59,31 +61,36 @@ public void read(VirtualFrame frame, Object source) {

@Specialization
public DynamicObject read(VirtualFrame frame, byte[] source) {
final int start = getSourcePosition(frame);
final long start = getSourcePosition(frame);

int length;
if (!CoreLibrary.fitsIntoInteger(start)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

long length;

if (readToEnd) {
length = 0;

while (start + length < getSourceLength(frame)
&& (!readToNull || (start + length < getSourceLength(frame) && source[start + length] != 0))) {
&& (!readToNull || (start + length < getSourceLength(frame) && source[(int) (start + length)] != 0))) {
length++;
}

if (start + length < getSourceLength(frame) && source[start + length] == 0) {
if (start + length < getSourceLength(frame) && source[(int) (start + length)] == 0) {
length++;
}
} else if (readToNull) {
length = 0;

while (start + length < getSourceLength(frame)
&& length < count
&& (!readToNull || (start + length < getSourceLength(frame) && source[start + length] != 0))) {
&& (!readToNull || (start + length < getSourceLength(frame) && source[(int) (start + length)] != 0))) {
length++;
}

if (start + length < getSourceLength(frame) && source[start + length] == 0) {
if (start + length < getSourceLength(frame) && source[(int) (start + length)] == 0) {
length++;
}
} else {
@@ -94,15 +101,15 @@ public DynamicObject read(VirtualFrame frame, byte[] source) {
}
}

int usedLength = length;
long usedLength = length;

while (usedLength > 0 && ((trimTrailingSpaces && source[start + usedLength - 1] == ' ')
|| (trimTrailingNulls && source[start + usedLength - 1] == 0))) {
while (usedLength > 0 && ((trimTrailingSpaces && source[(int) (start + usedLength - 1)] == ' ')
|| (trimTrailingNulls && source[(int) (start + usedLength - 1)] == 0))) {
usedLength--;
}

if (trimToFirstNull) {
final int firstNull = indexOfFirstNull(source, start, usedLength);
final int firstNull = indexOfFirstNull(source, (int) start, (int) usedLength);

if (firstNull != -1 && trimTrailingNulls) {
usedLength = firstNull;
@@ -112,7 +119,7 @@ public DynamicObject read(VirtualFrame frame, byte[] source) {
setSourcePosition(frame, start + length);

return Layouts.STRING.createString(getContext().getCoreLibrary().getStringFactory(),
new AsciiOnlyLeafRope(Arrays.copyOfRange(source, start, start + usedLength), ASCIIEncoding.INSTANCE));
new AsciiOnlyLeafRope(Arrays.copyOfRange(source, (int) start, (int) (start + usedLength)), ASCIIEncoding.INSTANCE));
}

private int indexOfFirstNull(byte[] bytes, int start, int length) {
Original file line number Diff line number Diff line change
@@ -45,16 +45,19 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -77,9 +80,20 @@ public ReadBitStringNode(RubyContext context, ByteOrder byteOrder, boolean star,

@Specialization
public Object read(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final long position = getSourcePosition(frame);
final long sourceLength = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, getSourceLength(frame) - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(sourceLength)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (sourceLength - position));

final int occurrences;

Original file line number Diff line number Diff line change
@@ -45,16 +45,19 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;
import org.jruby.util.Pack;

import java.nio.ByteBuffer;
@@ -78,9 +81,20 @@ public ReadHexStringNode(RubyContext context, ByteOrder byteOrder, boolean star,

@Specialization
public Object read(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final long position = getSourcePosition(frame);
final long sourceLength = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, getSourceLength(frame) - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(sourceLength)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (sourceLength - position));

int occurrences = length;

Original file line number Diff line number Diff line change
@@ -45,16 +45,19 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;
import org.jruby.util.Pack;

import java.nio.ByteBuffer;
@@ -71,10 +74,20 @@ public ReadMIMEStringNode(RubyContext context) {

@Specialization
public Object read(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final int length = getSourceLength(frame);
final long position = getSourcePosition(frame);
final long length = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, length - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(length)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (length - position));

final byte[] lElem = new byte[Math.max(encode.remaining(), 0)];

Original file line number Diff line number Diff line change
@@ -16,10 +16,12 @@
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.MissingValue;
import org.jruby.truffle.core.format.exceptions.InvalidFormatException;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.RopeTooLongException;

@NodeChildren({
@NodeChild(value = "source", type = SourceNode.class),
@@ -40,16 +42,21 @@ public void read(VirtualFrame frame, Object source) {

@Specialization
public Object read(VirtualFrame frame, byte[] source) {
final int index = getSourcePosition(frame);
final int sourceLength = getSourceLength(frame);
final long index = getSourcePosition(frame);
final long sourceLength = getSourceLength(frame);

assert index != -1;

if (rangeProfile.profile(index >= sourceLength)) {
return MissingValue.INSTANCE;
}

long codepoint = source[index] & 0xff;
if (!CoreLibrary.fitsIntoInteger(index)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with indices larger than int range");
}

long codepoint = source[(int) index] & 0xff;
final int length;

if (codepoint >> 7 == 0) {
@@ -84,7 +91,7 @@ public Object read(VirtualFrame frame, byte[] source) {

for (int n = 1; n < length; n++) {
codepoint <<= 6;
codepoint |= source[index + n] & 0b00111111;
codepoint |= source[(int) (index + n)] & 0b00111111;
}

setSourcePosition(frame, index + length);
Original file line number Diff line number Diff line change
@@ -45,16 +45,19 @@
*/
package org.jruby.truffle.core.format.read.bytes;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.CoreLibrary;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.format.FormatNode;
import org.jruby.truffle.core.format.read.SourceNode;
import org.jruby.truffle.core.rope.AsciiOnlyLeafRope;
import org.jruby.truffle.core.rope.RopeTooLongException;
import org.jruby.util.Pack;

import java.nio.ByteBuffer;
@@ -71,9 +74,20 @@ public ReadUUStringNode(RubyContext context) {

@Specialization
protected Object encode(VirtualFrame frame, byte[] source) {
final int position = getSourcePosition(frame);
final long position = getSourcePosition(frame);
final long sourceLength = getSourceLength(frame);

final ByteBuffer encode = ByteBuffer.wrap(source, position, getSourceLength(frame) - position);
if (!CoreLibrary.fitsIntoInteger(position)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with positions larger than int range");
}

if (!CoreLibrary.fitsIntoInteger(sourceLength)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with strings larger than int range");
}

final ByteBuffer encode = ByteBuffer.wrap(source, (int) position, (int) (sourceLength - position));

int length = encode.remaining() * 3 / 4;
byte[] lElem = new byte[length];
Original file line number Diff line number Diff line change
@@ -46,12 +46,17 @@ public UnpackRootNode(RubyContext context, String description, FormatNode child)
@Override
public Object execute(VirtualFrame frame) {
frame.setObject(FormatFrameDescriptor.SOURCE_SLOT, frame.getArguments()[0]);
frame.setInt(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (int) frame.getArguments()[1]);
frame.setInt(FormatFrameDescriptor.SOURCE_POSITION_SLOT, 0);
frame.setLong(FormatFrameDescriptor.SOURCE_POSITION_SLOT, 0L);
frame.setObject(FormatFrameDescriptor.OUTPUT_SLOT, new Object[expectedLength]);
frame.setInt(FormatFrameDescriptor.OUTPUT_POSITION_SLOT, 0);
frame.setBoolean(FormatFrameDescriptor.TAINT_SLOT, false);

if (frame.getArguments()[1] instanceof Integer) {
frame.setLong(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (long)(int) frame.getArguments()[1]);
} else {
frame.setLong(FormatFrameDescriptor.SOURCE_LENGTH_SLOT, (long) frame.getArguments()[1]);
}

child.execute(frame);

final int outputLength;
Original file line number Diff line number Diff line change
@@ -336,7 +336,7 @@ public LeafRope makeAsciiOnlyLeafRope(byte[] bytes, Encoding encoding, CodeRange
}

@Specialization(guards = { "isValid(codeRange)", "wasProvided(characterLength)" })
public LeafRope makeValidLeafRopeWithCharacterLength(byte[] bytes, Encoding encoding, CodeRange codeRange, int characterLength) {
public LeafRope makeValidLeafRopeWithCharacterLength(byte[] bytes, Encoding encoding, CodeRange codeRange, long characterLength) {
return new ValidLeafRope(bytes, encoding, characterLength);
}

Original file line number Diff line number Diff line change
@@ -711,7 +711,7 @@ public GetcwdNode(RubyContext context, SourceSection sourceSection) {

@CompilerDirectives.TruffleBoundary
@Specialization(guards = "isRubyString(resultPath)")
public DynamicObject getcwd(DynamicObject resultPath, int maxSize) {
public DynamicObject getcwd(DynamicObject resultPath, long maxSize) {
// We just ignore maxSize - I think this is ok

final String path = getContext().getJRubyRuntime().getCurrentDirectory();
Original file line number Diff line number Diff line change
@@ -428,7 +428,7 @@ public Object stringChrAtSingleByte(DynamicObject string, long byteIndex,
}

@Specialization(guards = { "!indexOutOfBounds(string, byteIndex)", "!isSingleByteOptimizable(string)" })
public Object stringChrAt(DynamicObject string, int byteIndex,
public Object stringChrAt(DynamicObject string, long byteIndex,
@Cached("create(getContext(), getSourceSection())") StringByteSubstringPrimitiveNode stringByteSubstringNode) {
// Taken from Rubinius's Character::create_from.

@@ -439,8 +439,13 @@ public Object stringChrAt(DynamicObject string, int byteIndex,
throw new RopeTooLongException("Can't work out the length for subranges of ropes larger than the int range");
}

if (!CoreLibrary.fitsIntoInteger(byteIndex)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't handle byte index larger than int range");
}

final int end = (int) rope.byteLength();
final int c = preciseLength(rope, byteIndex, end);
final int c = preciseLength(rope, (int) byteIndex, end);

if (! StringSupport.MBCLEN_CHARFOUND_P(c)) {
return nil();
@@ -1293,14 +1298,19 @@ public StringPreviousByteIndexPrimitiveNode(RubyContext context, SourceSection s
}

@Specialization
public Object stringPreviousByteIndex(DynamicObject string, int index) {
public Object stringPreviousByteIndex(DynamicObject string, long index) {
// Port of Rubinius's String::previous_byte_index.

if (index < 0) {
CompilerDirectives.transferToInterpreter();
throw new RaiseException(coreLibrary().argumentError("negative index given", this));
}

if (!CoreLibrary.fitsIntoInteger(index)) {
CompilerDirectives.transferToInterpreter();
throw new RopeTooLongException("Can't work with indices larger than int range");
}

final Rope rope = rope(string);
final int p = rope.begin();
final long end = p + rope.byteLength();
@@ -1310,7 +1320,7 @@ public Object stringPreviousByteIndex(DynamicObject string, int index) {
throw new RopeTooLongException("Can't index into rope larger than int range");
}

final int b = rope.getEncoding().prevCharHead(rope.getBytes(), p, p + index, (int) end);
final int b = rope.getEncoding().prevCharHead(rope.getBytes(), p, (int) (p + index), (int) end);

if (b == -1) {
return nil();

0 comments on commit c240e8c

Please sign in to comment.