Skip to content

Commit

Permalink
Merge branch 'master' into truffle-head
Browse files Browse the repository at this point in the history
Conflicts:
	truffle/src/main/java/org/jruby/truffle/nodes/core/ArrayNodes.java
	truffle/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
	truffle/src/main/java/org/jruby/truffle/nodes/core/StringNodes.java
  • Loading branch information
chrisseaton committed Mar 31, 2015
2 parents e002633 + ad4dcf0 commit 7be2875
Show file tree
Hide file tree
Showing 344 changed files with 4,489 additions and 2,306 deletions.
4 changes: 2 additions & 2 deletions core/pom.xml
Expand Up @@ -107,7 +107,7 @@
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-posix</artifactId>
<version>3.0.10</version>
<version>3.0.11-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
Expand Down Expand Up @@ -138,7 +138,7 @@
<dependency>
<groupId>org.jruby.extras</groupId>
<artifactId>bytelist</artifactId>
<version>1.0.12</version>
<version>1.0.13-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jruby.jcodings</groupId>
Expand Down
15 changes: 8 additions & 7 deletions core/src/main/java/org/jruby/RubyArray.java
Expand Up @@ -39,6 +39,7 @@

import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.jcodings.specific.UTF16BEEncoding;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.common.IRubyWarnings.ID;
Expand Down Expand Up @@ -1444,15 +1445,15 @@ private IRubyObject inspectAry(ThreadContext context) {
boolean tainted = isTaint();

for (int i = 0; i < realLength; i++) {
if (i > 0) str.cat((byte)',').cat((byte)' ');

RubyString str2 = inspect(context, safeArrayRef(values, begin + i));
if (i == 0 && str2.getEncoding() != encoding) str.setEncoding(str2.getEncoding());
if (str2.isTaint()) tainted = true;

str.cat19(str2);
RubyString s = inspect(context, safeArrayRef(values, begin + i));
if (s.isTaint()) tainted = true;
if (i > 0) str.cat(',', encoding).cat(' ', encoding);
else str.setEncoding(s.getEncoding());

str.cat19(s);
}
str.cat((byte)']');
str.cat(']', encoding);

if (tainted) str.setTaint(true);

Expand Down
17 changes: 12 additions & 5 deletions core/src/main/java/org/jruby/RubyInteger.java
Expand Up @@ -348,26 +348,33 @@ public RubyString chr19(ThreadContext context, IRubyObject arg) {
if (enc == ASCIIEncoding.INSTANCE && value >= 0x80) {
return chr19(context);
}
return RubyString.newStringNoCopy(runtime, fromEncodedBytes(runtime, enc, (int)value), enc, 0);
return RubyString.newStringNoCopy(runtime, fromEncodedBytes(runtime, enc, value), enc, 0);
}

private ByteList fromEncodedBytes(Ruby runtime, Encoding enc, int value) {
private ByteList fromEncodedBytes(Ruby runtime, Encoding enc, long value) {
int n;
try {
n = value < 0 ? 0 : enc.codeToMbcLength(value);
n = value < 0 ? 0 : enc.codeToMbcLength((int)value);
} catch (EncodingException ee) {
n = 0;
}

if (n <= 0) throw runtime.newRangeError(this.toString() + " out of char range");

ByteList bytes = new ByteList(n);


boolean ok = false;
try {
enc.codeToMbc(value, bytes.getUnsafeBytes(), 0);
enc.codeToMbc((int)value, bytes.getUnsafeBytes(), 0);
ok = StringSupport.preciseLength(enc, bytes.unsafeBytes(), 0, n) == n;
} catch (EncodingException e) {
// ok = false, fall through
}

if (!ok) {
throw runtime.newRangeError("invalid codepoint " + String.format("0x%x in ", value) + enc.getCharsetName());
}

bytes.setRealSize(n);
return bytes;
}
Expand Down
88 changes: 71 additions & 17 deletions core/src/main/java/org/jruby/RubyMatchData.java
Expand Up @@ -138,6 +138,8 @@ private void updatePairs(ByteList value, Encoding encoding, Pair[] pairs) {
}

private void updateCharOffsetOnlyOneReg(ByteList value, Encoding encoding) {
if (charOffsetUpdated) return;

if (charOffsets == null || charOffsets.numRegs < 1) charOffsets = new Region(1);

if (encoding.maxLength() == 1) {
Expand All @@ -148,21 +150,32 @@ private void updateCharOffsetOnlyOneReg(ByteList value, Encoding encoding) {
}

Pair[] pairs = new Pair[2];
pairs[0] = new Pair();
pairs[0].bytePos = begin;
pairs[1] = new Pair();
pairs[1].bytePos = end;
if (begin >= 0) {
pairs[0] = new Pair();
pairs[0].bytePos = begin;
pairs[1] = new Pair();
pairs[1].bytePos = end;
}

updatePairs(value, encoding, pairs);

if (begin < 0) {
charOffsets.beg[0] = charOffsets.end[0] = -1;
return;
}
Pair key = new Pair();
key.bytePos = begin;
charOffsets.beg[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
key.bytePos = end;
charOffsets.end[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;
charOffsets.end[0] = pairs[Arrays.binarySearch(pairs, key)].charPos;

charOffsetUpdated = true;
}

private void updateCharOffsetManyRegs(ByteList value, Encoding encoding) {
if (charOffsetUpdated) return;

final Region regs = this.regs;
int numRegs = regs.numRegs;

if (charOffsets == null || charOffsets.numRegs < numRegs) charOffsets = new Region(numRegs);
Expand All @@ -172,6 +185,7 @@ private void updateCharOffsetManyRegs(ByteList value, Encoding encoding) {
charOffsets.beg[i] = regs.beg[i];
charOffsets.end[i] = regs.end[i];
}
charOffsetUpdated = true;
return;
}

Expand All @@ -197,7 +211,9 @@ private void updateCharOffsetManyRegs(ByteList value, Encoding encoding) {
charOffsets.beg[i] = pairs[Arrays.binarySearch(pairs, key)].charPos;
key.bytePos = regs.end[i];
charOffsets.end[i] = pairs[Arrays.binarySearch(pairs, key)].charPos;
}
}

charOffsetUpdated = true;
}

private void updateCharOffset() {
Expand Down Expand Up @@ -454,28 +470,27 @@ public IRubyObject size(ThreadContext context) {
return regs == null ? RubyFixnum.one(runtime) : RubyFixnum.newFixnum(runtime, regs.numRegs);
}

/** match_begin
*
/**
* MRI: match_begin
*/
@JRubyMethod
public IRubyObject begin(ThreadContext context, IRubyObject index) {
check();
Ruby runtime = context.runtime;

int i = backrefNumber(index);
Ruby runtime = context.runtime;

if (i < 0 || (regs == null ? 1 : regs.numRegs) <= i) throw runtime.newIndexError("index " + i + " out of matches");
check();
if (i < 0 || (regs == null ? 1 : regs.numRegs) <= i) {
throw runtime.newIndexError("index " + i + " out of matches");
}

int b = regs == null ? begin : regs.beg[i];

if (b < 0) return runtime.getNil();
if (b < 0) return context.nil;

if (!str.singleByteOptimizable()) {
updateCharOffset();
b = charOffsets.beg[i];
}
updateCharOffset();

return RubyFixnum.newFixnum(runtime, b);
return RubyFixnum.newFixnum(runtime, charOffsets.beg[i]);
}

/** match_end
Expand Down Expand Up @@ -627,4 +642,43 @@ public RubyFixnum hash() {
return getRuntime().newFixnum(pattern.hashCode() ^ str.hashCode());
}

/**
* Get the begin offset of the given region, or -1 if the region does not exist.
*
* @param i the region for which to fetch the begin offset
* @return the begin offset for the region
*/
public int begin(int i) {
if (regs == null) {
if (i > 1) return -1;
return begin;
}
if (i > regs.numRegs) return -1;
return regs.beg[i];
}

/**
* Get the end offset of the given region, or -1 if the region does not exist.
*
* @param i the region for which to fetch the end offset
* @return the end offset for the region
*/
public int end(int i) {
if (regs == null) {
if (i > 1) return -1;
return end;
}
if (i > regs.numRegs) return -1;
return regs.end[i];
}

/**
* Fetch the number of regions in this match.
*
* @return the number of regions in this match
*/
public int numRegs() {
return regs == null ? 1 : regs.numRegs;
}

}
15 changes: 14 additions & 1 deletion core/src/main/java/org/jruby/RubyObject.java
Expand Up @@ -45,6 +45,7 @@
import java.util.List;
import java.util.Set;

import org.jcodings.Encoding;
import org.jruby.anno.JRubyClass;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Block;
Expand Down Expand Up @@ -530,7 +531,19 @@ private int nonFixnumHashCode(IRubyObject hashValue) {
* Prefered over callMethod(context, "inspect")
*/
public static RubyString inspect(ThreadContext context, IRubyObject object) {
return RubyString.objAsString(context, object.callMethod(context, "inspect"));
Ruby runtime = context.runtime;
RubyString str = RubyString.objAsString(context, object.callMethod(context, "inspect"));
Encoding ext = runtime.getDefaultExternalEncoding();
if (!ext.isAsciiCompatible()) {
if (!str.isAsciiOnly()) {
throw runtime.newEncodingCompatibilityError("inspected result must be ASCII only if default external encoding is ASCII incompatible");
}
return str;
}
if (str.getEncoding() != ext && !str.isAsciiOnly()) {
throw runtime.newEncodingCompatibilityError("inspected result must be ASCII only or use the default external encoding");
}
return str;
}

/**
Expand Down

0 comments on commit 7be2875

Please sign in to comment.