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

Commits on Jan 12, 2015

  1. [Truffle] Initial implementation of MatchData#begin.

    This currently only works on matches against single-byte encoded strings and MatchData instances with captures.
    nirvdrum committed Jan 12, 2015
    Copy the full SHA
    021ce5a View commit details
  2. [Truffle] Initial implementation of MatchData#end.

    This currently only works on matches against single-byte encoded strings and MatchData instances with captures.
    nirvdrum committed Jan 12, 2015
    Copy the full SHA
    bcbe444 View commit details
Original file line number Diff line number Diff line change
@@ -9,13 +9,15 @@
*/
package org.jruby.truffle.nodes.core;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;
import com.oracle.truffle.api.utilities.ConditionProfile;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyMatchData;
import org.jruby.truffle.runtime.core.RubyString;
import org.jruby.truffle.runtime.util.ArrayUtils;

@CoreClass(name = "MatchData")
public abstract class MatchDataNodes {
@@ -44,6 +46,36 @@ public Object getIndex(RubyMatchData matchData, int index) {

}

@CoreMethod(names = "begin", required = 1, lowerFixnumParameters = 1)
public abstract static class BeginNode extends CoreMethodNode {

private final ConditionProfile badIndexProfile = ConditionProfile.createBinaryProfile();

public BeginNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public BeginNode(BeginNode prev) {
super(prev);
}

@Specialization
public Object begin(RubyMatchData matchData, int index) {
notDesignedForCompilation();

if (badIndexProfile.profile((index < 0) || (index >= matchData.getNumberOfRegions()))) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().indexError(String.format("index %d out of matches", index), this));

} else {
return matchData.begin(index);
}
}
}


@CoreMethod(names = "captures")
public abstract static class CapturesNode extends CoreMethodNode {

@@ -63,6 +95,35 @@ public RubyArray toA(RubyMatchData matchData) {
}
}

@CoreMethod(names = "end", required = 1, lowerFixnumParameters = 1)
public abstract static class EndNode extends CoreMethodNode {

private final ConditionProfile badIndexProfile = ConditionProfile.createBinaryProfile();

public EndNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
}

public EndNode(EndNode prev) {
super(prev);
}

@Specialization
public Object end(RubyMatchData matchData, int index) {
notDesignedForCompilation();

if (badIndexProfile.profile((index < 0) || (index >= matchData.getNumberOfRegions()))) {
CompilerDirectives.transferToInterpreter();

throw new RaiseException(
getContext().getCoreLibrary().indexError(String.format("index %d out of matches", index), this));

} else {
return matchData.end(index);
}
}
}

@CoreMethod(names = "pre_match")
public abstract static class PreMatchNode extends CoreMethodNode {

Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
*/
package org.jruby.truffle.runtime.core;

import org.joni.Region;
import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.subsystems.ObjectSpaceManager;
import org.jruby.truffle.runtime.util.ArrayUtils;
@@ -18,13 +19,15 @@
*/
public class RubyMatchData extends RubyBasicObject {

private Region region;
private final Object[] values;
private final RubyString pre;
private final RubyString post;
private final RubyString global;

public RubyMatchData(RubyClass rubyClass, Object[] values, RubyString pre, RubyString post, RubyString global) {
public RubyMatchData(RubyClass rubyClass, Region region, Object[] values, RubyString pre, RubyString post, RubyString global) {
super(rubyClass);
this.region = region;
this.values = values;
this.pre = pre;
this.post = post;
@@ -53,6 +56,38 @@ public Object[] getCaptures() {
return ArrayUtils.extractRange(values, 1, values.length);
}

public Object begin(int index) {
if (region == null) {
throw new UnsupportedOperationException("begin is not yet working when no grouping data is available");
}

int begin = region.beg[index];

if (begin < 0) {
return getContext().getCoreLibrary().getNilObject();
}

return begin;
}

public Object end(int index) {
if (region == null) {
throw new UnsupportedOperationException("end is not yet working when no grouping data is available");
}

int end = region.end[index];

if (end < 0) {
return getContext().getCoreLibrary().getNilObject();
}

return end;
}

public int getNumberOfRegions() {
return region.numRegs;
}

@Override
public void visitObjectGraphChildren(ObjectSpaceManager.ObjectGraphVisitor visitor) {
for (Object object : values) {
Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ public Object matchCommon(ByteList bytes, boolean operator, boolean setNamedCapt
final RubyString post = new RubyString(context.getCoreLibrary().getStringClass(), bytes.makeShared(region.end[0], bytes.length() - region.end[0]).dup());
final RubyString global = new RubyString(context.getCoreLibrary().getStringClass(), bytes.makeShared(region.beg[0], region.end[0] - region.beg[0]).dup());

final RubyMatchData matchObject = new RubyMatchData(context.getCoreLibrary().getMatchDataClass(), values, pre, post, global);
final RubyMatchData matchObject = new RubyMatchData(context.getCoreLibrary().getMatchDataClass(), region, values, pre, post, global);

if (operator) {
if (values.length > 0) {
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/matchdata/begin_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:MatchData#begin returns the offset of the start of the nth element
fails:MatchData#begin returns nil when the nth match isn't found
fails:MatchData#begin returns the offset for multi byte strings
fails:MatchData#begin returns the offset for multi byte strings with unicode regexp
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/matchdata/end_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:MatchData#end returns the offset of the end of the nth element
fails:MatchData#end returns nil when the nth match isn't found
fails:MatchData#end returns the offset for multi byte strings
fails:MatchData#end returns the offset for multi byte strings with unicode regexp