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: 4bf8f6efe1d1
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0e60f311b328
Choose a head ref
  • 1 commit
  • 5 files changed
  • 1 contributor

Commits on Dec 10, 2014

  1. Copy the full SHA
    0e60f31 View commit details
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ public CaseEqualNode(CaseEqualNode prev) {
public Object match(RubyRegexp regexp, RubyString string) {
notDesignedForCompilation();

return regexp.matchCommon(string.getBytes(), true) != getContext().getCoreLibrary().getNilObject();
return regexp.matchCommon(string.getBytes(), true, false) != getContext().getCoreLibrary().getNilObject();
}

}
@@ -96,7 +96,7 @@ public MatchOperatorNode(MatchOperatorNode prev) {

@Specialization
public Object match(RubyRegexp regexp, RubyString string) {
return regexp.matchCommon(string.getBytes(), true);
return regexp.matchCommon(string.getBytes(), true, true);
}

@Specialization
@@ -238,7 +238,7 @@ public MatchNode(MatchNode prev) {

@Specialization
public Object match(RubyRegexp regexp, RubyString string) {
return regexp.matchCommon(string.getBytes(), false);
return regexp.matchCommon(string.getBytes(), false, false);
}

}
Original file line number Diff line number Diff line change
@@ -253,7 +253,7 @@ public MatchOperatorNode(MatchOperatorNode prev) {

@Specialization
public Object match(RubyString string, RubyRegexp regexp) {
return regexp.matchCommon(string.getBytes(), true);
return regexp.matchCommon(string.getBytes(), true, false);
}
}

@@ -645,12 +645,12 @@ public Object match(RubyString string, RubyString regexpString) {
notDesignedForCompilation();

final RubyRegexp regexp = new RubyRegexp(this, getContext().getCoreLibrary().getRegexpClass(), regexpString.getBytes(), Option.DEFAULT);
return regexp.matchCommon(string.getBytes(), false);
return regexp.matchCommon(string.getBytes(), false, false);
}

@Specialization
public Object match(RubyString string, RubyRegexp regexp) {
return regexp.matchCommon(string.getBytes(), false);
return regexp.matchCommon(string.getBytes(), false, false);
}
}

59 changes: 54 additions & 5 deletions core/src/main/java/org/jruby/truffle/runtime/core/RubyRegexp.java
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Iterator;

