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: 27c255257a11
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a804329678ed
Choose a head ref
  • 3 commits
  • 3 files changed
  • 1 contributor

Commits on Aug 7, 2016

  1. Copy the full SHA
    e6f783a View commit details
  2. Copy the full SHA
    019ff2e View commit details
  3. Copy the full SHA
    a804329 View commit details
Original file line number Diff line number Diff line change
@@ -66,11 +66,11 @@
import org.jruby.truffle.language.dispatch.CallDispatchHeadNode;
import org.jruby.truffle.language.dispatch.DispatchHeadNodeFactory;
import org.jruby.truffle.language.objects.AllocateObjectNode;
import org.jruby.truffle.language.objects.AllocateObjectNodeGen;
import org.jruby.truffle.util.StringUtils;
import org.jruby.util.ByteList;
import org.jruby.util.RegexpOptions;
import org.jruby.util.RegexpSupport;
import org.jruby.util.RegexpSupport.ErrorMode;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Iterator;
@@ -79,25 +79,29 @@
public abstract class RegexpNodes {

@TruffleBoundary
public static Matcher preprocess(RubyContext context, DynamicObject regexp, DynamicObject string) {
assert RubyGuards.isRubyRegexp(regexp);
assert RubyGuards.isRubyString(string);

public static Matcher createMatcher(RubyContext context, DynamicObject regexp, DynamicObject string) {
final Rope stringRope = StringOperations.rope(string);

final Rope regexpSourceRope = Layouts.REGEXP.getSource(regexp);
final Encoding enc = checkEncoding(regexp, stringRope, true);
final ByteList preprocessed = RegexpSupport.preprocess(context.getJRubyRuntime(), RopeOperations.getByteListReadOnly(regexpSourceRope), enc, new Encoding[] { null }, RegexpSupport.ErrorMode.RAISE);
Regex regex = Layouts.REGEXP.getRegex(regexp);

if (regex.getEncoding() != enc) {
final Encoding[] fixedEnc = new Encoding[] { null };
final ByteList sourceByteList = RopeOperations.getByteListReadOnly(Layouts.REGEXP.getSource(regexp));
final ByteList preprocessed = RegexpSupport.preprocess(context.getJRubyRuntime(), sourceByteList, enc, fixedEnc, ErrorMode.RAISE);
final RegexpOptions options = Layouts.REGEXP.getOptions(regexp);
final Encoding newEnc = checkEncoding(regexp, stringRope, true);
regex = new Regex(preprocessed.getUnsafeBytes(), preprocessed.getBegin(), preprocessed.getBegin() + preprocessed.getRealSize(),
options.toJoniOptions(), newEnc);
assert enc == newEnc;
}

final Regex regex = new Regex(preprocessed.getUnsafeBytes(), preprocessed.getBegin(), preprocessed.getBegin() + preprocessed.getRealSize(),
Layouts.REGEXP.getOptions(regexp).toJoniOptions(), checkEncoding(regexp, stringRope, true));
return regex.matcher(stringRope.getBytes(), 0, stringRope.byteLength());
}

@TruffleBoundary
public static Object matchCommon(RubyContext context, Node currentNode, RopeNodes.MakeSubstringNode makeSubstringNode, DynamicObject regexp, DynamicObject string, boolean operator,
boolean setNamedCaptures, int startPos) {
final Matcher matcher = preprocess(context, regexp, string);
final Matcher matcher = createMatcher(context, regexp, string);
int range = StringOperations.rope(string).byteLength();
return matchCommon(context, currentNode, makeSubstringNode, regexp, string, operator, setNamedCaptures, matcher, startPos, range);
}
@@ -257,21 +261,6 @@ public static Regex compile(Node currentNode, RubyContext context, Rope bytes, R
bytes = shimModifiers(bytes);

try {
/*
// This isn't quite right - we shouldn't be looking up by name, we need a real reference to this constants
if (node.getOptions().isEncodingNone()) {
if (!all7Bit(node.getValue().bytes())) {
regexp.getSource().setEncoding(ASCIIEncoding.INSTANCE);
} else {
regexp.getSource().setEncoding(USASCIIEncoding.INSTANCE);
}
} else if (node.getOptions().getKCode().getKCode().equals("SJIS")) {
regexp.getSource().setEncoding(Windows_31JEncoding.INSTANCE);
} else if (node.getOptions().getKCode().getKCode().equals("UTF8")) {
regexp.getSource().setEncoding(UTF8Encoding.INSTANCE);
}
*/

final ByteList byteList = RopeOperations.getByteListReadOnly(bytes);
Encoding enc = bytes.getEncoding();
Encoding[] fixedEnc = new Encoding[]{null};
@@ -292,10 +281,10 @@ public static Regex compile(Node currentNode, RubyContext context, Rope bytes, R
if (fixedEnc[0] != null) options.setFixed(true);
//if (regexpOptions.isEncodingNone()) setEncodingNone();

Regex ret = new Regex(unescaped.getUnsafeBytes(), unescaped.getBegin(), unescaped.getBegin() + unescaped.getRealSize(), options.toJoniOptions(), enc, Syntax.RUBY);
ret.setUserObject(RopeOperations.withEncodingVerySlow(bytes, enc));
Regex regexp = new Regex(unescaped.getUnsafeBytes(), unescaped.getBegin(), unescaped.getBegin() + unescaped.getRealSize(), options.toJoniOptions(), enc, Syntax.RUBY);
regexp.setUserObject(RopeOperations.withEncodingVerySlow(bytes, enc));

return ret;
return regexp;
} catch (ValueException e) {
throw new RaiseException(context.getCoreExceptions().runtimeError("error compiling regex", currentNode));
} catch (SyntaxException e) {
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@ private String formatError(DynamicObject string) {
@Specialization(guards = {"isInitialized(regexp)", "isRubyString(string)", "isValidEncoding(string)"})
public Object searchRegion(DynamicObject regexp, DynamicObject string, int start, int end, boolean forward,
@Cached("createX()") RopeNodes.MakeSubstringNode makeSubstringNode) {
final Matcher matcher = RegexpNodes.preprocess(getContext(), regexp, string);
final Matcher matcher = RegexpNodes.createMatcher(getContext(), regexp, string);

if (forward) {
// Search forward through the string.
Original file line number Diff line number Diff line change
@@ -169,6 +169,7 @@
import org.jruby.truffle.util.StringUtils;
import org.jruby.util.ByteList;
import org.jruby.util.KeyValuePair;
import org.jruby.util.RegexpOptions;
import java.io.File;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
@@ -2613,21 +2614,17 @@ public RubyNode visitRedoNode(org.jruby.ast.RedoNode node) {
@Override
public RubyNode visitRegexpNode(org.jruby.ast.RegexpNode node) {
final Rope rope = StringOperations.ropeFromByteList(node.getValue());
Regex regex = RegexpNodes.compile(currentNode, context, rope, node.getOptions());
final RegexpOptions options = node.getOptions();
options.setLiteral(true);
Regex regex = RegexpNodes.compile(currentNode, context, rope, options);

// The RegexpNodes.compile operation may modify the encoding of the source rope. This modified copy is stored
// in the Regex object as the "user object". Since ropes are immutable, we need to take this updated copy when
// constructing the final regexp.
final DynamicObject regexp = RegexpNodes.createRubyRegexp(context.getCoreLibrary().getRegexpFactory(), regex, (Rope) regex.getUserObject(), node.getOptions());
Layouts.REGEXP.getOptions(regexp).setLiteral(true);
final Rope updatedRope = (Rope) regex.getUserObject();
final DynamicObject regexp = RegexpNodes.createRubyRegexp(context.getCoreLibrary().getRegexpFactory(), regex, updatedRope, options);

final ObjectLiteralNode literalNode = new ObjectLiteralNode(context, translate(node.getPosition()), regexp);

if (node.getOptions().isOnce()) {
final RubyNode ret = new OnceNode(context, literalNode.getEncapsulatingSourceSection(), literalNode);
return addNewlineIfNeeded(node, ret);
}

return addNewlineIfNeeded(node, literalNode);
}