Skip to content

Commit

Permalink
Showing 2 changed files with 30 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -78,29 +78,34 @@
public abstract class RegexpNodes {

@TruffleBoundary
public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNode makeSubstringNode, DynamicObject regexp, DynamicObject source, boolean operator, boolean setNamedCaptures, int startPos) {
public static Matcher preprocess(RubyContext context, DynamicObject regexp, DynamicObject string) {
assert RubyGuards.isRubyRegexp(regexp);
assert RubyGuards.isRubyString(source);
assert RubyGuards.isRubyString(string);

final Rope sourceRope = StringOperations.rope(source);
final Rope stringRope = StringOperations.rope(string);

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

final Regex r = new Regex(preprocessed.getUnsafeBytes(), preprocessed.getBegin(), preprocessed.getBegin() + preprocessed.getRealSize(), Layouts.REGEXP.getOptions(regexp).toJoniOptions(), checkEncoding(regexp, sourceRope, true));
final Matcher matcher = r.matcher(sourceRope.getBytes(), 0, sourceRope.byteLength());
int range = sourceRope.byteLength();
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());
}

return matchCommon(context, makeSubstringNode, regexp, source, operator, setNamedCaptures, matcher, startPos, range);
@TruffleBoundary
public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNode makeSubstringNode, DynamicObject regexp, DynamicObject string, boolean operator, boolean setNamedCaptures, int startPos) {
final Matcher matcher = preprocess(context, regexp, string);
int range = StringOperations.rope(string).byteLength();
return matchCommon(context, makeSubstringNode, regexp, string, operator, setNamedCaptures, matcher, startPos, range);
}

@TruffleBoundary
public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNode makeSubstringNode, DynamicObject regexp, DynamicObject source, boolean operator, boolean setNamedCaptures, Matcher matcher, int startPos, int range) {
public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNode makeSubstringNode, DynamicObject regexp, DynamicObject string, boolean operator, boolean setNamedCaptures, Matcher matcher, int startPos, int range) {
assert RubyGuards.isRubyRegexp(regexp);
assert RubyGuards.isRubyString(source);
assert RubyGuards.isRubyString(string);

final Rope sourceRope = StringOperations.rope(source);
final Rope sourceRope = StringOperations.rope(string);

final int match = matcher.search(startPos, range, Option.DEFAULT);

@@ -128,43 +133,21 @@ public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNod
final int start = region.beg[n];
final int end = region.end[n];

if (operator) {
final Object groupString;

if (start > -1 && end > -1) {
groupString = createSubstring(makeSubstringNode, source, start, end - start);
} else {
groupString = nil;
}

values[n] = groupString;
if (start > -1 && end > -1) {
values[n] = createSubstring(makeSubstringNode, string, start, end - start);
} else {
if (start == -1 || end == -1) {
values[n] = nil;
} else {
values[n] = createSubstring(makeSubstringNode, source, start, end - start);
}
values[n] = nil;
}
}

final DynamicObject pre = createSubstring(makeSubstringNode, source, 0, region.beg[0]);
final DynamicObject post = createSubstring(makeSubstringNode, source, region.end[0], sourceRope.byteLength() - region.end[0]);
final DynamicObject global = createSubstring(makeSubstringNode, source, region.beg[0], region.end[0] - region.beg[0]);
final DynamicObject pre = createSubstring(makeSubstringNode, string, 0, region.beg[0]);
final DynamicObject post = createSubstring(makeSubstringNode, string, region.end[0], sourceRope.byteLength() - region.end[0]);
final DynamicObject global = createSubstring(makeSubstringNode, string, region.beg[0], region.end[0] - region.beg[0]);

final DynamicObject matchObject = Layouts.MATCH_DATA.createMatchData(context.getCoreLibrary().getMatchDataFactory(),
source, regexp, region, values, pre, post, global, null);

if (operator) {
if (values.length > 0) {
int nonNil = values.length - 1;

while (values[nonNil] == nil) {
nonNil--;
}
}
}
final DynamicObject matchData = Layouts.MATCH_DATA.createMatchData(context.getCoreLibrary().getMatchDataFactory(),
string, regexp, region, values, pre, post, global, null);

RegexpSetLastMatchPrimitiveNode.setLastMatch(context, matchObject);
RegexpSetLastMatchPrimitiveNode.setLastMatch(context, matchData);

if (setNamedCaptures && Layouts.REGEXP.getRegex(regexp).numberOfNames() > 0) {
final Frame frame = context.getCallStack().getCallerFrameIgnoringSend().getFrame(FrameAccess.READ_WRITE, false);
@@ -183,7 +166,7 @@ public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNod
final int start = region.beg[nth];
final int end = region.end[nth];
if (start != -1) {
value = createSubstring(makeSubstringNode, source, start, end - start);
value = createSubstring(makeSubstringNode, string, start, end - start);
} else {
value = nil;
}
@@ -196,7 +179,7 @@ public static Object matchCommon(RubyContext context, RopeNodes.MakeSubstringNod
if (operator) {
return matcher.getBegin();
} else {
return matchObject;
return matchData;
}
}

Original file line number Diff line number Diff line change
@@ -14,23 +14,17 @@
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.object.DynamicObject;
import org.jcodings.Encoding;
import org.joni.Matcher;
import org.joni.Regex;
import org.jruby.truffle.Layouts;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.builtins.Primitive;
import org.jruby.truffle.builtins.PrimitiveArrayArgumentsNode;
import org.jruby.truffle.core.regexp.RegexpGuards;
import org.jruby.truffle.core.regexp.RegexpNodes;
import org.jruby.truffle.core.rope.Rope;
import org.jruby.truffle.core.rope.RopeNodes;
import org.jruby.truffle.core.rope.RopeOperations;
import org.jruby.truffle.core.string.StringOperations;
import org.jruby.truffle.language.control.RaiseException;
import org.jruby.truffle.util.StringUtils;
import org.jruby.util.ByteList;
import org.jruby.util.RegexpSupport;

/**
* Rubinius primitives associated with the Ruby {@code Regexp} class.
@@ -120,13 +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 Rope stringRope = StringOperations.rope(string);
final Rope regexpSourceRope = Layouts.REGEXP.getSource(regexp);
final Encoding enc = RegexpNodes.checkEncoding(regexp, stringRope, true);
ByteList preprocessed = RegexpSupport.preprocess(getContext().getJRubyRuntime(), RopeOperations.getByteListReadOnly(regexpSourceRope), enc, new Encoding[]{null}, RegexpSupport.ErrorMode.RAISE);
Rope preprocessedRope = RegexpNodes.shimModifiers(StringOperations.ropeFromByteList(preprocessed));
final Regex r = new Regex(preprocessedRope.getBytes(), 0, preprocessedRope.byteLength(), Layouts.REGEXP.getRegex(regexp).getOptions(), RegexpNodes.checkEncoding(regexp, stringRope, true));
final Matcher matcher = r.matcher(stringRope.getBytes(), 0, stringRope.byteLength());
final Matcher matcher = RegexpNodes.preprocess(getContext(), regexp, string);

if (forward) {
// Search forward through the string.
@@ -151,7 +139,8 @@ public Object setLastMatchData(DynamicObject regexpClass, Object matchData) {
@TruffleBoundary
public static void setLastMatch(RubyContext context, Object matchData) {
final DynamicObject threadLocals = Layouts.THREAD.getThreadLocals(context.getThreadManager().getCurrentThread());
threadLocals.set("$~", matchData);
boolean res = threadLocals.set("$~", matchData);
assert res;
}

}

0 comments on commit aea3d01

Please sign in to comment.