/**
* Represents the Ruby {@code Regexp} class.
@@ -89,7 +90,7 @@ public ByteList getSource() {
}

@CompilerDirectives.SlowPath
public Object matchCommon(ByteList bytes, boolean operator) {
public Object matchCommon(ByteList bytes, boolean operator, boolean setNamedCaptures) {
final RubyContext context = getContext();

final Frame frame = Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.READ_WRITE, false);
@@ -117,6 +118,14 @@ public Object matchCommon(ByteList bytes, boolean operator) {

setThread("$~", nil);

if (setNamedCaptures && regex.numberOfNames() > 0) {
for (Iterator<NameEntry> i = regex.namedBackrefIterator(); i.hasNext();) {
final NameEntry e = i.next();
final String name = new String(e.name, e.nameP, e.nameEnd - e.nameP).intern();
setFrame(frame, name, getContext().getCoreLibrary().getNilObject());
}
}

return getContext().getCoreLibrary().getNilObject();
}

@@ -173,6 +182,46 @@ public Object matchCommon(ByteList bytes, boolean operator) {

setThread("$~", matchObject);

if (setNamedCaptures && regex.numberOfNames() > 0) {
for (Iterator<NameEntry> i = regex.namedBackrefIterator(); i.hasNext();) {
final NameEntry e = i.next();
final String name = new String(e.name, e.nameP, e.nameEnd - e.nameP).intern();
int nth = regex.nameToBackrefNumber(e.name, e.nameP, e.nameEnd, region);

final Object value;

// Copied from jubry/RubyRegexp - see copyright notice there

if (region == null) {
if (nth >= 1 || (nth < 0 && ++nth <= 0)) {
value = getContext().getCoreLibrary().getNilObject();
} else {
final int start = matcher.getBegin();
final int end = matcher.getEnd();
if (start != -1) {
value = new RubyString(context.getCoreLibrary().getStringClass(), bytes.makeShared(start, end - start).dup());
} else {
value = getContext().getCoreLibrary().getNilObject();
}
}
} else {
if (nth >= region.numRegs || (nth < 0 && (nth+=region.numRegs) <= 0)) {
value = getContext().getCoreLibrary().getNilObject();
} else {
final int start = region.beg[nth];
final int end = region.end[nth];
if (start != -1) {
value = new RubyString(context.getCoreLibrary().getStringClass(), bytes.makeShared(start, end - start).dup());
} else {
value = getContext().getCoreLibrary().getNilObject();
}
}
}

setFrame(frame, name, value);
}
}

if (operator) {
return matcher.getBegin();
} else {
@@ -337,11 +386,11 @@ public static Regex compile(RubyNode currentNode, RubyContext context, ByteList
public static Regex compile(RubyNode currentNode, RubyContext context, byte[] bytes, Encoding encoding, int options) {
RubyNode.notDesignedForCompilation();

//try {
try {
return new Regex(bytes, 0, bytes.length, options, encoding, Syntax.RUBY);
//} catch (ValueException e) {
// throw new org.jruby.truffle.runtime.control.RaiseException(context.getCoreLibrary().runtimeError("error compiling regex", currentNode));
//}
} catch (ValueException e) {
throw new org.jruby.truffle.runtime.control.RaiseException(context.getCoreLibrary().runtimeError("error compiling regex", currentNode));
}
}

public void forceEncoding(RubyEncoding encoding) {
Original file line number Diff line number Diff line change
@@ -15,7 +15,9 @@
import com.oracle.truffle.api.nodes.NodeUtil;
import org.jcodings.Encoding;
import org.jcodings.specific.USASCIIEncoding;
import org.joni.NameEntry;
import org.joni.Regex;
import org.joni.Syntax;
import org.jruby.ast.*;
import org.jruby.common.IRubyWarnings;
import org.jruby.lexer.yacc.InvalidSourcePosition;
@@ -1239,15 +1241,16 @@ public RubyNode visitLocalAsgnNode(org.jruby.ast.LocalAsgnNode node) {
if (lhs == null) {
if (environment.hasOwnScopeForAssignments()) {
environment.declareVar(node.getName());
}
} else {
TranslatorEnvironment environmentToDeclareIn = environment;

TranslatorEnvironment environmentToDeclareIn = environment;
while (!environmentToDeclareIn.hasOwnScopeForAssignments()) {
environmentToDeclareIn = environmentToDeclareIn.getParent();
}

while (!environmentToDeclareIn.hasOwnScopeForAssignments()) {
environmentToDeclareIn = environmentToDeclareIn.getParent();
environmentToDeclareIn.declareVar(node.getName());
}

environmentToDeclareIn.declareVar(node.getName());
lhs = environment.findLocalVarNode(node.getName(), sourceSection);

if (lhs == null) {
@@ -1317,6 +1320,30 @@ public RubyNode visitMatchNode(org.jruby.ast.MatchNode node) {

@Override
public RubyNode visitMatch2Node(org.jruby.ast.Match2Node node) {
if (node.getReceiverNode() instanceof org.jruby.ast.RegexpNode) {
final org.jruby.ast.RegexpNode regexpNode = (org.jruby.ast.RegexpNode) node.getReceiverNode();
final Regex regex = new Regex(regexpNode.getValue().bytes(), 0, regexpNode.getValue().length(), regexpNode.getOptions().toOptions(), regexpNode.getEncoding(), Syntax.RUBY);

if (regex.numberOfNames() > 0) {
for (Iterator<NameEntry> i = regex.namedBackrefIterator(); i.hasNext(); ) {
final NameEntry e = i.next();
final String name = new String(e.name, e.nameP, e.nameEnd - e.nameP).intern();

if (environment.hasOwnScopeForAssignments()) {
environment.declareVar(name);
} else {
TranslatorEnvironment environmentToDeclareIn = environment;

while (!environmentToDeclareIn.hasOwnScopeForAssignments()) {
environmentToDeclareIn = environmentToDeclareIn.getParent();
}

environmentToDeclareIn.declareVar(name);
}
}
}
}

final org.jruby.ast.Node argsNode = buildArrayNode(node.getPosition(), node.getValueNode());
final org.jruby.ast.Node callNode = new CallNode(node.getPosition(), node.getReceiverNode(), "=~", argsNode, null);
return callNode.accept(this);
1 change: 0 additions & 1 deletion spec/truffle/tags/language/match_tags.txt

This file was deleted.