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

Commits on Mar 20, 2015

  1. Copy the full SHA
    4a6ed4b View commit details
  2. Tidy up semantics of matchdata out param in search/match.

    Previously the semantics were a bit of a mix; some consumers
    passed the out param *and* wanted the matchdata set into context,
    some did not want it set, and some did not pass an out param. The
    modified logic always uses *either* context.setBackref *or* the
    out param in all cases.
    
    Methods that use regexp match/search and need matchdata set now
    skip passing the out param, localizing backref setting for those
    methods back to where it should live.
    
    This also fixes matchPos to not require the IRubyObject[] out param
    if the caller is not interested in the coerced string.
    headius committed Mar 20, 2015
    Copy the full SHA
    0c9ebf6 View commit details
Showing with 48 additions and 70 deletions.
  1. +37 −45 core/src/main/java/org/jruby/RubyRegexp.java
  2. +10 −24 core/src/main/java/org/jruby/RubyString.java
  3. +1 −1 core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
82 changes: 37 additions & 45 deletions core/src/main/java/org/jruby/RubyRegexp.java
Original file line number Diff line number Diff line change
@@ -1384,9 +1384,7 @@ public IRubyObject op_match2_19(ThreadContext context) {
Ruby runtime = context.runtime;
IRubyObject line = context.getLastLine();
if (line instanceof RubyString) {
IRubyObject[] holder = {context.nil};
int start = search19(context, (RubyString)line, 0, false, holder);
context.setBackRef(holder[0]);
int start = search19(context, (RubyString)line, 0, false);
if (start < 0) return runtime.getNil();
return runtime.newFixnum(start);
}
@@ -1410,9 +1408,7 @@ public IRubyObject eqq19(ThreadContext context, IRubyObject arg) {
context.setBackRef(arg);
return runtime.getFalse();
}
IRubyObject[] holder = {context.nil};
int start = search19(context, (RubyString)arg, 0, false, holder);
context.setBackRef(holder[0]);
int start = search19(context, (RubyString)arg, 0, false);
return (start < 0) ? runtime.getFalse() : runtime.getTrue();
}

