Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: e3ce8b2ccbcf
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 720234c1250c
Choose a head ref
  • 3 commits
  • 4 files changed
  • 1 contributor

Commits on Mar 10, 2016

  1. Copy the full SHA
    c590cd5 View commit details
  2. Copy the full SHA
    2184cb1 View commit details
  3. Copy the full SHA
    720234c View commit details
Original file line number Diff line number Diff line change
@@ -10,6 +10,14 @@
*
* Some of the code in this class is modified from org.jruby.runtime.Helpers,
* licensed under the same EPL1.0/GPL 2.0/LGPL 2.1 used throughout.
*
* Contains code modified from ByteList's ByteList.java
*
* Copyright (C) 2007-2010 JRuby Community
* Copyright (C) 2007 Charles O Nutter <headius@headius.com>
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
* Copyright (C) 2007 Ola Bini <ola@ologix.com>
* Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
*/
package org.jruby.truffle.core.rope;

@@ -397,4 +405,28 @@ public static int hashForRange(Rope rope, int startingHashCode, int offset, int
}
}

@TruffleBoundary
public static int cmp(Rope string, Rope other) {
// Taken from org.jruby.util.ByteList#cmp.

if (string == other) return 0;
final int size = string.realSize();
final int len = Math.min(size, other.realSize());
int offset = -1;

final byte[] bytes = string.getBytes();
final byte[] otherBytes = other.getBytes();

// a bit of VM/JIT weirdness here: though in most cases
// performance is improved if array references are kept in
// a local variable (saves an instruction per access, as I
// [slightly] understand it), in some cases, when two (or more?)
// arrays are being accessed, the member reference is actually
// faster. this is one of those cases...
for ( ; ++offset < len && bytes[string.begin() + offset] == otherBytes[other.begin() + offset]; ) ;
if (offset < len) {
return (bytes[string.begin() + offset]&0xFF) > (otherBytes[other.begin() + offset]&0xFF) ? 1 : -1;
}
return size == other.realSize() ? 0 : size == len ? -1 : 1;
}
}
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.Layouts;
import org.jruby.truffle.core.array.ArrayOperations;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.core.thread.ThreadManager;
import org.jruby.truffle.language.RubyGuards;
@@ -67,6 +68,8 @@

import java.nio.ByteBuffer;

import static org.jruby.truffle.core.string.StringOperations.rope;

public abstract class IOPrimitiveNodes {

private static int STDOUT = 1;
@@ -205,14 +208,15 @@ public IOFNMatchPrimitiveNode(RubyContext context, SourceSection sourceSection)
@TruffleBoundary
@Specialization(guards = {"isRubyString(pattern)", "isRubyString(path)"})
public boolean fnmatch(DynamicObject pattern, DynamicObject path, int flags) {
final ByteList patternBytes = StringOperations.getByteListReadOnly(pattern);
final ByteList pathBytes = StringOperations.getByteListReadOnly(path);
return Dir.fnmatch(patternBytes.getUnsafeBytes(),
patternBytes.getBegin(),
patternBytes.getBegin() + patternBytes.getRealSize(),
pathBytes.getUnsafeBytes(),
pathBytes.getBegin(),
pathBytes.getBegin() + pathBytes.getRealSize(),
final Rope patternRope = rope(pattern);
final Rope pathRope = rope(path);

return Dir.fnmatch(patternRope.getBytes(),
patternRope.getBegin(),
patternRope.getBegin() + patternRope.getRealSize(),
pathRope.getBytes(),
pathRope.getBegin(),
pathRope.getBegin() + pathRope.getRealSize(),
flags) != Dir.FNM_NOMATCH;
}

Original file line number Diff line number Diff line change
@@ -22,6 +22,15 @@
* Copyright (C) 2006 Ola Bini <ola@ologix.com>
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
*
* Some of the code in this class is transposed from org.jruby.util.ByteList,
* licensed under the same EPL1.0/GPL 2.0/LGPL 2.1 used throughout.
*
* Copyright (C) 2007-2010 JRuby Community
* Copyright (C) 2007 Charles O Nutter <headius@headius.com>
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
* Copyright (C) 2007 Ola Bini <ola@ologix.com>
* Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
*
* Some of the code in this class is transliterated from C++ code in Rubinius.
*
* Copyright (c) 2007-2014, Evan Phoenix and contributors
@@ -768,16 +777,22 @@ public Object stringToF(DynamicObject string) {
}

@RubiniusPrimitive(name = "string_index", lowerFixnumParameters = 1)
@ImportStatic(StringGuards.class)
public static abstract class StringIndexPrimitiveNode extends RubiniusPrimitiveArrayArgumentsNode {

@Child StringByteCharacterIndexNode byteIndexToCharIndexNode;

public StringIndexPrimitiveNode(RubyContext context, SourceSection sourceSection) {

super(context, sourceSection);
}

@Specialization(guards = "isRubyString(pattern)")
@Specialization(guards = { "isRubyString(pattern)", "isBrokenCodeRange(pattern)" })
public DynamicObject stringIndexBrokenCodeRange(DynamicObject string, DynamicObject pattern, int start) {
return nil();
}


@Specialization(guards = { "isRubyString(pattern)", "!isBrokenCodeRange(pattern)" })
public Object stringIndex(VirtualFrame frame, DynamicObject string, DynamicObject pattern, int start) {
if (byteIndexToCharIndexNode == null) {
CompilerDirectives.transferToInterpreter();
@@ -787,9 +802,7 @@ public Object stringIndex(VirtualFrame frame, DynamicObject string, DynamicObjec
// Rubinius will pass in a byte index for the `start` value, but StringSupport.index requires a character index.
final int charIndex = byteIndexToCharIndexNode.executeStringBytCharacterIndex(frame, string, start, 0);

final int index = StringSupport.index(StringOperations.getCodeRangeableReadOnly(string),
StringOperations.getCodeRangeableReadOnly(pattern),
charIndex, Layouts.STRING.getRope(string).getEncoding());
final int index = index(rope(string), rope(pattern), charIndex, encoding(string));

if (index == -1) {
return nil();
@@ -798,6 +811,71 @@ public Object stringIndex(VirtualFrame frame, DynamicObject string, DynamicObjec
return index;
}

@TruffleBoundary
private int index(Rope source, Rope other, int offset, Encoding enc) {
// Taken from org.jruby.util.StringSupport.index.

int sourceLen = source.characterLength();
int otherLen = other.characterLength();

if (offset < 0) {
offset += sourceLen;
if (offset < 0) return -1;
}

if (sourceLen - offset < otherLen) return -1;
byte[]bytes = source.getBytes();
int p = source.getBegin();
int end = p + source.getRealSize();
if (offset != 0) {
offset = source.isSingleByteOptimizable() ? offset : StringSupport.offset(enc, bytes, p, end, offset);
p += offset;
}
if (otherLen == 0) return offset;

while (true) {
int pos = indexOf(source, other, p - source.getBegin());
if (pos < 0) return pos;
pos -= (p - source.getBegin());
int t = enc.rightAdjustCharHead(bytes, p, p + pos, end);
if (t == p + pos) return pos + offset;
if ((sourceLen -= t - p) <= 0) return -1;
offset += t - p;
p = t;
}
}

@TruffleBoundary
private int indexOf(Rope sourceRope, Rope otherRope, int fromIndex) {
// Taken from org.jruby.util.ByteList.indexOf.

final byte[] source = sourceRope.getBytes();
final int sourceOffset = sourceRope.begin();
final int sourceCount = sourceRope.realSize();
final byte[] target = otherRope.getBytes();
final int targetOffset = otherRope.begin();
final int targetCount = otherRope.realSize();

if (fromIndex >= sourceCount) return (targetCount == 0 ? sourceCount : -1);
if (fromIndex < 0) fromIndex = 0;
if (targetCount == 0) return fromIndex;

byte first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);

for (int i = sourceOffset + fromIndex; i <= max; i++) {
if (source[i] != first) while (++i <= max && source[i] != first);

if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++);

if (j == end) return i - sourceOffset;
}
}
return -1;
}
}

@RubiniusPrimitive(name = "string_character_byte_index", needsSelf = false, lowerFixnumParameters = { 0, 1 })
Loading