@@ -1426,10 +1422,10 @@ public IRubyObject op_match(ThreadContext context, IRubyObject arg) {
@Override
public IRubyObject op_match19(ThreadContext context, IRubyObject str) {
Ruby runtime = context.runtime;
IRubyObject[] holder = {str};
int pos = matchPos(context, holder, 0);
IRubyObject[] strp = {str};
int pos = matchPos(context, str, strp, null, 0);
if (pos < 0) return runtime.getNil();
pos = ((RubyString)holder[0]).subLength(pos);
pos = ((RubyString)strp[0]).subLength(pos);
return RubyFixnum.newFixnum(runtime, pos);
}

@@ -1459,30 +1455,36 @@ private IRubyObject match19Common(ThreadContext context, IRubyObject arg, int po
if (setBackref) context.setBackRef(arg);
return arg;
}
Ruby runtime = context.runtime;

RubyString _str = operandCheck(arg);
IRubyObject[] holder = {context.nil};
if (matchPos(context, holder, pos) < 0) {
if (setBackref) context.setBackRef(runtime.getNil());
return runtime.getNil();

IRubyObject[] holder = setBackref ? null : new IRubyObject[]{context.nil};
if (matchPos(context, _str, null, holder, pos) < 0) {
setBackref(context, holder, context.nil);
return context.nil;
}

IRubyObject backref = holder[0];
if (setBackref) context.setBackRef(backref);
IRubyObject backref = getBackref(context, holder);
if (block.isGiven()) return block.yield(context, backref);
return backref;
}

// MRI: reg_match_pos
private int matchPos(ThreadContext context, IRubyObject[] strp, int pos) {
IRubyObject _str = strp[0];
if (_str.isNil()) {
context.setBackRef(context.nil);
/**
* MRI: reg_match_pos
*
* @param context thread context
* @param stringlike the stringlike to match
* @param strp an out param to hold the coerced string; ignored if null
* @param holder an out param to hold the resulting match object; ignored if null
* @param pos the position from which to start matching
*/
private int matchPos(ThreadContext context, IRubyObject stringlike, IRubyObject[] strp, IRubyObject[] holder, int pos) {
if (stringlike.isNil()) {
setBackref(context, holder, context.nil);
return -1;
}
RubyString str;
strp[0] = str = operandCheck(_str);
RubyString str = operandCheck(stringlike);
if (strp != null) strp[0] = str;
if (pos != 0) {
if (pos < 0) {
int l = str.strLength();
@@ -1493,32 +1495,13 @@ private int matchPos(ThreadContext context, IRubyObject[] strp, int pos) {
}
pos = str.rbStrOffset(pos);
}
return search19(context, str, pos, false, null);
return search19(context, str, pos, false, holder);
}

/** rb_reg_search
*/
public final int search(ThreadContext context, RubyString str, int pos, boolean reverse, IRubyObject[] holder) {
check();
ByteList value = str.getByteList();

if (pos <= value.getRealSize() && pos >= 0) {
int realSize = value.getRealSize();
int begin = value.getBegin();
Matcher matcher = pattern.matcher(value.getUnsafeBytes(), begin, begin + realSize);

int result = matcherSearch(context.runtime, matcher, begin + pos, begin + (reverse ? 0 : realSize), Option.NONE);
if (result >= 0) {
RubyMatchData matchData = createMatchData(context, str, matcher, pattern);
matchData.regexp = this;
matchData.infectBy(this);
if (holder != null) holder[0] = matchData;
return result;
}
}

if (holder != null) holder[0] = context.nil;
return -1;
return search19(context, str, pos, reverse, holder);
}

static final RubyMatchData createMatchData(ThreadContext context, RubyString str, Matcher matcher, Regex pattern) {
@@ -1544,6 +1527,15 @@ static final RubyMatchData createMatchData(ThreadContext context, RubyString str
return match;
}

/**
* MRI: rb_reg_search
*
* This version uses current thread context to hold the resulting match data.
*/
public final int search19(ThreadContext context, RubyString str, int pos, boolean reverse) {
return search19(context, str, pos, reverse, true, null);
}

/**
* MRI: rb_reg_search
*
34 changes: 10 additions & 24 deletions core/src/main/java/org/jruby/RubyString.java
Original file line number Diff line number Diff line change
@@ -2652,9 +2652,7 @@ private IRubyObject indexCommon19(Ruby runtime, ThreadContext context, IRubyObje
value.getBegin() + value.getRealSize(),
pos) - value.getBegin();
pos = regSub.adjustStartPos19(this, pos, false);
IRubyObject[] holder = {context.nil};
pos = regSub.search19(context, this, pos, false, holder);
context.setBackRef(holder[0]);
pos = regSub.search19(context, this, pos, false);
pos = subLength(pos);
} else if (sub instanceof RubyString) {
pos = StringSupport.index(this, (RubyString) sub, pos, this.checkEncoding((RubyString) sub));
@@ -2710,9 +2708,7 @@ private IRubyObject rindexCommon19(Ruby runtime, ThreadContext context, final IR
pos) - value.getBegin();
if (regSub.length() > 0) {
pos = regSub.adjustStartPos19(this, pos, true);
IRubyObject[] holder = {context.nil};
pos = regSub.search19(context, this, pos, true, holder);
context.setBackRef(holder[0]);
pos = regSub.search19(context, this, pos, true);
pos = subLength(pos);
}
} else if (sub instanceof RubyString) {
@@ -2958,15 +2954,13 @@ private int subpatSetCheck(Ruby runtime, int nth, Region regs) {

private void subpatSet19(ThreadContext context, RubyRegexp regexp, IRubyObject backref, IRubyObject repl) {
Ruby runtime = context.runtime;
IRubyObject[] holder = {context.nil};

int result = regexp.search19(context, this, 0, false, holder);
context.setBackRef(holder[0]);
int result = regexp.search19(context, this, 0, false);

if (result < 0) throw runtime.newIndexError("regexp not matched");

// this cast should be ok, since nil matchdata will be < 0 above
RubyMatchData match = (RubyMatchData)holder[0];
RubyMatchData match = (RubyMatchData)context.getBackRef();

int nth = backref == null ? 0 : subpatSetCheck(runtime, match.backrefNumber(backref), match.regs);

@@ -2987,13 +2981,10 @@ private void subpatSet19(ThreadContext context, RubyRegexp regexp, IRubyObject b
}

private IRubyObject subpat19(Ruby runtime, ThreadContext context, RubyRegexp regex, IRubyObject backref) {
IRubyObject[] holder = {context.nil};

int result = regex.search19(context, this, 0, false, holder);
context.setBackRef(holder[0]);
int result = regex.search19(context, this, 0, false);

if (result >= 0) {
RubyMatchData match = (RubyMatchData)holder[0];
RubyMatchData match = (RubyMatchData)context.getBackRef();
return RubyRegexp.nth_match(match.backrefNumber(backref), match);
}

@@ -3003,8 +2994,7 @@ private IRubyObject subpat19(Ruby runtime, ThreadContext context, RubyRegexp reg
private IRubyObject subpat19(Ruby runtime, ThreadContext context, RubyRegexp regex) {
IRubyObject[] holder = {context.nil};

int result = regex.search19(context, this, 0, false, holder);
context.setBackRef(holder[0]);
int result = regex.search19(context, this, 0, false);

if (result >= 0) {
return RubyRegexp.nth_match(0, holder[0]);
@@ -4024,10 +4014,8 @@ public IRubyObject partition(ThreadContext context, IRubyObject arg, Block block
final RubyString sep;
if (arg instanceof RubyRegexp) {
RubyRegexp regex = (RubyRegexp)arg;
IRubyObject[] holder = {context.nil};

pos = regex.search19(context, this, 0, false, holder);
context.setBackRef(holder[0]);
pos = regex.search19(context, this, 0, false);
if (pos < 0) return partitionMismatch(runtime);
sep = (RubyString)subpat19(runtime, context, regex);
if (pos == 0 && sep.value.getRealSize() == 0) return partitionMismatch(runtime);
@@ -4056,13 +4044,11 @@ public IRubyObject rpartition(ThreadContext context, IRubyObject arg) {
final RubyString sep;
if (arg instanceof RubyRegexp) {
RubyRegexp regex = (RubyRegexp)arg;
IRubyObject[] holder = {context.nil};

pos = regex.search19(context, this, value.getRealSize(), true, holder);
context.setBackRef(holder[0]);
pos = regex.search19(context, this, value.getRealSize(), true);

if (pos < 0) return rpartitionMismatch(runtime);
sep = (RubyString)RubyRegexp.nth_match(0, holder[0]);
sep = (RubyString)RubyRegexp.nth_match(0, context.getBackRef());
} else {
IRubyObject tmp = arg.checkStringType();
if (tmp.isNil()) throw runtime.newTypeError("type mismatch: " + arg.getMetaClass().getName() + " given");
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
Original file line number Diff line number Diff line change
@@ -635,7 +635,7 @@ public boolean isASCII(int c) {
* @return whether c is an multibyte char or not
*/
protected boolean isMultiByteChar(int c) {
return encoding.codeToMbcLength(c) != 1;
return encoding.length((byte)c) > 1;
}

// STR_NEW3/parser_str_new