8012359: Increase code coverage in Joni

Reviewed-by: jlaskey, lagergren
This commit is contained in:
Hannes Wallnöfer 2013-05-16 19:52:39 +02:00
parent aeda283b75
commit 2c97733af0
48 changed files with 531 additions and 3953 deletions

View File

@ -305,6 +305,8 @@
<include name="**/codegen/*Test.class"/>
<include name="**/parser/*Test.class"/>
<include name="**/runtime/*Test.class"/>
<include name="**/runtime/regexp/*Test.class"/>
<include name="**/runtime/regexp/joni/*Test.class"/>
<include name="**/framework/*Test.class"/>
</fileset>

View File

@ -41,7 +41,7 @@ import java.util.regex.PatternSyntaxException;
* Note that this class is not thread-safe as it stores the current match result
* and the string being matched in instance fields.
*/
public class DefaultRegExp extends RegExp {
public class JdkRegExp extends RegExp {
/** Java regexp pattern to use for match. We compile to one of these */
private Pattern pattern;
@ -56,7 +56,7 @@ public class DefaultRegExp extends RegExp {
* @param flags RegExp flag string
* @throws ParserException if flags is invalid or source string has syntax error.
*/
public DefaultRegExp(final String source, final String flags) throws ParserException {
public JdkRegExp(final String source, final String flags) throws ParserException {
super(source, flags);
int intFlags = 0;

View File

@ -113,7 +113,7 @@ public class JoniRegExp extends RegExp {
public static class Factory extends RegExpFactory {
@Override
protected RegExp compile(final String pattern, final String flags) throws ParserException {
public RegExp compile(final String pattern, final String flags) throws ParserException {
return new JoniRegExp(pattern, flags);
}

View File

@ -29,7 +29,7 @@ import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.options.Options;
/**
* Factory class for regular expressions. This class creates instances of {@link DefaultRegExp}.
* Factory class for regular expressions. This class creates instances of {@link JdkRegExp}.
* An alternative factory can be installed using the {@code nashorn.regexp.impl} system property.
*/
public class RegExpFactory {
@ -62,8 +62,8 @@ public class RegExpFactory {
* @return new RegExp
* @throws ParserException if flags is invalid or pattern string has syntax error.
*/
protected RegExp compile(final String pattern, final String flags) throws ParserException {
return new DefaultRegExp(pattern, flags);
public RegExp compile(final String pattern, final String flags) throws ParserException {
return new JdkRegExp(pattern, flags);
}
/**

View File

@ -21,10 +21,7 @@ package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAll;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAt;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
@ -36,8 +33,6 @@ import java.util.HashSet;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@ -49,9 +44,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
final class Analyser extends Parser {
@ -74,38 +67,9 @@ final class Analyser extends Parser {
//regex.repeatRangeAlloc = 0;
regex.repeatRangeLo = null;
regex.repeatRangeHi = null;
regex.numCombExpCheck = 0;
if (Config.USE_COMBINATION_EXPLOSION_CHECK) regex.numCombExpCheck = 0;
parse();
if (Config.USE_NAMED_GROUP) {
/* mixed use named group and no-named group */
if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(regex.options)) {
if (env.numNamed != env.numMem) {
root = disableNoNameGroupCapture(root);
} else {
numberedRefCheck(root);
}
}
} // USE_NAMED_GROUP
if (Config.USE_NAMED_GROUP) {
if (env.numCall > 0) {
env.unsetAddrList = new UnsetAddrList(env.numCall);
setupSubExpCall(root);
// r != 0 ???
subexpRecursiveCheckTrav(root);
// r < 0 -< err, FOUND_CALLED_NODE = 1
subexpInfRecursiveCheckTrav(root);
// r != 0 recursion infinite ???
regex.numCall = env.numCall;
} else {
regex.numCall = 0;
}
} // USE_NAMED_GROUP
if (Config.DEBUG_PARSE_TREE_RAW && Config.DEBUG_PARSE_TREE) {
Config.log.println("<RAW TREE>");
Config.log.println(root + "\n");
@ -129,27 +93,6 @@ final class Analyser extends Parser {
regex.btMemEnd |= regex.captureHistory;
}
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
setupCombExpCheck(root, 0);
if (Config.USE_SUBEXP_CALL && env.hasRecursion) {
env.numCombExpCheck = 0;
} else { // USE_SUBEXP_CALL
if (env.combExpMaxRegNum > 0) {
for (int i=1; i<env.combExpMaxRegNum; i++) {
if (bsAt(env.backrefedMem, i)) {
env.numCombExpCheck = 0;
break;
}
}
}
}
} // USE_SUBEXP_CALL
regex.numCombExpCheck = env.numCombExpCheck;
} // USE_COMBINATION_EXPLOSION_CHECK
regex.clearOptimizeInfo();
if (!Config.DONT_OPTIMIZE) setOptimizedInfoFromTree(root);
@ -167,7 +110,6 @@ final class Analyser extends Parser {
}
if (Config.DEBUG_COMPILE) {
if (Config.USE_NAMED_GROUP) Config.log.print(regex.nameTableToString());
Config.log.println("stack used: " + regex.stackNeeded);
if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
@ -177,157 +119,6 @@ final class Analyser extends Parser {
regex.state = RegexState.NORMAL;
}
private void noNameDisableMapFor_cosAlt(Node node, int[]map, Ptr counter) {
ConsAltNode can = (ConsAltNode)node;
do {
can.setCar(noNameDisableMap(can.car, map, counter));
} while ((can = can.cdr) != null);
}
private void noNameDisableMapFor_quantifier(Node node, int[]map, Ptr counter) {
QuantifierNode qn = (QuantifierNode)node;
Node target = qn.target;
Node old = target;
target = noNameDisableMap(target, map, counter);
if (target != old) {
qn.setTarget(target);
if (target.getType() == NodeType.QTFR) qn.reduceNestedQuantifier((QuantifierNode)target);
}
}
private Node noNameDisableMapFor_enclose(Node node, int[]map, Ptr counter) {
EncloseNode en = (EncloseNode)node;
if (en.type == EncloseType.MEMORY) {
if (en.isNamedGroup()) {
counter.p++;
map[en.regNum] = counter.p;
en.regNum = counter.p;
//en.target = noNameDisableMap(en.target, map, counter);
en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
} else {
node = en.target;
en.target = null; // remove first enclose: /(a)(?<b>c)/
node = noNameDisableMap(node, map, counter);
}
} else {
//en.target = noNameDisableMap(en.target, map, counter);
en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
}
return node;
}
private void noNameDisableMapFor_anchor(Node node, int[]map, Ptr counter) {
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorNode.PREC_READ:
case AnchorNode.PREC_READ_NOT:
case AnchorNode.LOOK_BEHIND:
case AnchorNode.LOOK_BEHIND_NOT:
an.setTarget(noNameDisableMap(an.target, map, counter));
}
}
private Node noNameDisableMap(Node node, int[]map, Ptr counter) {
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
noNameDisableMapFor_cosAlt(node, map, counter);
break;
case NodeType.QTFR:
noNameDisableMapFor_quantifier(node, map, counter);
break;
case NodeType.ENCLOSE:
node = noNameDisableMapFor_enclose(node, map, counter);
break;
case NodeType.ANCHOR:
noNameDisableMapFor_anchor(node, map, counter);
break;
} // switch
return node;
}
private void renumberByMap(Node node, int[]map) {
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
renumberByMap(can.car, map);
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
renumberByMap(((QuantifierNode)node).target, map);
break;
case NodeType.ENCLOSE:
renumberByMap(((EncloseNode)node).target, map);
break;
case NodeType.BREF:
((BackRefNode)node).renumber(map);
break;
} // switch
}
protected final void numberedRefCheck(Node node) {
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
numberedRefCheck(can.car);
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
numberedRefCheck(((QuantifierNode)node).target);
break;
case NodeType.ENCLOSE:
numberedRefCheck(((EncloseNode)node).target);
break;
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
if (!br.isNameRef()) newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
break;
} // switch
}
protected final Node disableNoNameGroupCapture(Node root) {
int[]map = new int[env.numMem + 1];
for (int i=1; i<=env.numMem; i++) map[i] = 0;
root = noNameDisableMap(root, map, new Ptr(0));
renumberByMap(root, map);
for (int i=1, pos=1; i<=env.numMem; i++) {
if (map[i] > 0) {
env.memNodes[pos] = env.memNodes[i];
pos++;
}
}
int loc = env.captureHistory;
env.captureHistory = bsClear();
for (int i=1; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
if (bsAt(loc, i)) {
env.captureHistory = bsOnAtSimple(env.captureHistory, map[i]);
}
}
env.numMem = env.numNamed;
regex.numMem = env.numNamed;
regex.renumberNameTable(map);
return root;
}
private void swap(Node a, Node b) {
a.swap(b);
@ -352,17 +143,6 @@ final class Analyser extends Parser {
} while ((can = can.cdr) != null);
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (cn.isRecursion()) {
return TargetInfo.IS_EMPTY_REC; /* tiny version */
} else {
info = quantifiersMemoryInfo(cn.target);
}
} // USE_SUBEXP_CALL
break;
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
@ -417,18 +197,6 @@ final class Analyser extends Parser {
}
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (cn.isRecursion()) {
EncloseNode en = (EncloseNode)cn.target;
if (en.isMinFixed()) min = en.minLength;
} else {
min = getMinMatchLength(cn.target);
}
} // USE_SUBEXP_CALL
break;
case NodeType.LIST:
ConsAltNode can = (ConsAltNode)node;
do {
@ -474,15 +242,13 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch (en.type) {
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL) {
if (en.isMinFixed()) {
min = en.minLength;
} else {
min = getMinMatchLength(en.target);
en.minLength = min;
en.setMinFixed();
}
} // USE_SUBEXP_CALL
if (en.isMinFixed()) {
min = en.minLength;
} else {
min = getMinMatchLength(en.target);
en.minLength = min;
en.setMinFixed();
}
break;
case EncloseType.OPTION:
@ -547,17 +313,6 @@ final class Analyser extends Parser {
}
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (!cn.isRecursion()) {
max = getMaxMatchLength(cn.target);
} else {
max = MinMaxLen.INFINITE_DISTANCE;
}
} // USE_SUBEXP_CALL
break;
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
@ -576,15 +331,13 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch (en.type) {
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL) {
if (en.isMaxFixed()) {
max = en.maxLength;
} else {
max = getMaxMatchLength(en.target);
en.maxLength = max;
en.setMaxFixed();
}
} // USE_SUBEXP_CALL
if (en.isMaxFixed()) {
max = en.maxLength;
} else {
max = getMaxMatchLength(en.target);
en.maxLength = max;
en.setMaxFixed();
}
break;
case EncloseType.OPTION:
@ -663,17 +416,6 @@ final class Analyser extends Parser {
}
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (!cn.isRecursion()) {
len = getCharLengthTree(cn.target, level);
} else {
returnCode = GET_CHAR_LEN_VARLEN;
}
} // USE_SUBEXP_CALL
break;
case NodeType.CTYPE:
len = 1;
@ -686,17 +428,15 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch(en.type) {
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL) {
if (en.isCLenFixed()) {
len = en.charLength;
} else {
len = getCharLengthTree(en.target, level);
if (returnCode == 0) {
en.charLength = len;
en.setCLenFixed();
}
if (en.isCLenFixed()) {
len = en.charLength;
} else {
len = getCharLengthTree(en.target, level);
if (returnCode == 0) {
en.charLength = len;
en.setCLenFixed();
}
} // USE_SUBEXP_CALL
}
break;
case EncloseType.OPTION:
@ -727,10 +467,6 @@ final class Analyser extends Parser {
switch(x.getType()) {
case NodeType.CTYPE:
switch(yType) {
case NodeType.CTYPE:
CTypeNode cny = (CTypeNode)y;
CTypeNode cnx = (CTypeNode)x;
return cny.ctype == cnx.ctype && cny.not != cnx.not;
case NodeType.CCLASS:
// !swap:!
@ -756,37 +492,6 @@ final class Analyser extends Parser {
CClassNode xc = (CClassNode)x;
switch(yType) {
case NodeType.CTYPE:
switch(((CTypeNode)y).ctype) {
case CharacterType.WORD:
if (!((CTypeNode)y).not) {
if (xc.mbuf == null && !xc.isNot()) {
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (xc.bs.at(i)) {
if (EncodingHelper.isWord(i)) return false;
}
}
return true;
}
return false;
} else {
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (!EncodingHelper.isWord(i)) {
if (!xc.isNot()) {
if (xc.bs.at(i)) return false;
} else {
if (!xc.bs.at(i)) return false;
}
}
}
return true;
}
// break; not reached
default:
break;
} // inner switch
break;
case NodeType.CCLASS:
CClassNode yc = (CClassNode)y;
@ -820,17 +525,6 @@ final class Analyser extends Parser {
if (xs.length() == 0) break;
switch (yType) {
case NodeType.CTYPE:
CTypeNode cy = ((CTypeNode)y);
switch (cy.ctype) {
case CharacterType.WORD:
return !cy.not;
default:
break;
} // inner switch
break;
case NodeType.CCLASS:
CClassNode cc = (CClassNode)y;
@ -873,9 +567,6 @@ final class Analyser extends Parser {
case NodeType.CANY:
break;
case NodeType.CALL:
break; // if (Config.USE_SUBEXP_CALL)
case NodeType.CTYPE:
case NodeType.CCLASS:
if (!exact) n = node;
@ -977,316 +668,6 @@ final class Analyser extends Parser {
return invalid;
}
private static final int RECURSION_EXIST = 1;
private static final int RECURSION_INFINITE = 2;
private int subexpInfRecursiveCheck(Node node, boolean head) {
int r = 0;
switch (node.getType()) {
case NodeType.LIST:
int min;
ConsAltNode x = (ConsAltNode)node;
do {
int ret = subexpInfRecursiveCheck(x.car, head);
if (ret == RECURSION_INFINITE) return ret;
r |= ret;
if (head) {
min = getMinMatchLength(x.car);
if (min != 0) head = false;
}
} while ((x = x.cdr) != null);
break;
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
r = RECURSION_EXIST;
do {
int ret = subexpInfRecursiveCheck(can.car, head);
if (ret == RECURSION_INFINITE) return ret;
r &= ret;
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
r = subexpInfRecursiveCheck(qn.target, head);
if (r == RECURSION_EXIST) {
if (qn.lower == 0) r = 0;
}
break;
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
case AnchorType.PREC_READ_NOT:
case AnchorType.LOOK_BEHIND:
case AnchorType.LOOK_BEHIND_NOT:
r = subexpInfRecursiveCheck(an.target, head);
break;
} // inner switch
break;
case NodeType.CALL:
r = subexpInfRecursiveCheck(((CallNode)node).target, head);
break;
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isMark2()) {
return 0;
} else if (en.isMark1()) {
return !head ? RECURSION_EXIST : RECURSION_INFINITE;
// throw exception here ???
} else {
en.setMark2();
r = subexpInfRecursiveCheck(en.target, head);
en.clearMark2();
}
break;
default:
break;
} // switch
return r;
}
protected final int subexpInfRecursiveCheckTrav(Node node) {
int r = 0;
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
r = subexpInfRecursiveCheckTrav(can.car);
} while (r == 0 && (can = can.cdr) != null);
break;
case NodeType.QTFR:
r = subexpInfRecursiveCheckTrav(((QuantifierNode)node).target);
break;
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
case AnchorType.PREC_READ_NOT:
case AnchorType.LOOK_BEHIND:
case AnchorType.LOOK_BEHIND_NOT:
r = subexpInfRecursiveCheckTrav(an.target);
break;
} // inner switch
break;
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isRecursion()) {
en.setMark1();
r = subexpInfRecursiveCheck(en.target, true);
if (r > 0) newValueException(ERR_NEVER_ENDING_RECURSION);
en.clearMark1();
}
r = subexpInfRecursiveCheckTrav(en.target);
break;
default:
break;
} // switch
return r;
}
private int subexpRecursiveCheck(Node node) {
int r = 0;
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
r |= subexpRecursiveCheck(can.car);
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
r = subexpRecursiveCheck(((QuantifierNode)node).target);
break;
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
case AnchorType.PREC_READ_NOT:
case AnchorType.LOOK_BEHIND:
case AnchorType.LOOK_BEHIND_NOT:
r = subexpRecursiveCheck(an.target);
break;
} // inner switch
break;
case NodeType.CALL:
CallNode cn = (CallNode)node;
r = subexpRecursiveCheck(cn.target);
if (r != 0) cn.setRecursion();
break;
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (en.isMark2()) {
return 0;
} else if (en.isMark1()) {
return 1; /* recursion */
} else {
en.setMark2();
r = subexpRecursiveCheck(en.target);
en.clearMark2();
}
break;
default:
break;
} // switch
return r;
}
private static final int FOUND_CALLED_NODE = 1;
protected final int subexpRecursiveCheckTrav(Node node) {
int r = 0;
switch (node.getType()) {
case NodeType.LIST:
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
int ret = subexpRecursiveCheckTrav(can.car);
if (ret == FOUND_CALLED_NODE) {
r = FOUND_CALLED_NODE;
}
// else if (ret < 0) return ret; ???
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
r = subexpRecursiveCheckTrav(qn.target);
if (qn.upper == 0) {
if (r == FOUND_CALLED_NODE) qn.isRefered = true;
}
break;
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
case AnchorType.PREC_READ_NOT:
case AnchorType.LOOK_BEHIND:
case AnchorType.LOOK_BEHIND_NOT:
r = subexpRecursiveCheckTrav(an.target);
break;
} // inner switch
break;
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
if (!en.isRecursion()) {
if (en.isCalled()) {
en.setMark1();
r = subexpRecursiveCheck(en.target);
if (r != 0) en.setRecursion();
en.clearMark1();
}
}
r = subexpRecursiveCheckTrav(en.target);
if (en.isCalled()) r |= FOUND_CALLED_NODE;
break;
default:
break;
} // switch
return r;
}
private void setCallAttr(CallNode cn) {
cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
((EncloseNode)cn.target).setCalled();
env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
cn.unsetAddrList = env.unsetAddrList;
}
protected final void setupSubExpCall(Node node) {
switch(node.getType()) {
case NodeType.LIST:
ConsAltNode ln = (ConsAltNode)node;
do {
setupSubExpCall(ln.car);
} while ((ln = ln.cdr) != null);
break;
case NodeType.ALT:
ConsAltNode can = (ConsAltNode)node;
do {
setupSubExpCall(can.car);
} while ((can = can.cdr) != null);
break;
case NodeType.QTFR:
setupSubExpCall(((QuantifierNode)node).target);
break;
case NodeType.ENCLOSE:
setupSubExpCall(((EncloseNode)node).target);
break;
case NodeType.CALL:
CallNode cn = (CallNode)node;
if (cn.groupNum != 0) {
int gNum = cn.groupNum;
if (Config.USE_NAMED_GROUP) {
if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(env.option)) {
newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
}
} // USE_NAMED_GROUP
if (gNum > env.numMem) newValueException(ERR_UNDEFINED_GROUP_REFERENCE, cn.nameP, cn.nameEnd);
setCallAttr(cn);
} else {
if (Config.USE_NAMED_GROUP) {
NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
if (ne == null) {
newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
} else if (ne.backNum > 1) {
newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
} else {
cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
setCallAttr(cn);
}
}
}
break;
case NodeType.ANCHOR:
AnchorNode an = (AnchorNode)node;
switch (an.type) {
case AnchorType.PREC_READ:
case AnchorType.PREC_READ_NOT:
case AnchorType.LOOK_BEHIND:
case AnchorType.LOOK_BEHIND_NOT:
setupSubExpCall(an.target);
break;
}
break;
} // switch
}
/* divide different length alternatives in look-behind.
(?<=A|B) ==> (?<=A)|(?<=B)
(?<!A|B) ==> (?<!A)(?<!B)
@ -1523,125 +904,6 @@ final class Analyser extends Parser {
return xnode;
}
private static final int CEC_THRES_NUM_BIG_REPEAT = 512;
private static final int CEC_INFINITE_NUM = 0x7fffffff;
private static final int CEC_IN_INFINITE_REPEAT = (1<<0);
private static final int CEC_IN_FINITE_REPEAT = (1<<1);
private static final int CEC_CONT_BIG_REPEAT = (1<<2);
protected final int setupCombExpCheck(Node node, int state) {
int r = state;
int ret;
switch (node.getType()) {
case NodeType.LIST:
ConsAltNode ln = (ConsAltNode)node;
do {
r = setupCombExpCheck(ln.car, r);
//prev = ((ConsAltNode)node).car;
} while (r >= 0 && (ln = ln.cdr) != null);
break;
case NodeType.ALT:
ConsAltNode an = (ConsAltNode)node;
do {
ret = setupCombExpCheck(an.car, state);
r |= ret;
} while (ret >= 0 && (an = an.cdr) != null);
break;
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
int childState = state;
int addState = 0;
int varNum;
if (!isRepeatInfinite(qn.upper)) {
if (qn.upper > 1) {
/* {0,1}, {1,1} are allowed */
childState |= CEC_IN_FINITE_REPEAT;
/* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
if (env.backrefedMem == 0) {
if (qn.target.getType() == NodeType.ENCLOSE) {
EncloseNode en = (EncloseNode)qn.target;
if (en.type == EncloseType.MEMORY) {
if (en.target.getType() == NodeType.QTFR) {
QuantifierNode q = (QuantifierNode)en.target;
if (isRepeatInfinite(q.upper) && q.greedy == qn.greedy) {
qn.upper = qn.lower == 0 ? 1 : qn.lower;
if (qn.upper == 1) childState = state;
}
}
}
}
}
}
}
if ((state & CEC_IN_FINITE_REPEAT) != 0) {
qn.combExpCheckNum = -1;
} else {
if (isRepeatInfinite(qn.upper)) {
varNum = CEC_INFINITE_NUM;
childState |= CEC_IN_INFINITE_REPEAT;
} else {
varNum = qn.upper - qn.lower;
}
if (varNum >= CEC_THRES_NUM_BIG_REPEAT) addState |= CEC_CONT_BIG_REPEAT;
if (((state & CEC_IN_INFINITE_REPEAT) != 0 && varNum != 0) ||
((state & CEC_CONT_BIG_REPEAT) != 0 && varNum >= CEC_THRES_NUM_BIG_REPEAT)) {
if (qn.combExpCheckNum == 0) {
env.numCombExpCheck++;
qn.combExpCheckNum = env.numCombExpCheck;
if (env.currMaxRegNum > env.combExpMaxRegNum) {
env.combExpMaxRegNum = env.currMaxRegNum;
}
}
}
}
r = setupCombExpCheck(qn.target, childState);
r |= addState;
break;
case NodeType.ENCLOSE:
EncloseNode en = (EncloseNode)node;
switch( en.type) {
case EncloseNode.MEMORY:
if (env.currMaxRegNum < en.regNum) {
env.currMaxRegNum = en.regNum;
}
r = setupCombExpCheck(en.target, state);
break;
default:
r = setupCombExpCheck(en.target, state);
} // inner switch
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (cn.isRecursion()) {
env.hasRecursion = true;
} else {
r = setupCombExpCheck(cn.target, state);
}
} // USE_SUBEXP_CALL
break;
default:
break;
} // switch
return r;
}
private static final int IN_ALT = (1<<0);
private static final int IN_NOT = (1<<1);
private static final int IN_REPEAT = (1<<2);
@ -1691,20 +953,12 @@ final class Analyser extends Parser {
case NodeType.CANY:
break;
case NodeType.CALL: // if (Config.USE_SUBEXP_CALL) ?
break;
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
for (int i=0; i<br.backNum; i++) {
if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
if (Config.USE_BACKREF_WITH_LEVEL) {
if (br.isNestLevel()) {
env.btMemEnd = bsOnAt(env.btMemEnd, br.back[i]);
}
} // USE_BACKREF_AT_LEVEL
((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
}
break;
@ -1916,37 +1170,6 @@ final class Analyser extends Parser {
break;
}
case NodeType.CTYPE: {
int min;
int max = 1;
if (max == 1) {
min = 1;
CTypeNode cn = (CTypeNode)node;
switch (cn.ctype) {
case CharacterType.WORD:
if (cn.not) {
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (!EncodingHelper.isWord(i)) {
opt.map.addChar(i);
}
}
} else {
for (int i=0; i<BitSet.SINGLE_BYTE_SIZE; i++) {
if (EncodingHelper.isWord(i)) {
opt.map.addChar(i);
}
}
}
break;
} // inner switch
} else {
min = 1;
}
opt.length.set(min, max);
break;
}
case NodeType.CANY: {
opt.length.set(1, 1);
break;
@ -2008,20 +1231,6 @@ final class Analyser extends Parser {
break;
}
case NodeType.CALL: {
if (Config.USE_SUBEXP_CALL) {
CallNode cn = (CallNode)node;
if (cn.isRecursion()) {
opt.length.set(0, MinMaxLen.INFINITE_DISTANCE);
} else {
int safe = oenv.options;
oenv.options = ((EncloseNode)cn.target).option;
optimizeNodeLeft(cn.target, opt, oenv);
oenv.options = safe;
}
} // USE_SUBEXP_CALL
break;
}
case NodeType.QTFR: {
NodeOptInfo nopt = new NodeOptInfo();
@ -2081,7 +1290,7 @@ final class Analyser extends Parser {
break;
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL && ++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
if (++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
int min = 0;
int max = MinMaxLen.INFINITE_DISTANCE;
if (en.isMinFixed()) min = en.minLength;

View File

@ -28,8 +28,6 @@ import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepe
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@ -71,11 +69,6 @@ final class ArrayCompiler extends Compiler {
regex.templates = templates;
regex.templateNum = templateNum;
regex.factory = MatcherFactory.DEFAULT;
if (Config.USE_SUBEXP_CALL && analyser.env.unsetAddrList != null) {
analyser.env.unsetAddrList.fix(regex);
analyser.env.unsetAddrList = null;
}
}
@Override
@ -119,7 +112,7 @@ final class ArrayCompiler extends Compiler {
return isNeedStrLenOpExact(op);
}
private int selectStrOpcode(int mbLength, int strLength, boolean ignoreCase) {
private int selectStrOpcode(int strLength, boolean ignoreCase) {
int op;
if (ignoreCase) {
@ -128,31 +121,14 @@ final class ArrayCompiler extends Compiler {
default:op = OPCode.EXACTN_IC; break;
} // switch
} else {
switch (mbLength) {
case 1:
switch (strLength) {
case 1: op = OPCode.EXACT1; break;
case 2: op = OPCode.EXACT2; break;
case 3: op = OPCode.EXACT3; break;
case 4: op = OPCode.EXACT4; break;
case 5: op = OPCode.EXACT5; break;
default:op = OPCode.EXACTN; break;
} // inner switch
break;
case 2:
switch (strLength) {
case 1: op = OPCode.EXACTMB2N1; break;
case 2: op = OPCode.EXACTMB2N2; break;
case 3: op = OPCode.EXACTMB2N3; break;
default:op = OPCode.EXACTMB2N; break;
} // inner switch
break;
case 3:
op = OPCode.EXACTMB3N;
break;
default:
op = OPCode.EXACTMBN;
} // switch
switch (strLength) {
case 1: op = OPCode.EXACT1; break;
case 2: op = OPCode.EXACT2; break;
case 3: op = OPCode.EXACT3; break;
case 4: op = OPCode.EXACT4; break;
case 5: op = OPCode.EXACT5; break;
default:op = OPCode.EXACTN; break;
} // inner switch
}
return op;
}
@ -185,8 +161,8 @@ final class ArrayCompiler extends Compiler {
}
}
private int addCompileStringlength(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(mbLength, strLength, ignoreCase);
private int addCompileStringlength(char[] chars, int p, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(strLength, ignoreCase);
int len = OPSize.OPCODE;
if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
@ -194,25 +170,21 @@ final class ArrayCompiler extends Compiler {
len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
} else {
if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
len += mbLength * strLength;
len += strLength;
}
if (op == OPCode.EXACTMBN) len += OPSize.LENGTH;
return len;
}
@Override
protected final void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(mbLength, strLength, ignoreCase);
protected final void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase) {
int op = selectStrOpcode(strLength, ignoreCase);
addOpcode(op);
if (op == OPCode.EXACTMBN) addLength(mbLength);
if (op == OPCode.EXACTMBN) addLength(1);
if (isNeedStrLenOpExact(op)) {
if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) {
addLength(mbLength * strLength);
} else {
addLength(strLength);
}
addLength(strLength);
}
if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
@ -220,7 +192,7 @@ final class ArrayCompiler extends Compiler {
addInt(p);
addTemplate(chars);
} else {
addChars(chars, p, mbLength * strLength);
addChars(chars, p, strLength);
}
}
@ -242,14 +214,14 @@ final class ArrayCompiler extends Compiler {
slen++;
p++;
}
int r = addCompileStringlength(chars, prev, 1, slen, ambig);
int r = addCompileStringlength(chars, prev, slen, ambig);
rlen += r;
return rlen;
}
private int compileLengthStringRawNode(StringNode sn) {
if (sn.length() <= 0) return 0;
return addCompileStringlength(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
return addCompileStringlength(sn.chars, sn.p, sn.length(), false);
}
private void addMultiByteCClass(CodeRangeBuffer mbuf) {
@ -311,26 +283,6 @@ final class ArrayCompiler extends Compiler {
}
}
@Override
protected void compileCTypeNode(CTypeNode node) {
CTypeNode cn = node;
int op;
switch (cn.ctype) {
case CharacterType.WORD:
if (cn.not) {
op = OPCode.NOT_WORD;
} else {
op = OPCode.WORD;
}
break;
default:
newInternalException(ERR_PARSER_BUG);
return; // not reached
} // inner switch
addOpcode(op);
}
@Override
protected void compileAnyCharNode() {
if (isMultiline(regex.options)) {
@ -340,31 +292,16 @@ final class ArrayCompiler extends Compiler {
}
}
@Override
protected void compileCallNode(CallNode node) {
addOpcode(OPCode.CALL);
node.unsetAddrList.add(codeLength, node.target);
addAbsAddr(0); /*dummy addr.*/
}
@Override
protected void compileBackrefNode(BackRefNode node) {
BackRefNode br = node;
if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
addOpcode(OPCode.BACKREF_WITH_LEVEL);
addOption(regex.options & Option.IGNORECASE);
addLength(br.nestLevel);
// !goto add_bacref_mems;!
addLength(br.backNum);
for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
return;
} else { // USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
if (isIgnoreCase(regex.options)) {
addOpcode(OPCode.BACKREFN_IC);
addMemNum(br.back[0]);
} else {
switch (br.back[0]) {
// USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
if (isIgnoreCase(regex.options)) {
addOpcode(OPCode.BACKREFN_IC);
addMemNum(br.back[0]);
} else {
switch (br.back[0]) {
case 1:
addOpcode(OPCode.BACKREF1);
break;
@ -375,18 +312,17 @@ final class ArrayCompiler extends Compiler {
addOpcode(OPCode.BACKREFN);
addOpcode(br.back[0]);
break;
} // switch
}
} else {
if (isIgnoreCase(regex.options)) {
addOpcode(OPCode.BACKREF_MULTI_IC);
} else {
addOpcode(OPCode.BACKREF_MULTI);
}
// !add_bacref_mems:!
addLength(br.backNum);
for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
} // switch
}
} else {
if (isIgnoreCase(regex.options)) {
addOpcode(OPCode.BACKREF_MULTI_IC);
} else {
addOpcode(OPCode.BACKREF_MULTI);
}
// !add_bacref_mems:!
addLength(br.backNum);
for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
}
}
@ -419,7 +355,7 @@ final class ArrayCompiler extends Compiler {
compileTreeEmptyCheck(qn.target, emptyInfo);
if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) {
if (qn.isInRepeat()) {
addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG);
} else {
addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
@ -434,193 +370,6 @@ final class ArrayCompiler extends Compiler {
return ckn > 0;
}
private int compileCECLengthQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
int tlen = compileLengthTree(qn.target);
int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
int cklen = cknOn(ckn) ? OPSize.STATE_CHECK_NUM : 0;
/* anychar repeat */
if (qn.target.getType() == NodeType.CANY) {
if (qn.greedy && infinite) {
if (qn.nextHeadExact != null && !cknOn(ckn)) {
return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower + cklen;
} else {
return OPSize.ANYCHAR_STAR + tlen * qn.lower + cklen;
}
}
}
int modTLen;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
} else {
modTLen = tlen;
}
int len;
if (infinite && qn.lower <= 1) {
if (qn.greedy) {
if (qn.lower == 1) {
len = OPSize.JUMP;
} else {
len = 0;
}
len += OPSize.PUSH + cklen + modTLen + OPSize.JUMP;
} else {
if (qn.lower == 0) {
len = OPSize.JUMP;
} else {
len = 0;
}
len += modTLen + OPSize.PUSH + cklen;
}
} else if (qn.upper == 0) {
if (qn.isRefered) { /* /(?<n>..){0}/ */
len = OPSize.JUMP + tlen;
} else {
len = 0;
}
} else if (qn.upper == 1 && qn.greedy) {
if (qn.lower == 0) {
if (cknOn(ckn)) {
len = OPSize.STATE_CHECK_PUSH + tlen;
} else {
len = OPSize.PUSH + tlen;
}
} else {
len = tlen;
}
} else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
len = OPSize.PUSH + cklen + OPSize.JUMP + tlen;
} else {
len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
if (cknOn(ckn)) {
len += OPSize.STATE_CHECK;
}
}
return len;
}
@Override
protected void compileCECQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
int tlen = compileLengthTree(qn.target);
int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
if (qn.isAnyCharStar()) {
compileTreeNTimes(qn.target, qn.lower);
if (qn.nextHeadExact != null && !cknOn(ckn)) {
if (isMultiline(regex.options)) {
addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT);
} else {
addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
}
if (cknOn(ckn)) {
addStateCheckNum(ckn);
}
StringNode sn = (StringNode)qn.nextHeadExact;
addChars(sn.chars, sn.p, 1);
return;
} else {
if (isMultiline(regex.options)) {
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR);
} else {
addOpcode(OPCode.ANYCHAR_ML_STAR);
}
} else {
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR);
} else {
addOpcode(OPCode.ANYCHAR_STAR);
}
}
if (cknOn(ckn)) {
addStateCheckNum(ckn);
}
return;
}
}
int modTLen;
if (emptyInfo != 0) {
modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
} else {
modTLen = tlen;
}
if (infinite && qn.lower <= 1) {
if (qn.greedy) {
if (qn.lower == 1) {
addOpcodeRelAddr(OPCode.JUMP, cknOn(ckn) ? OPSize.STATE_CHECK_PUSH :
OPSize.PUSH);
}
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_PUSH);
addStateCheckNum(ckn);
addRelAddr(modTLen + OPSize.JUMP);
} else {
addOpcodeRelAddr(OPCode.PUSH, modTLen + OPSize.JUMP);
}
compileTreeEmptyCheck(qn.target, emptyInfo);
addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + (cknOn(ckn) ?
OPSize.STATE_CHECK_PUSH :
OPSize.PUSH)));
} else {
if (qn.lower == 0) {
addOpcodeRelAddr(OPCode.JUMP, modTLen);
}
compileTreeEmptyCheck(qn.target, emptyInfo);
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_PUSH_OR_JUMP);
addStateCheckNum(ckn);
addRelAddr(-(modTLen + OPSize.STATE_CHECK_PUSH_OR_JUMP));
} else {
addOpcodeRelAddr(OPCode.PUSH, -(modTLen + OPSize.PUSH));
}
}
} else if (qn.upper == 0) {
if (qn.isRefered) { /* /(?<n>..){0}/ */
addOpcodeRelAddr(OPCode.JUMP, tlen);
compileTree(qn.target);
} // else r=0 ???
} else if (qn.upper == 1 && qn.greedy) {
if (qn.lower == 0) {
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_PUSH);
addStateCheckNum(ckn);
addRelAddr(tlen);
} else {
addOpcodeRelAddr(OPCode.PUSH, tlen);
}
}
compileTree(qn.target);
} else if (!qn.greedy && qn.upper == 1 && qn.lower == 0){ /* '??' */
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK_PUSH);
addStateCheckNum(ckn);
addRelAddr(OPSize.JUMP);
} else {
addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
}
addOpcodeRelAddr(OPCode.JUMP, tlen);
compileTree(qn.target);
} else {
compileRangeRepeatNode(qn, modTLen, emptyInfo);
if (cknOn(ckn)) {
addOpcode(OPCode.STATE_CHECK);
addStateCheckNum(ckn);
}
}
}
private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
@ -821,21 +570,12 @@ final class ArrayCompiler extends Compiler {
int len;
switch (node.type) {
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL && node.isCalled()) {
len = OPSize.MEMORY_START_PUSH + tlen + OPSize.CALL + OPSize.JUMP + OPSize.RETURN;
if (bsAt(regex.btMemEnd, node.regNum)) {
len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
} else {
len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
}
} else { // USE_SUBEXP_CALL
if (bsAt(regex.btMemStart, node.regNum)) {
len = OPSize.MEMORY_START_PUSH;
} else {
len = OPSize.MEMORY_START;
}
len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
if (bsAt(regex.btMemStart, node.regNum)) {
len = OPSize.MEMORY_START_PUSH;
} else {
len = OPSize.MEMORY_START;
}
len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
break;
case EncloseType.STOP_BACKTRACK:
@ -860,23 +600,6 @@ final class ArrayCompiler extends Compiler {
int len;
switch (node.type) {
case EncloseType.MEMORY:
if (Config.USE_SUBEXP_CALL) {
if (node.isCalled()) {
addOpcode(OPCode.CALL);
node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP;
node.setAddrFixed();
addAbsAddr(node.callAddr);
len = compileLengthTree(node.target);
len += OPSize.MEMORY_START_PUSH + OPSize.RETURN;
if (bsAt(regex.btMemEnd, node.regNum)) {
len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
} else {
len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
}
addOpcodeRelAddr(OPCode.JUMP, len);
}
} // USE_SUBEXP_CALL
if (bsAt(regex.btMemStart, node.regNum)) {
addOpcode(OPCode.MEMORY_START_PUSH);
} else {
@ -886,22 +609,12 @@ final class ArrayCompiler extends Compiler {
addMemNum(node.regNum);
compileTree(node.target);
if (Config.USE_SUBEXP_CALL && node.isCalled()) {
if (bsAt(regex.btMemEnd, node.regNum)) {
addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH);
} else {
addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END);
}
addMemNum(node.regNum);
addOpcode(OPCode.RETURN);
} else { // USE_SUBEXP_CALL
if (bsAt(regex.btMemEnd, node.regNum)) {
addOpcode(OPCode.MEMORY_END_PUSH);
} else {
addOpcode(OPCode.MEMORY_END);
}
addMemNum(node.regNum);
if (bsAt(regex.btMemEnd, node.regNum)) {
addOpcode(OPCode.MEMORY_END_PUSH);
} else {
addOpcode(OPCode.MEMORY_END);
}
addMemNum(node.regNum);
break;
case EncloseType.STOP_BACKTRACK:
@ -1078,32 +791,17 @@ final class ArrayCompiler extends Compiler {
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
} else { // USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
} else {
len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
}
// USE_BACKREF_AT_LEVEL
if (br.backNum == 1) {
len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
} else {
len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
}
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
len = OPSize.CALL;
break;
} // USE_SUBEXP_CALL
break;
case NodeType.QTFR:
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
len = compileCECLengthQuantifierNode((QuantifierNode)node);
} else {
len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
}
len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
break;
case NodeType.ENCLOSE:

View File

@ -1,109 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
final class AsmCompiler extends AsmCompilerSupport {
public AsmCompiler(Analyser analyser) {
super(analyser);
}
@Override
protected void prepare() {
REG_NUM++;
prepareMachine();
prepareMachineInit();
prepareMachineMatch();
prepareFactory();
prepareFactoryInit();
}
@Override
protected void finish() {
setupFactoryInit();
setupMachineInit();
setupMachineMatch();
setupClasses();
}
@Override
protected void compileAltNode(ConsAltNode node) {
}
@Override
protected void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
String template = installTemplate(chars, p, strLength);
}
@Override
protected void compileCClassNode(CClassNode node) {
if (node.bs != null) {
String bitsetName = installBitSet(node.bs.bits);
}
}
@Override
protected void compileCTypeNode(CTypeNode node) {
}
@Override
protected void compileAnyCharNode() {
}
@Override
protected void compileBackrefNode(BackRefNode node) {
}
@Override
protected void compileCallNode(CallNode node) {
}
@Override
protected void compileCECQuantifierNode(QuantifierNode node) {
}
@Override
protected void compileNonCECQuantifierNode(QuantifierNode node) {
}
@Override
protected void compileOptionNode(EncloseNode node) {
}
@Override
protected void compileEncloseNode(EncloseNode node) {
}
@Override
protected void compileAnchorNode(AnchorNode node) {
}
}

View File

@ -1,267 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import java.io.FileOutputStream;
import java.io.IOException;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AsmConstants;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConstants {
protected ClassWriter factory; // matcher allocator, also bit set, code rage and string template container
protected MethodVisitor factoryInit;// factory constructor
protected String factoryName;
protected ClassWriter machine; // matcher
protected MethodVisitor machineInit;// matcher constructor
protected MethodVisitor match; // actual matcher implementation (the matchAt method)
protected String machineName;
// we will? try to manage visitMaxs ourselves for efficiency
protected int maxStack = 1;
protected int maxVars = LAST_INDEX;
// for field generation
protected int bitsets, ranges, templates;
// simple class name postfix scheme for now
static int REG_NUM = 0;
// dummy class loader for now
private static final class DummyClassLoader extends ClassLoader {
public Class<?> defineClass(String name, byte[] bytes) {
return super.defineClass(name, bytes, 0, bytes.length);
}
};
private static final DummyClassLoader loader = new DummyClassLoader();
AsmCompilerSupport(Analyser analyser) {
super(analyser);
}
protected final void prepareFactory() {
factory = new ClassWriter(ClassWriter.COMPUTE_MAXS);
factoryName = "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory" + REG_NUM;
factory.visit(V1_4, ACC_PUBLIC + ACC_FINAL, factoryName, null, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", null);
MethodVisitor create = factory.visitMethod(ACC_SYNTHETIC, "create", "(Lorg/joni/Regex;[BII)Lorg/joni/Matcher;", null, null);
create.visitTypeInsn(NEW, machineName);
create.visitInsn(DUP); // instance
create.visitVarInsn(ALOAD, 1); // Regex
create.visitVarInsn(ALOAD, 2); // bytes[]
create.visitVarInsn(ILOAD, 3); // p
create.visitVarInsn(ILOAD, 4); // end
create.visitMethodInsn(INVOKESPECIAL, machineName, "<init>", "(Lorg/joni/Regex;[BII)V");
create.visitInsn(ARETURN);
create.visitMaxs(0, 0);
//create.visitMaxs(6, 5);
create.visitEnd();
}
protected final void prepareFactoryInit() {
factoryInit = factory.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
factoryInit.visitVarInsn(ALOAD, 0);
factoryInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", "<init>", "()V");
}
protected final void setupFactoryInit() {
factoryInit.visitInsn(RETURN);
factoryInit.visitMaxs(0, 0);
//init.visitMaxs(1, 1);
factoryInit.visitEnd();
}
protected final void prepareMachine() {
machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
machineName = "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine" + REG_NUM;
}
protected final void prepareMachineInit() {
machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", null);
machineInit = machine.visitMethod(ACC_PROTECTED, "<init>", "(Lorg/joni/Regex;[BII)V", null, null);
machineInit.visitVarInsn(ALOAD, THIS); // this
machineInit.visitVarInsn(ALOAD, 1); // Regex
machineInit.visitVarInsn(ALOAD, 2); // bytes[]
machineInit.visitVarInsn(ILOAD, 3); // p
machineInit.visitVarInsn(ILOAD, 4); // end
machineInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", "<init>", "(Lorg/joni/Regex;[BII)V");
}
protected final void setupMachineInit() {
if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
machineInit.visitVarInsn(ALOAD, THIS); // this
machineInit.visitVarInsn(ALOAD, 1); // this, Regex
machineInit.visitFieldInsn(GETFIELD, "jdk/nashorn/internal/runtime/regexp/joni/Regex", "factory", "Lorg/joni/MatcherFactory;"); // this, factory
machineInit.visitTypeInsn(CHECKCAST, factoryName);
machineInit.visitFieldInsn(PUTFIELD, machineName, "factory", "L" + factoryName + ";"); // []
}
machineInit.visitInsn(RETURN);
machineInit.visitMaxs(0, 0);
//init.visitMaxs(5, 5);
machineInit.visitEnd();
}
protected final void prepareMachineMatch() {
match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
move(S, SSTART); // s = sstart
load("bytes", "[B"); //
astore(BYTES); // byte[]bytes = this.bytes
}
protected final void setupMachineMatch() {
match.visitInsn(ICONST_M1);
match.visitInsn(IRETURN);
match.visitMaxs(maxStack, maxVars);
match.visitEnd();
}
protected final void setupClasses() {
byte[]factoryCode = factory.toByteArray();
byte[]machineCode = machine.toByteArray();
if (Config.DEBUG_ASM) {
try {
FileOutputStream fos;
fos = new FileOutputStream(factoryName.substring(factoryName.lastIndexOf('/') + 1) + ".class");
fos.write(factoryCode);
fos.close();
fos = new FileOutputStream(machineName.substring(machineName.lastIndexOf('/') + 1) + ".class");
fos.write(machineCode);
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace(Config.err);
}
}
loader.defineClass(machineName.replace('/', '.'), machineCode);
Class<?> cls = loader.defineClass(factoryName.replace('/', '.'), factoryCode);
try {
regex.factory = (MatcherFactory)cls.newInstance();
} catch(Exception e) {
e.printStackTrace(Config.err);
}
}
protected final void aload(int var) {
match.visitVarInsn(ALOAD, var);
}
protected final void astore(int var) {
match.visitVarInsn(ASTORE, var);
}
protected final void loadThis() {
match.visitVarInsn(ALOAD, THIS);
}
protected final void load(int var) {
match.visitVarInsn(ILOAD, var);
}
protected final void store(int var) {
match.visitVarInsn(ISTORE, var);
}
protected final void move(int to, int from) {
load(from);
store(to);
}
protected final void load(String field, String singature) {
loadThis();
match.visitFieldInsn(GETFIELD, machineName, field, singature);
}
protected final void load(String field) {
load(field, "I");
}
protected final void store(String field, String singature) {
loadThis();
match.visitFieldInsn(PUTFIELD, machineName, field, singature);
}
protected final void store(String field) {
store(field, "I");
}
protected final String installTemplate(char[] arr, int p, int length) {
String templateName = TEMPLATE + ++templates;
installArray(templateName, arr, p, length);
return templateName;
}
protected final String installCodeRange(int[]arr) {
String coreRangeName = CODERANGE + ++ranges;
installArray(coreRangeName, arr);
return coreRangeName;
}
protected final String installBitSet(int[]arr) {
String bitsetName = BITSET + ++bitsets;
installArray(bitsetName, arr);
return bitsetName;
}
private void installArray(String name, int[]arr) {
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
factoryInit.visitIntInsn(NEWARRAY, T_INT); // this, arr
for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
}
private void installArray(String name, char[]arr, int p, int length) {
factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
factoryInit.visitVarInsn(ALOAD, THIS); // this;
loadInt(factoryInit, arr.length); // this, length
factoryInit.visitIntInsn(NEWARRAY, T_BYTE); // this, arr
for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
}
private void buildArray(int index, int value, int type) {
factoryInit.visitInsn(DUP); // ... arr, arr
loadInt(factoryInit, index); // ... arr, arr, index
loadInt(factoryInit, value); // ... arr, arr, index, value
factoryInit.visitInsn(type); // ... arr
}
private void loadInt(MethodVisitor mv, int value) {
if (value >= -1 && value <= 5) {
mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
} else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
mv.visitIntInsn(BIPUSH, value);
} else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
mv.visitIntInsn(SIPUSH, value);
} else {
mv.visitLdcInsn(new Integer(value));
}
}
}

View File

@ -51,10 +51,6 @@ public final class BitSet {
bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
}
public void invert(int pos) {
bits[pos >>> ROOM_SHIFT] ^= bit(pos);
}
public void clear() {
for (int i=0; i<BITSET_SIZE; i++) bits[i]=0;
}
@ -70,10 +66,6 @@ public final class BitSet {
for (int i=from; i<=to && i < SINGLE_BYTE_SIZE; i++) set(i);
}
public void setAll() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~0;
}
public void invert() {
for (int i=0; i<BITSET_SIZE; i++) bits[i] = ~bits[i];
}

View File

@ -25,12 +25,15 @@ final class BitStatus {
public static int bsClear() {
return 0;
}
public static int bsAll() {
return -1;
}
public static boolean bsAt(int stats, int n) {
return (n < BIT_STATUS_BITS_NUM ? stats & (1 << n) : (stats & 1)) != 0;
}
public static int bsOnAt(int stats, int n) {
if (n < BIT_STATUS_BITS_NUM) {
stats |= (1 << n);
@ -39,10 +42,6 @@ final class BitStatus {
}
return stats;
}
public static int bsOnAtSimple(int stats, int n) {
if (n < BIT_STATUS_BITS_NUM) stats |= (1 << n);
return stats;
}
public static int bsOnOff(int v, int f, boolean negative) {
if (negative) {

View File

@ -53,56 +53,6 @@ class ByteCodeMachine extends StackMachine {
this.code = regex.code;
}
protected int stkp; // a temporary
private boolean makeCaptureHistoryTree(CaptureTreeNode node) {
//CaptureTreeNode child;
int k = stkp;
//int k = kp;
while (k < stk) {
StackEntry e = stack[k];
if (e.type == MEM_START) {
int n = e.getMemNum();
if (n <= Config.MAX_CAPTURE_HISTORY_GROUP && bsAt(regex.captureHistory, n)) {
CaptureTreeNode child = new CaptureTreeNode();
child.group = n;
child.beg = e.getMemPStr() - str;
node.addChild(child);
stkp = k + 1;
if (makeCaptureHistoryTree(child)) return true;
k = stkp;
child.end = e.getMemPStr() - str;
}
} else if (e.type == MEM_END) {
if (e.getMemNum() == node.group) {
node.end = e.getMemPStr() - str;
stkp = k;
return false;
}
}
}
return true; /* 1: root node ending. */
}
private void checkCaptureHistory(Region region) {
CaptureTreeNode node;
if (region.historyRoot == null) {
node = region.historyRoot = new CaptureTreeNode();
} else {
node = region.historyRoot;
node.clear();
}
// was clear ???
node.group = 0;
node.beg = sstart - str;
node.end = s - str;
stkp = 0;
makeCaptureHistoryTree(region.historyRoot);
}
private boolean stringCmpIC(int caseFlodFlag, int s1, IntHolder ps2, int mbLen, int textEnd) {
int s2 = ps2.value;
@ -175,13 +125,6 @@ class ByteCodeMachine extends StackMachine {
case OPCode.EXACT5: opExact5(); continue;
case OPCode.EXACTN: opExactN(); continue;
case OPCode.EXACTMB2N1: opExactMB2N1(); break;
case OPCode.EXACTMB2N2: opExactMB2N2(); continue;
case OPCode.EXACTMB2N3: opExactMB2N3(); continue;
case OPCode.EXACTMB2N: opExactMB2N(); continue;
case OPCode.EXACTMB3N: opExactMB3N(); continue;
case OPCode.EXACTMBN: opExactMBN(); continue;
case OPCode.EXACT1_IC: opExact1IC(); break;
case OPCode.EXACTN_IC: opExactNIC(); continue;
@ -199,8 +142,6 @@ class ByteCodeMachine extends StackMachine {
case OPCode.ANYCHAR_ML_STAR: opAnyCharMLStar(); break;
case OPCode.ANYCHAR_STAR_PEEK_NEXT: opAnyCharStarPeekNext(); break;
case OPCode.ANYCHAR_ML_STAR_PEEK_NEXT: opAnyCharMLStarPeekNext(); break;
case OPCode.STATE_CHECK_ANYCHAR_STAR: opStateCheckAnyCharStar(); break;
case OPCode.STATE_CHECK_ANYCHAR_ML_STAR:opStateCheckAnyCharMLStar();break;
case OPCode.WORD: opWord(); break;
case OPCode.NOT_WORD: opNotWord(); break;
@ -239,11 +180,6 @@ class ByteCodeMachine extends StackMachine {
case OPCode.JUMP: opJump(); continue;
case OPCode.PUSH: opPush(); continue;
// CEC
case OPCode.STATE_CHECK_PUSH: opStateCheckPush(); continue;
case OPCode.STATE_CHECK_PUSH_OR_JUMP: opStateCheckPushOrJump(); continue;
case OPCode.STATE_CHECK: opStateCheck(); continue;
case OPCode.POP: opPop(); continue;
case OPCode.PUSH_OR_JUMP_EXACT1: opPushOrJumpExact1(); continue;
case OPCode.PUSH_IF_PEEK_NEXT: opPushIfPeekNext(); continue;
@ -266,10 +202,6 @@ class ByteCodeMachine extends StackMachine {
case OPCode.PUSH_LOOK_BEHIND_NOT: opPushLookBehindNot(); continue;
case OPCode.FAIL_LOOK_BEHIND_NOT: opFailLookBehindNot(); continue;
// USE_SUBEXP_CALL
case OPCode.CALL: opCall(); continue;
case OPCode.RETURN: opReturn(); continue;
case OPCode.FINISH:
return finish();
@ -322,9 +254,6 @@ class ByteCodeMachine extends StackMachine {
}
if (Config.USE_CAPTURE_HISTORY) {
if (regex.captureHistory != 0) checkCaptureHistory(region);
}
} else {
msaBegin = sstart - str;
msaEnd = s - str;
@ -437,125 +366,6 @@ class ByteCodeMachine extends StackMachine {
sprev = s - 1;
}
private void opExactMB2N1() {
if (s + 2 > range) {opFail(); return;}
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
sprev = sbegin; // break;
}
private void opExactMB2N2() {
if (s + 4 > range) {opFail(); return;}
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
sprev = s;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
}
private void opExactMB2N3() {
if (s + 6 > range) {opFail(); return;}
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
sprev = s;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
}
private void opExactMB2N() {
int tlen = code[ip++];
if (s + tlen * 2 > range) {opFail(); return;}
if (Config.USE_STRING_TEMPLATES) {
char[] bs = regex.templates[code[ip++]];
int ps = code[ip++];
while(tlen-- > 0) {
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
}
} else {
while(tlen-- > 0) {
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
}
}
sprev = s - 2;
}
private void opExactMB3N() {
int tlen = code[ip++];
if (s + tlen * 3 > range) {opFail(); return;}
if (Config.USE_STRING_TEMPLATES) {
char[] bs = regex.templates[code[ip++]];
int ps = code[ip++];
while (tlen-- > 0) {
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
}
} else {
while (tlen-- > 0) {
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
}
}
sprev = s - 3;
}
private void opExactMBN() {
int tlen = code[ip++]; /* mb-len */
int tlen2= code[ip++]; /* string len */
tlen2 *= tlen;
if (s + tlen2 > range) {opFail(); return;}
if (Config.USE_STRING_TEMPLATES) {
char[] bs = regex.templates[code[ip++]];
int ps = code[ip++];
while (tlen2-- > 0) {
if (bs[ps] != chars[s]) {opFail(); return;}
ps++; s++;
}
} else {
while (tlen2-- > 0) {
if (code[ip] != chars[s]) {opFail(); return;}
ip++; s++;
}
}
sprev = s - tlen;
}
private void opExact1IC() {
if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
ip++;
@ -748,34 +558,6 @@ class ByteCodeMachine extends StackMachine {
sprev = sbegin; // break;
}
// CEC
private void opStateCheckAnyCharStar() {
int mem = code[ip++];
final char[] chars = this.chars;
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
sprev = s;
s++;
}
sprev = sbegin; // break;
}
// CEC
private void opStateCheckAnyCharMLStar() {
int mem = code[ip++];
while (s < range) {
if (stateCheckVal(s, mem)) {opFail(); return;}
pushAltWithStateCheck(ip, s, sprev, mem);
sprev = s;
s++;
}
sprev = sbegin; // break;
}
private void opWord() {
if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
s++;
@ -1223,33 +1005,6 @@ class ByteCodeMachine extends StackMachine {
pushAlt(ip + addr, s, sprev);
}
// CEC
private void opStateCheckPush() {
int mem = code[ip++];
if (stateCheckVal(s, mem)) {opFail(); return;}
int addr = code[ip++];
pushAltWithStateCheck(ip + addr, s, sprev, mem);
}
// CEC
private void opStateCheckPushOrJump() {
int mem = code[ip++];
int addr= code[ip++];
if (stateCheckVal(s, mem)) {
ip += addr;
} else {
pushAltWithStateCheck(ip + addr, s, sprev, mem);
}
}
// CEC
private void opStateCheck() {
int mem = code[ip++];
if (stateCheckVal(s, mem)) {opFail(); return;}
pushStateCheck(s, mem);
}
private void opPop() {
popOne();
}
@ -1425,17 +1180,6 @@ class ByteCodeMachine extends StackMachine {
opFail();
}
private void opCall() {
int addr = code[ip++];
pushCallFrame(ip);
ip = addr; // absolute address
}
private void opReturn() {
ip = sreturn();
pushReturn();
}
private void opFail() {
if (stack == null) {
ip = regex.codeLength - 1;
@ -1447,13 +1191,6 @@ class ByteCodeMachine extends StackMachine {
ip = e.getStatePCode();
s = e.getStatePStr();
sprev = e.getStatePStrPrev();
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.getStateCheck() != 0) {
e.type = STATE_CHECK_MARK;
stk++;
}
}
}
private int finish() {

View File

@ -34,6 +34,239 @@ class ByteCodePrinter {
int operantCount;
WarnCallback warnings;
private final static String OpCodeNames[] = new String[] {
"finish", /*OP_FINISH*/
"end", /*OP_END*/
"exact1", /*OP_EXACT1*/
"exact2", /*OP_EXACT2*/
"exact3", /*OP_EXACT3*/
"exact4", /*OP_EXACT4*/
"exact5", /*OP_EXACT5*/
"exactn", /*OP_EXACTN*/
"exactmb2-n1", /*OP_EXACTMB2N1*/
"exactmb2-n2", /*OP_EXACTMB2N2*/
"exactmb2-n3", /*OP_EXACTMB2N3*/
"exactmb2-n", /*OP_EXACTMB2N*/
"exactmb3n", /*OP_EXACTMB3N*/
"exactmbn", /*OP_EXACTMBN*/
"exact1-ic", /*OP_EXACT1_IC*/
"exactn-ic", /*OP_EXACTN_IC*/
"cclass", /*OP_CCLASS*/
"cclass-mb", /*OP_CCLASS_MB*/
"cclass-mix", /*OP_CCLASS_MIX*/
"cclass-not", /*OP_CCLASS_NOT*/
"cclass-mb-not", /*OP_CCLASS_MB_NOT*/
"cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
"cclass-node", /*OP_CCLASS_NODE*/
"anychar", /*OP_ANYCHAR*/
"anychar-ml", /*OP_ANYCHAR_ML*/
"anychar*", /*OP_ANYCHAR_STAR*/
"anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"word", /*OP_WORD*/
"not-word", /*OP_NOT_WORD*/
"word-bound", /*OP_WORD_BOUND*/
"not-word-bound", /*OP_NOT_WORD_BOUND*/
"word-begin", /*OP_WORD_BEGIN*/
"word-end", /*OP_WORD_END*/
"begin-buf", /*OP_BEGIN_BUF*/
"end-buf", /*OP_END_BUF*/
"begin-line", /*OP_BEGIN_LINE*/
"end-line", /*OP_END_LINE*/
"semi-end-buf", /*OP_SEMI_END_BUF*/
"begin-position", /*OP_BEGIN_POSITION*/
"backref1", /*OP_BACKREF1*/
"backref2", /*OP_BACKREF2*/
"backrefn", /*OP_BACKREFN*/
"backrefn-ic", /*OP_BACKREFN_IC*/
"backref_multi", /*OP_BACKREF_MULTI*/
"backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
"backref_at_level", /*OP_BACKREF_AT_LEVEL*/
"mem-start", /*OP_MEMORY_START*/
"mem-start-push", /*OP_MEMORY_START_PUSH*/
"mem-end-push", /*OP_MEMORY_END_PUSH*/
"mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
"mem-end", /*OP_MEMORY_END*/
"mem-end-rec", /*OP_MEMORY_END_REC*/
"fail", /*OP_FAIL*/
"jump", /*OP_JUMP*/
"push", /*OP_PUSH*/
"pop", /*OP_POP*/
"push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
"push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
"repeat", /*OP_REPEAT*/
"repeat-ng", /*OP_REPEAT_NG*/
"repeat-inc", /*OP_REPEAT_INC*/
"repeat-inc-ng", /*OP_REPEAT_INC_NG*/
"repeat-inc-sg", /*OP_REPEAT_INC_SG*/
"repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
"null-check-start", /*OP_NULL_CHECK_START*/
"null-check-end", /*OP_NULL_CHECK_END*/
"null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
"null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
"push-pos", /*OP_PUSH_POS*/
"pop-pos", /*OP_POP_POS*/
"push-pos-not", /*OP_PUSH_POS_NOT*/
"fail-pos", /*OP_FAIL_POS*/
"push-stop-bt", /*OP_PUSH_STOP_BT*/
"pop-stop-bt", /*OP_POP_STOP_BT*/
"look-behind", /*OP_LOOK_BEHIND*/
"push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
"fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
"call", /*OP_CALL*/
"return", /*OP_RETURN*/
"state-check-push", /*OP_STATE_CHECK_PUSH*/
"state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
"state-check", /*OP_STATE_CHECK*/
"state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"set-option-push", /*OP_SET_OPTION_PUSH*/
"set-option", /*OP_SET_OPTION*/
// single byte versions
"anychar-sb", /*OP_ANYCHAR*/
"anychar-ml-sb", /*OP_ANYCHAR_ML*/
"anychar*-sb", /*OP_ANYCHAR_STAR*/
"anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"cclass-sb", /*OP_CCLASS*/
"cclass-not-sb", /*OP_CCLASS_NOT*/
"word-sb", /*OP_WORD*/
"not-word-sb", /*OP_NOT_WORD*/
"word-bound-sb", /*OP_WORD_BOUND*/
"not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
"word-begin-sb", /*OP_WORD_BEGIN*/
"word-end-sb", /*OP_WORD_END*/
"look-behind-sb", /*OP_LOOK_BEHIND*/
"exact1-ic-sb", /*OP_EXACT1_IC*/
"exactn-ic-sb", /*OP_EXACTN_IC*/
};
private final static int OpCodeArgTypes[] = new int[] {
Arguments.NON, /*OP_FINISH*/
Arguments.NON, /*OP_END*/
Arguments.SPECIAL, /*OP_EXACT1*/
Arguments.SPECIAL, /*OP_EXACT2*/
Arguments.SPECIAL, /*OP_EXACT3*/
Arguments.SPECIAL, /*OP_EXACT4*/
Arguments.SPECIAL, /*OP_EXACT5*/
Arguments.SPECIAL, /*OP_EXACTN*/
Arguments.SPECIAL, /*OP_EXACTMB2N1*/
Arguments.SPECIAL, /*OP_EXACTMB2N2*/
Arguments.SPECIAL, /*OP_EXACTMB2N3*/
Arguments.SPECIAL, /*OP_EXACTMB2N*/
Arguments.SPECIAL, /*OP_EXACTMB3N*/
Arguments.SPECIAL, /*OP_EXACTMBN*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_MB*/
Arguments.SPECIAL, /*OP_CCLASS_MIX*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_NODE*/
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.NON, /*OP_BEGIN_BUF*/
Arguments.NON, /*OP_END_BUF*/
Arguments.NON, /*OP_BEGIN_LINE*/
Arguments.NON, /*OP_END_LINE*/
Arguments.NON, /*OP_SEMI_END_BUF*/
Arguments.NON, /*OP_BEGIN_POSITION*/
Arguments.NON, /*OP_BACKREF1*/
Arguments.NON, /*OP_BACKREF2*/
Arguments.MEMNUM, /*OP_BACKREFN*/
Arguments.SPECIAL, /*OP_BACKREFN_IC*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
Arguments.MEMNUM, /*OP_MEMORY_START*/
Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
Arguments.MEMNUM, /*OP_MEMORY_END*/
Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
Arguments.NON, /*OP_FAIL*/
Arguments.RELADDR, /*OP_JUMP*/
Arguments.RELADDR, /*OP_PUSH*/
Arguments.NON, /*OP_POP*/
Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_REPEAT*/
Arguments.SPECIAL, /*OP_REPEAT_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
Arguments.NON, /*OP_PUSH_POS*/
Arguments.NON, /*OP_POP_POS*/
Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
Arguments.NON, /*OP_FAIL_POS*/
Arguments.NON, /*OP_PUSH_STOP_BT*/
Arguments.NON, /*OP_POP_STOP_BT*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
Arguments.ABSADDR, /*OP_CALL*/
Arguments.NON, /*OP_RETURN*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
Arguments.OPTION, /*OP_SET_OPTION*/
// single byte versions
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
};
public ByteCodePrinter(Regex regex) {
code = regex.code;
codeLength = regex.codeLength;
@ -76,8 +309,8 @@ class ByteCodePrinter {
CClassNode cc;
int tm, idx;
sb.append("[" + OPCode.OpCodeNames[code[bp]]);
int argType = OPCode.OpCodeArgTypes[code[bp]];
sb.append("[" + OpCodeNames[code[bp]]);
int argType = OpCodeArgTypes[code[bp]];
int ip = bp;
if (argType != Arguments.SPECIAL) {
bp++;

View File

@ -1,74 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public class CaptureTreeNode {
int group;
int beg;
int end;
// int allocated;
int numChildren;
CaptureTreeNode[]children;
CaptureTreeNode() {
beg = Region.REGION_NOTPOS;
end = Region.REGION_NOTPOS;
group = -1;
}
static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
void addChild(CaptureTreeNode child) {
if (children == null) {
children = new CaptureTreeNode[HISTORY_TREE_INIT_ALLOC_SIZE];
} else if (numChildren >= children.length) {
CaptureTreeNode[]tmp = new CaptureTreeNode[children.length << 1];
System.arraycopy(children, 0, tmp, 0, children.length);
children = tmp;
}
children[numChildren] = child;
numChildren++;
}
void clear() {
for (int i=0; i<numChildren; i++) {
children[i] = null; // ???
}
numChildren = 0;
beg = end = Region.REGION_NOTPOS;
group = -1;
}
CaptureTreeNode cloneTree() {
CaptureTreeNode clone = new CaptureTreeNode();
clone.beg = beg;
clone.end = end;
for (int i=0; i<numChildren; i++) {
CaptureTreeNode child = children[i].cloneTree();
clone.addChild(child);
}
return clone;
}
}

View File

@ -22,8 +22,6 @@ package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@ -56,7 +54,7 @@ abstract class Compiler implements ErrorMessages {
private void compileStringRawNode(StringNode sn) {
if (sn.length() <= 0) return;
addCompileString(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
addCompileString(sn.chars, sn.p, sn.length(), false);
}
private void compileStringNode(StringNode node) {
@ -76,17 +74,14 @@ abstract class Compiler implements ErrorMessages {
slen++;
p++;
}
addCompileString(chars, prev, 1, slen, ambig);
addCompileString(chars, prev, slen, ambig);
}
protected abstract void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase);
protected abstract void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase);
protected abstract void compileCClassNode(CClassNode node);
protected abstract void compileCTypeNode(CTypeNode node);
protected abstract void compileAnyCharNode();
protected abstract void compileCallNode(CallNode node);
protected abstract void compileBackrefNode(BackRefNode node);
protected abstract void compileCECQuantifierNode(QuantifierNode node);
protected abstract void compileNonCECQuantifierNode(QuantifierNode node);
protected abstract void compileOptionNode(EncloseNode node);
protected abstract void compileEncloseNode(EncloseNode node);
@ -118,10 +113,6 @@ abstract class Compiler implements ErrorMessages {
compileCClassNode((CClassNode)node);
break;
case NodeType.CTYPE:
compileCTypeNode((CTypeNode)node);
break;
case NodeType.CANY:
compileAnyCharNode();
break;
@ -130,19 +121,8 @@ abstract class Compiler implements ErrorMessages {
compileBackrefNode((BackRefNode)node);
break;
case NodeType.CALL:
if (Config.USE_SUBEXP_CALL) {
compileCallNode((CallNode)node);
break;
} // USE_SUBEXP_CALL
break;
case NodeType.QTFR:
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
compileCECQuantifierNode((QuantifierNode)node);
} else {
compileNonCECQuantifierNode((QuantifierNode)node);
}
compileNonCECQuantifierNode((QuantifierNode)node);
break;
case NodeType.ENCLOSE:

View File

@ -31,10 +31,6 @@ public interface Config {
final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
final boolean USE_NAMED_GROUP = true;
final boolean USE_SUBEXP_CALL = true;
final boolean USE_BACKREF_WITH_LEVEL = true; /* \k<name+n>, \k<name-n> */
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */
final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
@ -42,12 +38,10 @@ public interface Config {
final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
final boolean USE_CAPTURE_HISTORY = false;
final boolean USE_VARIABLE_META_CHARS = true;
final boolean USE_WORD_BEGIN_END = true; /* "\<": word-begin, "\>": word-end */
final boolean USE_POSIX_API_REGION_OPTION = true; /* needed for POSIX API support */
final boolean USE_POSIX_API_REGION_OPTION = false; /* needed for POSIX API support */
final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
final int NREGION = 10;
final int MAX_BACKREF_NUM = 1000;
@ -73,13 +67,6 @@ public interface Config {
final boolean USE_STRING_TEMPLATES = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
final int MAX_CAPTURE_HISTORY_GROUP = 31;
final int CHECK_STRING_THRESHOLD_LEN = 7;
final int CHECK_BUFF_MAX_SIZE = 0x4000;
final boolean NON_UNICODE_SDW = true;
@ -95,6 +82,4 @@ public interface Config {
final boolean DEBUG_COMPILE_BYTE_CODE_INFO = DEBUG_ALL;
final boolean DEBUG_SEARCH = DEBUG_ALL;
final boolean DEBUG_MATCH = DEBUG_ALL;
final boolean DEBUG_ASM = true;
final boolean DEBUG_ASM_EXEC = true;
}

View File

@ -95,20 +95,6 @@ public class EncodingHelper {
return s;
}
/* onigenc_with_ascii_strncmp */
public static int strNCmp(char[] chars1, int p1, int end, char[] chars2, int p2, int n) {
while (n-- > 0) {
if (p1 >= end) return chars2[p2];
int c = chars1[p1];
int x = chars2[p2] - c;
if (x != 0) return x;
p2++;
p1++;
}
return 0;
}
public static int mbcToCode(byte[] bytes, int p, int end) {
int code = 0;
for (int i = p; i < end; i++) {

View File

@ -27,10 +27,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
class Lexer extends ScannerSupport {
protected final ScanEnvironment env;
@ -215,198 +212,6 @@ class Lexer extends ScannerSupport {
\k<-num+n>, \k<-num-n>
*/
// value implicit (rnameEnd)
private boolean fetchNameWithLevel(int startCode, Ptr rbackNum, Ptr rlevel) {
int src = p;
boolean existLevel = false;
int isNum = 0;
int sign = 1;
int endCode = nameEndCodePoint(startCode);
int pnumHead = p;
int nameEnd = stop;
String err = null;
if (!left()) {
newValueException(ERR_EMPTY_GROUP_NAME);
} else {
fetch();
if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
if (Character.isDigit(c)) {
isNum = 1;
} else if (c == '-') {
isNum = 2;
sign = -1;
pnumHead = p;
} else if (!EncodingHelper.isWord(c)) {
err = ERR_INVALID_GROUP_NAME;
}
}
while (left()) {
nameEnd = p;
fetch();
if (c == endCode || c == ')' || c == '+' || c == '-') {
if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
break;
}
if (isNum != 0) {
if (EncodingHelper.isDigit(c)) {
isNum = 1;
} else {
err = ERR_INVALID_GROUP_NAME;
// isNum = 0;
}
} else if (!EncodingHelper.isWord(c)) {
err = ERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
boolean isEndCode = false;
if (err == null && c != endCode) {
if (c == '+' || c == '-') {
int flag = c == '-' ? -1 : 1;
fetch();
if (!EncodingHelper.isDigit(c)) newValueException(ERR_INVALID_GROUP_NAME, src, stop);
unfetch();
int level = scanUnsignedNumber();
if (level < 0) newValueException(ERR_TOO_BIG_NUMBER);
rlevel.p = level * flag;
existLevel = true;
fetch();
isEndCode = c == endCode;
}
if (!isEndCode) {
err = ERR_INVALID_GROUP_NAME;
nameEnd = stop;
}
}
if (err == null) {
if (isNum != 0) {
mark();
p = pnumHead;
int backNum = scanUnsignedNumber();
restore();
if (backNum < 0) {
newValueException(ERR_TOO_BIG_NUMBER);
} else if (backNum == 0) {
newValueException(ERR_INVALID_GROUP_NAME, src, stop);
}
rbackNum.p = backNum * sign;
}
value = nameEnd;
return existLevel;
} else {
newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
return false; // not reached
}
}
// USE_NAMED_GROUP
// ref: 0 -> define name (don't allow number name)
// 1 -> reference name (allow number name)
private int fetchNameForNamedGroup(int startCode, boolean ref) {
int src = p;
value = 0;
int isNum = 0;
int sign = 1;
int endCode = nameEndCodePoint(startCode);
int pnumHead = p;
int nameEnd = stop;
String err = null;
if (!left()) {
newValueException(ERR_EMPTY_GROUP_NAME);
} else {
fetch();
if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
if (EncodingHelper.isDigit(c)) {
if (ref) {
isNum = 1;
} else {
err = ERR_INVALID_GROUP_NAME;
// isNum = 0;
}
} else if (c == '-') {
if (ref) {
isNum = 2;
sign = -1;
pnumHead = p;
} else {
err = ERR_INVALID_GROUP_NAME;
// isNum = 0;
}
} else if (!EncodingHelper.isWord(c)) {
err = ERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
if (err == null) {
while (left()) {
nameEnd = p;
fetch();
if (c == endCode || c == ')') {
if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
break;
}
if (isNum != 0) {
if (EncodingHelper.isDigit(c)) {
isNum = 1;
} else {
if (!EncodingHelper.isWord(c)) {
err = ERR_INVALID_CHAR_IN_GROUP_NAME;
} else {
err = ERR_INVALID_GROUP_NAME;
}
// isNum = 0;
}
} else {
if (!EncodingHelper.isWord(c)) {
err = ERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
}
if (c != endCode) {
err = ERR_INVALID_GROUP_NAME;
nameEnd = stop;
}
int backNum = 0;
if (isNum != 0) {
mark();
p = pnumHead;
backNum = scanUnsignedNumber();
restore();
if (backNum < 0) {
newValueException(ERR_TOO_BIG_NUMBER);
} else if (backNum == 0) {
newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
}
backNum *= sign;
}
value = nameEnd;
return backNum;
} else {
while (left()) {
nameEnd = p;
fetch();
if (c == endCode || c == ')') break;
}
if (!left()) nameEnd = stop;
newValueException(err, src, nameEnd);
return 0; // not reached
}
}
// #else USE_NAMED_GROUP
// make it return nameEnd!
private final int fetchNameForNoNamedGroup(int startCode, boolean ref) {
@ -472,11 +277,7 @@ class Lexer extends ScannerSupport {
}
protected final int fetchName(int startCode, boolean ref) {
if (Config.USE_NAMED_GROUP) {
return fetchNameForNamedGroup(startCode, ref);
} else {
return fetchNameForNoNamedGroup(startCode, ref);
}
return fetchNameForNoNamedGroup(startCode, ref);
}
private boolean strExistCheckWithEsc(int[]s, int n, int bad) {
@ -519,26 +320,6 @@ class Lexer extends ScannerSupport {
token.setPropNot(flag);
}
private void fetchTokenInCCFor_p() {
int c2 = peek(); // !!! migrate to peekIs
if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
inc();
token.type = TokenType.CHAR_PROPERTY;
token.setPropNot(c == 'P');
if (syntax.op2EscPBraceCircumflexNot()) {
c2 = fetchTo();
if (c2 == '^') {
token.setPropNot(!token.getPropNot());
} else {
unfetch();
}
}
} else {
syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
}
}
private void fetchTokenInCCFor_x() {
if (!left()) return;
int last = p;
@ -604,30 +385,6 @@ class Lexer extends ScannerSupport {
}
}
private void fetchTokenInCCFor_posixBracket() {
if (syntax.opPosixBracket() && peekIs(':')) {
token.backP = p; /* point at '[' is readed */
inc();
if (strExistCheckWithEsc(send, send.length, ']')) {
token.type = TokenType.POSIX_BRACKET_OPEN;
} else {
unfetch();
// remove duplication, goto cc_in_cc;
if (syntax.op2CClassSetOp()) {
token.type = TokenType.CC_CC_OPEN;
} else {
env.ccEscWarn("[");
}
}
} else { // cc_in_cc:
if (syntax.op2CClassSetOp()) {
token.type = TokenType.CC_CC_OPEN;
} else {
env.ccEscWarn("[");
}
}
}
private void fetchTokenInCCFor_and() {
if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
inc();
@ -683,10 +440,6 @@ class Lexer extends ScannerSupport {
case 'H':
if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
break;
case 'p':
case 'P':
fetchTokenInCCFor_p();
break;
case 'x':
fetchTokenInCCFor_x();
break;
@ -714,18 +467,12 @@ class Lexer extends ScannerSupport {
break;
} // switch
} else if (c == '[') {
fetchTokenInCCFor_posixBracket();
} else if (c == '&') {
fetchTokenInCCFor_and();
}
return token.type;
}
protected final int backrefRelToAbs(int relNo) {
return env.numMem + 1 + relNo;
}
private void fetchTokenFor_repeat(int lower, int upper) {
token.type = TokenType.OP_REPEAT;
token.setRepeatLower(lower);
@ -815,7 +562,6 @@ class Lexer extends ScannerSupport {
token.setBackrefNum(1);
token.setBackrefRef1(num);
token.setBackrefByName(false);
if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
return;
}
@ -845,76 +591,6 @@ class Lexer extends ScannerSupport {
}
}
private void fetchTokenFor_namedBackref() {
if (syntax.op2EscKNamedBackref()) {
if (left()) {
fetch();
if (c =='<' || c == '\'') {
int last = p;
int backNum;
if (Config.USE_BACKREF_WITH_LEVEL) {
Ptr rbackNum = new Ptr();
Ptr rlevel = new Ptr();
token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
token.setBackrefLevel(rlevel.p);
backNum = rbackNum.p;
} else {
backNum = fetchName(c, true);
} // USE_BACKREF_AT_LEVEL
int nameEnd = value; // set by fetchNameWithLevel/fetchName
if (backNum != 0) {
if (backNum < 0) {
backNum = backrefRelToAbs(backNum);
if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
}
if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
newValueException(ERR_INVALID_BACKREF);
}
token.type = TokenType.BACKREF;
token.setBackrefByName(false);
token.setBackrefNum(1);
token.setBackrefRef1(backNum);
} else {
NameEntry e = env.reg.nameToGroupNumbers(chars, last, nameEnd);
if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
if (syntax.strictCheckBackref()) {
if (e.backNum == 1) {
if (e.backRef1 > env.numMem ||
env.memNodes == null ||
env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
} else {
for (int i=0; i<e.backNum; i++) {
if (e.backRefs[i] > env.numMem ||
env.memNodes == null ||
env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
}
}
}
token.type = TokenType.BACKREF;
token.setBackrefByName(true);
if (e.backNum == 1) {
token.setBackrefNum(1);
token.setBackrefRef1(e.backRef1);
} else {
token.setBackrefNum(e.backNum);
token.setBackrefRefs(e.backRefs);
}
}
} else {
unfetch();
syntaxWarn(Warnings.INVALID_BACKREFERENCE);
}
} else {
syntaxWarn(Warnings.INVALID_BACKREFERENCE);
}
}
}
private void fetchTokenFor_subexpCall() {
if (syntax.op2EscGSubexpCall()) {
if (left()) {
@ -937,25 +613,6 @@ class Lexer extends ScannerSupport {
}
}
private void fetchTokenFor_charProperty() {
if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
inc();
token.type = TokenType.CHAR_PROPERTY;
token.setPropNot(c == 'P');
if (syntax.op2EscPBraceCircumflexNot()) {
fetch();
if (c == '^') {
token.setPropNot(!token.getPropNot());
} else {
unfetch();
}
}
} else {
syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
}
}
private void fetchTokenFor_metaChars() {
if (c == syntax.metaCharTable.anyChar) {
token.type = TokenType.ANYCHAR;
@ -1091,19 +748,6 @@ class Lexer extends ScannerSupport {
case '0':
fetchTokenFor_zero();
break;
case 'k':
if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
break;
case 'g':
if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
break;
case 'Q':
if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
break;
case 'p':
case 'P':
fetchTokenFor_charProperty();
break;
default:
unfetch();
@ -1244,24 +888,6 @@ class Lexer extends ScannerSupport {
}
}
protected final int fetchCharPropertyToCType() {
mark();
while (left()) {
int last = p;
fetch();
if (c == '}') {
String name = new String(chars, _p, last - _p);
return PosixBracket.propertyNameToCType(name);
} else if (c == '(' || c == ')' || c == '{' || c == '|') {
String name = new String(chars, _p, last - _p);
throw new JOniException(ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
}
}
newInternalException(ERR_PARSER_BUG);
return 0; // not reached
}
protected final void syntaxWarn(String message, char c) {
syntaxWarn(message.replace("<%n>", Character.toString(c)));
}

View File

@ -58,17 +58,10 @@ public abstract class Matcher extends IntHolder {
// main matching method
protected abstract int matchAt(int range, int sstart, int sprev);
protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
protected abstract void stateCheckBuffClear();
public final Region getRegion() {
return msaRegion;
}
public final Region getEagerRegion() {
return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
}
public final int getBegin() {
return msaBegin;
}
@ -86,11 +79,6 @@ public abstract class Matcher extends IntHolder {
public final int match(int at, int range, int option) {
msaInit(option, at);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
int offset = at = str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
} // USE_COMBINATION_EXPLOSION_CHECK
int prev = EncodingHelper.prevCharHead(str, at);
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
@ -377,8 +365,6 @@ public abstract class Matcher extends IntHolder {
prev = -1;
msaInit(option, start);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) stateCheckBuffClear();
if (matchCheck(end, s, prev)) return match(s);
return mismatch();
}
@ -393,10 +379,6 @@ public abstract class Matcher extends IntHolder {
}
msaInit(option, origStart);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
int offset = Math.min(start, range) - str;
stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
}
s = start;
if (range > start) { /* forward search */

View File

@ -1,97 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public final class NameEntry {
static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
public final char[] name;
public final int nameP;
public final int nameEnd;
int backNum;
int backRef1;
int backRefs[];
public NameEntry(char[] chars, int p, int end) {
name = chars;
nameP = p;
nameEnd = end;
}
public int[] getBackRefs() {
switch (backNum) {
case 0:
return new int[]{};
case 1:
return new int[]{backRef1};
default:
int[]result = new int[backNum];
System.arraycopy(backRefs, 0, result, 0, backNum);
return result;
}
}
private void alloc() {
backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
}
private void ensureSize() {
if (backNum > backRefs.length) {
int[]tmp = new int[backRefs.length << 1];
System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
backRefs = tmp;
}
}
public void addBackref(int backRef) {
backNum++;
switch (backNum) {
case 1:
backRef1 = backRef;
break;
case 2:
alloc();
backRefs[0] = backRef1;
backRefs[1] = backRef;
break;
default:
ensureSize();
backRefs[backNum - 1] = backRef;
}
}
public String toString() {
StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
if (backNum == 0) {
buff.append("-");
} else if (backNum == 1){
buff.append(backRef1);
} else {
for (int i=0; i<backNum; i++){
if (i > 0) buff.append(", ");
buff.append(backRefs[i]);
}
}
return buff.toString();
}
}

View File

@ -1,27 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
public abstract class NativeMachine extends Matcher {
protected NativeMachine(Regex regex, char[] chars, int p, int end) {
super(regex, chars, p, end);
}
}

View File

@ -19,20 +19,15 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@ -66,65 +61,6 @@ class Parser extends Lexer {
return root;
}
private static final int POSIX_BRACKET_NAME_MIN_LEN = 4;
private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH = 20;
private static final char BRACKET_END[] = ":]".toCharArray();
private boolean parsePosixBracket(CClassNode cc) {
mark();
boolean not;
if (peekIs('^')) {
inc();
not = true;
} else {
not = false;
}
if (stop - p >= POSIX_BRACKET_NAME_MIN_LEN + 3) { // else goto not_posix_bracket
char[][] pbs = PosixBracket.PBSNamesLower;
for (int i=0; i<pbs.length; i++) {
char[] name = pbs[i];
// hash lookup here ?
if (EncodingHelper.strNCmp(chars, p, stop, name, 0, name.length) == 0) {
p += name.length;
if (EncodingHelper.strNCmp(chars, p, stop, BRACKET_END, 0, BRACKET_END.length) != 0) {
newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
}
cc.addCType(PosixBracket.PBSValues[i], not, env, this);
inc();
inc();
return false;
}
}
}
// not_posix_bracket:
c = 0;
int i= 0;
while (left() && ((c=peek()) != ':') && c != ']') {
inc();
if (++i > POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
}
if (c == ':' && left()) {
inc();
if (left()) {
fetch();
if (c == ']') newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
}
}
restore();
return true; /* 1: is not POSIX bracket, but no error. */
}
private CClassNode parseCharProperty() {
int ctype = fetchCharPropertyToCType();
CClassNode n = new CClassNode();
n.addCType(ctype, false, env, this);
if (token.getPropNot()) n.setNot();
return n;
}
private boolean codeExistCheck(int code, boolean ignoreEscaped) {
mark();
@ -225,29 +161,11 @@ class Parser extends Lexer {
parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
break;
case POSIX_BRACKET_OPEN:
if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
env.ccEscWarn("[");
p = token.backP;
arg.v = token.getC();
arg.vIsRaw = false;
parseCharClassValEntry(cc, arg); // goto val_entry
break;
}
cc.nextStateClass(arg, env); // goto next_class
break;
case CHAR_TYPE:
cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
cc.nextStateClass(arg, env); // next_class:
break;
case CHAR_PROPERTY:
int ctype = fetchCharPropertyToCType();
cc.addCType(ctype, token.getPropNot(), env, this);
cc.nextStateClass(arg, env); // goto next_class
break;
case CC_RANGE:
if (arg.state == CCSTATE.VALUE) {
fetchTokenInCC();
@ -413,15 +331,6 @@ class Parser extends Lexer {
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
break;
case '\'':
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
listCapture = false; // goto named_group1
node = parseEncloseNamedGroup2(listCapture);
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} // USE_NAMED_GROUP
break;
case '<': /* look behind (?<=...), (?<!...) */
fetch();
@ -430,36 +339,12 @@ class Parser extends Lexer {
} else if (c == '!') {
node = new AnchorNode(AnchorType.LOOK_BEHIND_NOT);
} else {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
unfetch();
c = '<';
listCapture = false; // named_group1:
node = parseEncloseNamedGroup2(listCapture); // named_group2:
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} else { // USE_NAMED_GROUP
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // USE_NAMED_GROUP
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
case '@':
if (syntax.op2AtMarkCaptureHistory()) {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
fetch();
if (c == '<' || c == '\'') {
listCapture = true;
node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
}
unfetch();
}
} // USE_NAMED_GROUP
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
EncloseNode en = new EncloseNode(); // node_new_enclose_memory
int num = env.addMemEntry();
if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
en.regNum = num;
@ -546,7 +431,7 @@ class Parser extends Lexer {
returnCode = 1; /* group */
return node;
}
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
EncloseNode en = new EncloseNode(); // node_new_enclose_memory
int num = env.addMemEntry();
en.regNum = num;
node = en;
@ -570,48 +455,6 @@ class Parser extends Lexer {
return node; // ??
}
private Node parseEncloseNamedGroup2(boolean listCapture) {
int nm = p;
int num = fetchName(c, false);
int nameEnd = value;
num = env.addMemEntry();
if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
regex.nameAdd(chars, nm, nameEnd, num, syntax);
EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
en.regNum = num;
Node node = en;
if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
env.numNamed++;
return node;
}
private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
int x;
int q;
int p = from;
int i = 0;
while (p < to) {
x = chars[p];
q = p + 1;
if (x == s[0]) {
for (i=1; i<n && q<to; i++) {
x = chars[q];
if (x != s[i]) break;
q++;
}
if (i >= n) {
if (chars[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
return p;
}
}
p = q;
}
return -1;
}
private Node parseExp(TokenType term) {
if (token.type == term) return StringNode.EMPTY; // goto end_of_token
@ -656,16 +499,6 @@ class Parser extends Lexer {
node = new StringNode(buf, 0, 1);
break;
case QUOTE_OPEN:
int[] endOp = new int[] {syntax.metaCharTable.esc, 'E'};
int qstart = p;
Ptr nextChar = new Ptr();
int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
if (qend == -1) nextChar.p = qend = stop;
node = new StringNode(chars, qstart, qend);
p = nextChar.p;
break;
case CHAR_TYPE:
switch(token.getPropCType()) {
case CharacterType.D:
@ -679,10 +512,6 @@ class Parser extends Lexer {
}
break;
case CharacterType.WORD:
node = new CTypeNode(token.getPropCType(), token.getPropNot());
break;
case CharacterType.SPACE:
case CharacterType.DIGIT:
case CharacterType.XDIGIT:
@ -699,10 +528,6 @@ class Parser extends Lexer {
} // inner switch
break;
case CHAR_PROPERTY:
node = parseCharProperty();
break;
case CC_CC_OPEN:
CClassNode cc = parseCharClass();
node = cc;
@ -735,20 +560,6 @@ class Parser extends Lexer {
token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
token.getBackrefLevel(), // ...
env);
break;
case CALL:
if (Config.USE_SUBEXP_CALL) {
int gNum = token.getCallGNum();
if (gNum < 0) {
gNum = backrefRelToAbs(gNum);
if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
}
node = new CallNode(chars, token.getCallNameP(), token.getCallNameEnd(), gNum);
env.numCall++;
} // USE_SUBEXP_CALL
break;
case ANCHOR:

View File

@ -23,9 +23,11 @@ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Iterator;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
@ -44,7 +46,6 @@ public final class Regex implements RegexState {
int numMem; /* used memory(...) num counted from 1 */
int numRepeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
int numNullCheck; /* OP_NULL_CHECK_START/END id counter */
int numCombExpCheck; /* combination explosion check */
int numCall; /* number of subexp call */
int captureHistory; /* (?@...) flag (1-31) */
int btMemStart; /* need backtrack flag */
@ -57,7 +58,7 @@ public final class Regex implements RegexState {
WarnCallback warnings;
MatcherFactory factory;
private Analyser analyser;
protected Analyser analyser;
int options;
int userOptions;
@ -65,8 +66,6 @@ public final class Regex implements RegexState {
//final Syntax syntax;
final int caseFoldFlag;
HashMap<String,NameEntry> nameTable; // named entries
/* optimization info (string search, char-map and anchors) */
SearchAlgorithm searchAlgorithm; /* optimize flag */
int thresholdLength; /* search str-length for apply optimize */
@ -172,112 +171,6 @@ public final class Regex implements RegexState {
return numMem;
}
public int numberOfCaptureHistories() {
if (Config.USE_CAPTURE_HISTORY) {
int n = 0;
for (int i=0; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
if (bsAt(captureHistory, i)) n++;
}
return n;
} else {
return 0;
}
}
String nameTableToString() {
StringBuilder sb = new StringBuilder();
if (nameTable != null) {
sb.append("name table\n");
for (NameEntry ne : nameTable.values()) {
sb.append(" " + ne + "\n");
}
sb.append("\n");
}
return sb.toString();
}
NameEntry nameFind(char[] name, int nameP, int nameEnd) {
if (nameTable != null) return nameTable.get(new String(name, nameP, nameEnd - nameP));
return null;
}
void renumberNameTable(int[]map) {
if (nameTable != null) {
for (NameEntry e : nameTable.values()) {
if (e.backNum > 1) {
for (int i=0; i<e.backNum; i++) {
e.backRefs[i] = map[e.backRefs[i]];
}
} else if (e.backNum == 1) {
e.backRef1 = map[e.backRef1];
}
}
}
}
public int numberOfNames() {
return nameTable == null ? 0 : nameTable.size();
}
void nameAdd(char[] name, int nameP, int nameEnd, int backRef, Syntax syntax) {
if (nameEnd - nameP <= 0) throw new ValueException(ErrorMessages.ERR_EMPTY_GROUP_NAME);
NameEntry e = null;
if (nameTable == null) {
nameTable = new HashMap<String,NameEntry>(); // 13, oni defaults to 5
} else {
e = nameFind(name, nameP, nameEnd);
}
if (e == null) {
// dup the name here as oni does ?, what for ? (it has to manage it, we don't)
e = new NameEntry(name, nameP, nameEnd);
nameTable.put(new String(name, nameP, nameEnd - nameP), e);
} else if (e.backNum >= 1 && !syntax.allowMultiplexDefinitionName()) {
throw new ValueException(ErrorMessages.ERR_MULTIPLEX_DEFINED_NAME, new String(name, nameP, nameEnd - nameP));
}
e.addBackref(backRef);
}
NameEntry nameToGroupNumbers(char[] name, int nameP, int nameEnd) {
return nameFind(name, nameP, nameEnd);
}
public int nameToBackrefNumber(char[] name, int nameP, int nameEnd, Region region) {
NameEntry e = nameToGroupNumbers(name, nameP, nameEnd);
if (e == null) throw new ValueException(ErrorMessages.ERR_UNDEFINED_NAME_REFERENCE,
new String(name, nameP, nameEnd - nameP));
switch(e.backNum) {
case 0:
throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
case 1:
return e.backRef1;
default:
if (region != null) {
for (int i = e.backNum - 1; i >= 0; i--) {
if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
}
}
return e.backRefs[e.backNum - 1];
}
}
public Iterator<NameEntry> namedBackrefIterator() {
return nameTable.values().iterator();
}
public boolean noNameGroupIsActive(Syntax syntax) {
if (isDontCaptureGroup(options)) return false;
if (Config.USE_NAMED_GROUP) {
if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
}
return true;
}
/* set skip map for Boyer-Moor search */
void setupBMSkipMap() {
char[] chars = exact;
@ -353,16 +246,6 @@ public final class Regex implements RegexState {
exactP = exactEnd = 0;
}
public String encStringToString(byte[]bytes, int p, int end) {
StringBuilder sb = new StringBuilder("\nPATTERN: /");
while (p < end) {
sb.append(new String(new byte[]{bytes[p]}));
p++;
}
return sb.append("/").toString();
}
public String optimizeInfoToString() {
String s = "";
s += "optimize: " + searchAlgorithm.getName() + "\n";
@ -410,19 +293,13 @@ public final class Regex implements RegexState {
return options;
}
public void setUserOptions(int options) {
this.userOptions = options;
public String dumpTree() {
return analyser == null ? null : analyser.root.toString();
}
public int getUserOptions() {
return userOptions;
public String dumpByteCode() {
compile();
return new ByteCodePrinter(this).byteCodeListToString();
}
public void setUserObject(Object object) {
this.userObject = object;
}
public Object getUserObject() {
return userObject;
}
}

View File

@ -25,7 +25,6 @@ public final class Region {
public final int numRegs;
public final int[]beg;
public final int[]end;
public CaptureTreeNode historyRoot;
public Region(int num) {
this.numRegs = num;
@ -33,20 +32,6 @@ public final class Region {
this.end = new int[num];
}
public Region(int begin, int end) {
this.numRegs = 1;
this.beg = new int[]{begin};
this.end = new int[]{end};
}
public Region clone() {
Region region = new Region(numRegs);
System.arraycopy(beg, 0, region.beg, 0, beg.length);
System.arraycopy(end, 0, region.end, 0, end.length);
if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
return region;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");
@ -54,10 +39,6 @@ public final class Region {
return sb.toString();
}
CaptureTreeNode getCaptureTree() {
return historyRoot;
}
void clear() {
for (int i=0; i<beg.length; i++) {
beg[i] = end[i] = REGION_NOTPOS;

View File

@ -40,16 +40,10 @@ public final class ScanEnvironment {
final public Regex reg;
int numCall;
UnsetAddrList unsetAddrList; // USE_SUBEXP_CALL
public int numMem;
int numNamed; // USE_NAMED_GROUP
public Node memNodes[];
// USE_COMBINATION_EXPLOSION_CHECK
int numCombExpCheck;
int combExpMaxRegNum;
int currMaxRegNum;
boolean hasRecursion;
@ -69,12 +63,8 @@ public final class ScanEnvironment {
numCall = 0;
numMem = 0;
numNamed = 0;
memNodes = null;
numCombExpCheck = 0;
combExpMaxRegNum = 0;
currMaxRegNum = 0;
hasRecursion = false;
}

View File

@ -37,6 +37,8 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
private final int end; // pattern end position for reset() support
protected int _p; // used by mark()/restore() to mark positions
private final static int INT_SIGN_BIT = 1 << 31;
protected ScannerSupport(char[] chars, int p, int end) {
this.chars = chars;
this.begin = p;
@ -53,8 +55,6 @@ abstract class ScannerSupport extends IntHolder implements ErrorMessages {
return end;
}
private final int INT_SIGN_BIT = 1 << 31;
protected final int scanUnsignedNumber() {
int last = c;
int num = 0; // long ???

View File

@ -22,7 +22,6 @@ package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
@ -36,10 +35,6 @@ abstract class StackMachine extends Matcher implements StackType {
protected final int[]repeatStk;
protected final int memStartStk, memEndStk;
// CEC
protected byte[] stateCheckBuff; // move to int[] ?
int stateCheckBuffSize;
protected StackMachine(Regex regex, char[] chars, int p , int end) {
super(regex, chars, p, end);
@ -104,67 +99,12 @@ abstract class StackMachine extends Matcher implements StackType {
stk++;
}
// CEC
// STATE_CHECK_POS
private int stateCheckPos(int s, int snum) {
return (s - str) * regex.numCombExpCheck + (snum - 1);
}
// STATE_CHECK_VAL
protected final boolean stateCheckVal(int s, int snum) {
if (stateCheckBuff != null) {
int x = stateCheckPos(s, snum);
return (stateCheckBuff[x / 8] & (1 << (x % 8))) != 0;
}
return false;
}
// ELSE_IF_STATE_CHECK_MARK
private void stateCheckMark() {
StackEntry e = stack[stk];
int x = stateCheckPos(e.getStatePStr(), e.getStateCheck());
stateCheckBuff[x / 8] |= (1 << (x % 8));
}
// STATE_CHECK_BUFF_INIT
private static final int STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE = 16;
protected final void stateCheckBuffInit(int strLength, int offset, int stateNum) {
if (stateNum > 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
int size = ((strLength + 1) * stateNum + 7) >>> 3;
offset = (offset * stateNum) >>> 3;
if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
stateCheckBuff = new byte[size];
} else {
// same impl, reduce...
stateCheckBuff = new byte[size];
}
Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
stateCheckBuffSize = size;
} else {
stateCheckBuff = null; // reduce
stateCheckBuffSize = 0;
}
} else {
stateCheckBuff = null; // reduce
stateCheckBuffSize = 0;
}
}
protected final void stateCheckBuffClear() {
stateCheckBuff = null;
stateCheckBuffSize = 0;
}
private void push(int type, int pat, int s, int prev) {
StackEntry e = ensure1();
e.type = type;
e.setStatePCode(pat);
e.setStatePStr(s);
e.setStatePStrPrev(prev);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
@ -172,30 +112,9 @@ abstract class StackMachine extends Matcher implements StackType {
StackEntry e = stack[stk];
e.type = type;
e.setStatePCode(pat);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
StackEntry e = ensure1();
e.type = ALT;
e.setStatePCode(pat);
e.setStatePStr(s);
e.setStatePStrPrev(sprev);
if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
stk++;
}
protected final void pushStateCheck(int s, int snum) {
if (stateCheckBuff != null) {
StackEntry e = ensure1();
e.type = STATE_CHECK_MARK;
e.setStatePStr(s);
e.setStateCheck(snum);
stk++;
}
}
protected final void pushAlt(int pat, int s, int prev) {
push(ALT, pat, s, prev);
}
@ -294,19 +213,6 @@ abstract class StackMachine extends Matcher implements StackType {
stk++;
}
protected final void pushCallFrame(int pat) {
StackEntry e = ensure1();
e.type = CALL_FRAME;
e.setCallFrameRetAddr(pat);
stk++;
}
protected final void pushReturn() {
StackEntry e = ensure1();
e.type = RETURN;
stk++;
}
// stack debug routines here
// ...
@ -331,8 +237,6 @@ abstract class StackMachine extends Matcher implements StackType {
if ((e.type & MASK_POP_USED) != 0) {
return e;
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@ -346,8 +250,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@ -368,8 +270,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@ -391,8 +291,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END){
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@ -414,8 +312,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
} else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}

View File

@ -609,7 +609,7 @@ public final class Syntax implements SyntaxProperties{
OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL | OP_ESC_X_HEX2)
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
( OP2_QMARK_GROUP_EFFECT | OP2_CCLASS_SET_OP |
( OP2_QMARK_GROUP_EFFECT |
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 ),
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),

View File

@ -1,69 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
public final class UnsetAddrList {
int num;
Node[]targets;
int[]offsets;
public UnsetAddrList(int size) {
targets = new Node[size];
offsets = new int[size];
}
public void add(int offset, Node node) {
if (num >= offsets.length) {
Node []ttmp = new Node[targets.length << 1];
System.arraycopy(targets, 0, ttmp, 0, num);
targets = ttmp;
int[]otmp = new int[offsets.length << 1];
System.arraycopy(offsets, 0, otmp, 0, num);
offsets = otmp;
}
targets[num] = node;
offsets[num] = offset;
num++;
}
public void fix(Regex regex) {
for (int i=0; i<num; i++) {
EncloseNode en = (EncloseNode)targets[i];
if (!en.isAddrFixed()) new InternalException(ErrorMessages.ERR_PARSER_BUG);
regex.code[offsets[i]] = en.callAddr; // is this safe ?
}
}
public String toString() {
StringBuilder value = new StringBuilder();
if (num > 0) {
for (int i=0; i<num; i++) {
value.append("offset + " + offsets[i] + " target: " + targets[i].getAddressName());
}
}
return value.toString();
}
}

View File

@ -22,7 +22,6 @@ package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.*;
import jdk.nashorn.internal.runtime.regexp.joni.constants.CCSTATE;
import jdk.nashorn.internal.runtime.regexp.joni.constants.CCVALTYPE;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.AsciiTables;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
@ -40,6 +39,41 @@ public final class CClassNode extends Node {
private int ctype; // for hashing purposes
private final static short AsciiCtypeTable[] = {
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
// node_new_cclass
public CClassNode() {}
@ -330,13 +364,13 @@ public final class CClassNode extends Node {
if (not) {
for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
// if (!ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
if ((AsciiCtypeTable[c] & (1 << ctype)) == 0) bs.set(c);
}
addAllMultiByteRange();
} else {
for (int c = 0; c < BitSet.SINGLE_BYTE_SIZE; c++) {
// if (ASCIIEncoding.INSTANCE.isCodeCType(c, ctype)) bs.set(c);
if ((AsciiTables.AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
if ((AsciiCtypeTable[c] & (1 << ctype)) != 0) bs.set(c);
}
}
return;

View File

@ -1,50 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
public final class CTypeNode extends Node {
public int ctype;
public boolean not;
public CTypeNode(int type, boolean not) {
this.ctype= type;
this.not = not;
}
@Override
public int getType() {
return CTYPE;
}
@Override
public String getName() {
return "Character Type";
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder();
value.append("\n ctype: " + ctype);
value.append("\n not: " + not);
return value.toString();
}
}

View File

@ -1,86 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import java.util.Set;
import jdk.nashorn.internal.runtime.regexp.joni.UnsetAddrList;
import jdk.nashorn.internal.runtime.regexp.joni.WarnCallback;
public final class CallNode extends StateNode {
public char[] name;
public int nameP;
public int nameEnd;
public int groupNum;
public Node target; // is it an EncloseNode always ?
public UnsetAddrList unsetAddrList;
public CallNode(char[] name, int nameP, int nameEnd, int gnum) {
this.name = name;
this.nameP = nameP;
this.nameEnd = nameEnd;
this.groupNum = gnum; /* call by number if gnum != 0 */
}
@Override
public int getType() {
return CALL;
}
@Override
protected void setChild(Node newChild) {
target = newChild;
}
@Override
protected Node getChild() {
return target;
}
public void setTarget(Node tgt) {
target = tgt;
tgt.parent = this;
}
@Override
public String getName() {
return "Call";
}
@Override
public void verifyTree(Set<Node> set, WarnCallback warnings) {
if (target == null || target.parent == this)
warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
// do not recurse here
}
@Override
public String toString(int level) {
StringBuilder value = new StringBuilder(super.toString(level));
value.append("\n name: " + new String(name, nameP, nameEnd - nameP));
value.append("\n groupNum: " + groupNum);
value.append("\n target: " + pad(target.getAddressName(), level + 1));
value.append("\n unsetAddrList: " + pad(unsetAddrList, level + 1));
return value.toString();
}
}

View File

@ -25,7 +25,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
public final class EncloseNode extends StateNode implements EncloseType {
public int type; // enclose type
public final int type; // enclose type
public int regNum;
public int option;
public Node target; /* EncloseNode : ENCLOSE_MEMORY */
@ -42,10 +42,8 @@ public final class EncloseNode extends StateNode implements EncloseType {
}
// node_new_enclose_memory
public EncloseNode(int option, boolean isNamed) {
public EncloseNode() {
this(MEMORY);
if (isNamed) setNamedGroup();
if (Config.USE_SUBEXP_CALL) this.option = option;
}
// node_new_option
@ -104,46 +102,14 @@ public final class EncloseNode extends StateNode implements EncloseType {
return types.toString();
}
public void setEncloseStatus(int flag) {
state |= flag;
}
public void clearEncloseStatus(int flag) {
state &= ~flag;
}
public void clearMemory() {
type &= ~MEMORY;
}
public void setMemory() {
type |= MEMORY;
}
public boolean isMemory() {
return (type & MEMORY) != 0;
}
public void clearOption() {
type &= ~OPTION;
}
public void setOption() {
type |= OPTION;
}
public boolean isOption() {
return (type & OPTION) != 0;
}
public void clearStopBacktrack() {
type &= ~STOP_BACKTRACK;
}
public void setStopBacktrack() {
type |= STOP_BACKTRACK;
}
public boolean isStopBacktrack() {
return (type & STOP_BACKTRACK) != 0;
}

View File

@ -21,9 +21,10 @@ package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
import jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.*;
public final class QuantifierNode extends StateNode {
public Node target;
@ -37,8 +38,33 @@ public final class QuantifierNode extends StateNode {
public Node nextHeadExact;
public boolean isRefered; /* include called node. don't eliminate even if {0} */
// USE_COMBINATION_EXPLOSION_CHECK
public int combExpCheckNum; /* 1,2,3...: check, 0: no check */
enum ReduceType {
ASIS, /* as is */
DEL, /* delete parent */
A, /* to '*' */
AQ, /* to '*?' */
QQ, /* to '??' */
P_QQ, /* to '+)??' */
PQ_Q, /* to '+?)?' */
}
private final static ReduceType[][] REDUCE_TABLE = {
{DEL, A, A, QQ, AQ, ASIS}, /* '?' */
{DEL, DEL, DEL, P_QQ, P_QQ, DEL}, /* '*' */
{A, A, DEL, ASIS, P_QQ, DEL}, /* '+' */
{DEL, AQ, AQ, DEL, AQ, AQ}, /* '??' */
{DEL, DEL, DEL, DEL, DEL, DEL}, /* '*?' */
{ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
};
private final static String PopularQStr[] = new String[] {
"?", "*", "+", "??", "*?", "+?"
};
private final static String ReduceQStr[]= new String[] {
"", "", "*", "*?", "??", "+ and ??", "+? and ?"
};
public QuantifierNode(int lower, int upper, boolean byNumber) {
this.lower = lower;
@ -92,7 +118,6 @@ public final class QuantifierNode extends StateNode {
value.append("\n headExact: " + pad(headExact, level + 1));
value.append("\n nextHeadExact: " + pad(nextHeadExact, level + 1));
value.append("\n isRefered: " + isRefered);
value.append("\n combExpCheckNum: " + combExpCheckNum);
return value.toString();
}
@ -134,7 +159,6 @@ public final class QuantifierNode extends StateNode {
headExact = other.headExact;
nextHeadExact = other.nextHeadExact;
isRefered = other.isRefered;
combExpCheckNum = other.combExpCheckNum;
}
public void reduceNestedQuantifier(QuantifierNode other) {
@ -143,7 +167,7 @@ public final class QuantifierNode extends StateNode {
if (pnum < 0 || cnum < 0) return;
switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
switch(REDUCE_TABLE[cnum][pnum]) {
case DEL:
// no need to set the parent here...
// swap ?
@ -226,7 +250,7 @@ public final class QuantifierNode extends StateNode {
if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
switch(REDUCE_TABLE[targetQNum][nestQNum]) {
case ASIS:
break;
@ -237,9 +261,9 @@ public final class QuantifierNode extends StateNode {
default:
env.reg.getWarnings().warn(new String(chars, p, end) +
" nested repeat operator " + Reduce.PopularQStr[targetQNum] +
" and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
" nested repeat operator " + PopularQStr[targetQNum] +
" and " + PopularQStr[nestQNum] + " was replaced with '" +
ReduceQStr[REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
}
}
} // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR

View File

@ -40,7 +40,6 @@ public abstract class StateNode extends Node implements NodeStatus {
if (isRecursion()) states.append("RECURSION ");
if (isCalled()) states.append("CALLED ");
if (isAddrFixed()) states.append("ADDR_FIXED ");
if (isNamedGroup()) states.append("NAMED_GROUP ");
if (isNameRef()) states.append("NAME_REF ");
if (isInRepeat()) states.append("IN_REPEAT ");
if (isNestLevel()) states.append("NEST_LEVEL ");
@ -57,10 +56,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MIN_FIXED;
}
public void clearMinFixed() {
state &= ~NST_MIN_FIXED;
}
public boolean isMaxFixed() {
return (state & NST_MAX_FIXED) != 0;
}
@ -69,10 +64,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MAX_FIXED;
}
public void clearMaxFixed() {
state &= ~NST_MAX_FIXED;
}
public boolean isCLenFixed() {
return (state & NST_CLEN_FIXED) != 0;
}
@ -81,10 +72,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_CLEN_FIXED;
}
public void clearCLenFixed() {
state &= ~NST_CLEN_FIXED;
}
public boolean isMark1() {
return (state & NST_MARK1) != 0;
}
@ -93,10 +80,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MARK1;
}
public void clearMark1() {
state &= ~NST_MARK1;
}
public boolean isMark2() {
return (state & NST_MARK2) != 0;
}
@ -117,10 +100,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MEM_BACKREFED;
}
public void clearMemBackrefed() {
state &= ~NST_MEM_BACKREFED;
}
public boolean isStopBtSimpleRepeat() {
return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
}
@ -129,10 +108,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_STOP_BT_SIMPLE_REPEAT;
}
public void clearStopBtSimpleRepeat() {
state &= ~NST_STOP_BT_SIMPLE_REPEAT;
}
public boolean isRecursion() {
return (state & NST_RECURSION) != 0;
}
@ -141,10 +116,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_RECURSION;
}
public void clearRecursion() {
state &= ~NST_RECURSION;
}
public boolean isCalled() {
return (state & NST_CALLED) != 0;
}
@ -153,10 +124,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_CALLED;
}
public void clearCAlled() {
state &= ~NST_CALLED;
}
public boolean isAddrFixed() {
return (state & NST_ADDR_FIXED) != 0;
}
@ -165,22 +132,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_ADDR_FIXED;
}
public void clearAddrFixed() {
state &= ~NST_ADDR_FIXED;
}
public boolean isNamedGroup() {
return (state & NST_NAMED_GROUP) != 0;
}
public void setNamedGroup() {
state |= NST_NAMED_GROUP;
}
public void clearNamedGroup() {
state &= ~NST_NAMED_GROUP;
}
public boolean isNameRef() {
return (state & NST_NAME_REF) != 0;
}
@ -189,10 +140,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_NAME_REF;
}
public void clearNameRef() {
state &= ~NST_NAME_REF;
}
public boolean isInRepeat() {
return (state & NST_IN_REPEAT) != 0;
}
@ -201,10 +148,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_IN_REPEAT;
}
public void clearInRepeat() {
state &= ~NST_IN_REPEAT;
}
public boolean isNestLevel() {
return (state & NST_NEST_LEVEL) != 0;
}
@ -213,10 +156,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_NEST_LEVEL;
}
public void clearNestLevel() {
state &= ~NST_NEST_LEVEL;
}
public boolean isByNumber() {
return (state & NST_BY_NUMBER) != 0;
}
@ -225,8 +164,4 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_BY_NUMBER;
}
public void clearByNumber() {
state &= ~NST_BY_NUMBER;
}
}

View File

@ -1,49 +0,0 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.Regex;
import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
public abstract class AbstractBench {
protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
char[] reg = _reg.toCharArray();
char[] str = _str.toCharArray();
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
for(int j=0;j<warmup;j++) {
long before = System.currentTimeMillis();
for(int i = 0; i < times; i++) {
p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
}
long time = System.currentTimeMillis() - before;
System.err.println(": " + time + "ms");
}
}
protected void benchBestOf(String _reg, String _str, int warmup, int times) throws Exception {
char[] reg = _reg.toCharArray();
char[] str = _str.toCharArray();
Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
long best = Long.MAX_VALUE;
for(int j=0;j<warmup;j++) {
long before = System.currentTimeMillis();
for(int i = 0; i < times; i++) {
p.matcher(str, 0, str.length).search(0, str.length, Option.NONE);
}
long time = System.currentTimeMillis() - before;
if(time < best) {
best = time;
}
System.err.print(".");
}
System.err.println(": " + best + "ms");
}
}

View File

@ -1,7 +0,0 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchGreedyBacktrack extends AbstractBench {
public static void main(String[] args) throws Exception {
new BenchGreedyBacktrack().bench(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,1000000);
}
}

View File

@ -1,31 +0,0 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchRailsRegs extends AbstractBench {
public static void main(String[] args) throws Exception {
final String[][] regexps = {{"a.*?[b-z]{2,4}aaaaaa","afdgdsgderaabxxaaaaaaaaaaaaaaaaaaaaaaaa"},
{"://","/shop/viewCategory.shtml?category=DOGS"},
{"^\\w+\\://[^/]+(/.*|$)$","/shop/viewCategory.shtml?category=DOGS"},
{"\\A/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/signonForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/newAccountForm\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/newAccount\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/viewCart\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/index\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A/shop/viewCategory\\.shtml/?\\Z","/shop/viewCategory.shtml"},
{"\\A(?:::)?([A-Z]\\w*(?:::[A-Z]\\w*)*)\\z","CategoriesController"},
{"\\Ainsert","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7') LIMIT 1"},
{"\\A\\(?\\s*(select|show)","SELECT * FROM sessions WHERE (session_id = '1b341ffe23b5298676d535fcabd3d0d7') LIMIT 1"},
{".*?\n","1b341ffe23b5298676d535fcabd3d0d7"},
{"^find_(all_by|by)_([_a-zA-Z]\\w*)$","find_by_string_id"},
{"\\.rjs$","categories/show.rhtml"},
{"^[-a-z]+://","petstore.css"},
{"^get$",""},
{"^post$",""},
{"^[^:]+","www.example.com"},
{"(=|\\?|_before_type_cast)$", "updated_on"},
{"^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/"}};
for(String[] reg : regexps) {
new BenchRailsRegs().benchBestOf(reg[0],reg[1],10,1000000);
}
}
}

View File

@ -1,17 +0,0 @@
package jdk.nashorn.internal.runtime.regexp.joni.bench;
public class BenchSeveralRegexps extends AbstractBench {
public static void main(String[] args) throws Exception {
int BASE = 1000000;
new BenchSeveralRegexps().benchBestOf("a"," a",10,4*BASE);
new BenchSeveralRegexps().benchBestOf(".*?=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
new BenchSeveralRegexps().benchBestOf("^(.*?)=(.*?);","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,BASE);
new BenchSeveralRegexps().benchBestOf(".*_p","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
new BenchSeveralRegexps().benchBestOf(".*=","_petstore_session_id=1b341ffe23b5298676d535fcabd3d0d7; path=/",10,4*BASE);
}
}

View File

@ -19,8 +19,6 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
public interface OPCode {
final int FINISH = 0; /* matching process terminator (no more alternative) */
final int END = 1; /* pattern code terminator (success end) */
@ -151,237 +149,4 @@ public interface OPCode {
final int EXACT1_IC_SB = 105; /* single byte, N = 1, ignore case */
final int EXACTN_IC_SB = 106; /* single byte, ignore case */
public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
"finish", /*OP_FINISH*/
"end", /*OP_END*/
"exact1", /*OP_EXACT1*/
"exact2", /*OP_EXACT2*/
"exact3", /*OP_EXACT3*/
"exact4", /*OP_EXACT4*/
"exact5", /*OP_EXACT5*/
"exactn", /*OP_EXACTN*/
"exactmb2-n1", /*OP_EXACTMB2N1*/
"exactmb2-n2", /*OP_EXACTMB2N2*/
"exactmb2-n3", /*OP_EXACTMB2N3*/
"exactmb2-n", /*OP_EXACTMB2N*/
"exactmb3n", /*OP_EXACTMB3N*/
"exactmbn", /*OP_EXACTMBN*/
"exact1-ic", /*OP_EXACT1_IC*/
"exactn-ic", /*OP_EXACTN_IC*/
"cclass", /*OP_CCLASS*/
"cclass-mb", /*OP_CCLASS_MB*/
"cclass-mix", /*OP_CCLASS_MIX*/
"cclass-not", /*OP_CCLASS_NOT*/
"cclass-mb-not", /*OP_CCLASS_MB_NOT*/
"cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
"cclass-node", /*OP_CCLASS_NODE*/
"anychar", /*OP_ANYCHAR*/
"anychar-ml", /*OP_ANYCHAR_ML*/
"anychar*", /*OP_ANYCHAR_STAR*/
"anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"word", /*OP_WORD*/
"not-word", /*OP_NOT_WORD*/
"word-bound", /*OP_WORD_BOUND*/
"not-word-bound", /*OP_NOT_WORD_BOUND*/
"word-begin", /*OP_WORD_BEGIN*/
"word-end", /*OP_WORD_END*/
"begin-buf", /*OP_BEGIN_BUF*/
"end-buf", /*OP_END_BUF*/
"begin-line", /*OP_BEGIN_LINE*/
"end-line", /*OP_END_LINE*/
"semi-end-buf", /*OP_SEMI_END_BUF*/
"begin-position", /*OP_BEGIN_POSITION*/
"backref1", /*OP_BACKREF1*/
"backref2", /*OP_BACKREF2*/
"backrefn", /*OP_BACKREFN*/
"backrefn-ic", /*OP_BACKREFN_IC*/
"backref_multi", /*OP_BACKREF_MULTI*/
"backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
"backref_at_level", /*OP_BACKREF_AT_LEVEL*/
"mem-start", /*OP_MEMORY_START*/
"mem-start-push", /*OP_MEMORY_START_PUSH*/
"mem-end-push", /*OP_MEMORY_END_PUSH*/
"mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
"mem-end", /*OP_MEMORY_END*/
"mem-end-rec", /*OP_MEMORY_END_REC*/
"fail", /*OP_FAIL*/
"jump", /*OP_JUMP*/
"push", /*OP_PUSH*/
"pop", /*OP_POP*/
"push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
"push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
"repeat", /*OP_REPEAT*/
"repeat-ng", /*OP_REPEAT_NG*/
"repeat-inc", /*OP_REPEAT_INC*/
"repeat-inc-ng", /*OP_REPEAT_INC_NG*/
"repeat-inc-sg", /*OP_REPEAT_INC_SG*/
"repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
"null-check-start", /*OP_NULL_CHECK_START*/
"null-check-end", /*OP_NULL_CHECK_END*/
"null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
"null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
"push-pos", /*OP_PUSH_POS*/
"pop-pos", /*OP_POP_POS*/
"push-pos-not", /*OP_PUSH_POS_NOT*/
"fail-pos", /*OP_FAIL_POS*/
"push-stop-bt", /*OP_PUSH_STOP_BT*/
"pop-stop-bt", /*OP_POP_STOP_BT*/
"look-behind", /*OP_LOOK_BEHIND*/
"push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
"fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
"call", /*OP_CALL*/
"return", /*OP_RETURN*/
"state-check-push", /*OP_STATE_CHECK_PUSH*/
"state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
"state-check", /*OP_STATE_CHECK*/
"state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"set-option-push", /*OP_SET_OPTION_PUSH*/
"set-option", /*OP_SET_OPTION*/
// single byte versions
"anychar-sb", /*OP_ANYCHAR*/
"anychar-ml-sb", /*OP_ANYCHAR_ML*/
"anychar*-sb", /*OP_ANYCHAR_STAR*/
"anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
"anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
"anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
"state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
"state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
"cclass-sb", /*OP_CCLASS*/
"cclass-not-sb", /*OP_CCLASS_NOT*/
"word-sb", /*OP_WORD*/
"not-word-sb", /*OP_NOT_WORD*/
"word-bound-sb", /*OP_WORD_BOUND*/
"not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
"word-begin-sb", /*OP_WORD_BEGIN*/
"word-end-sb", /*OP_WORD_END*/
"look-behind-sb", /*OP_LOOK_BEHIND*/
"exact1-ic-sb", /*OP_EXACT1_IC*/
"exactn-ic-sb", /*OP_EXACTN_IC*/
} : null;
public final int OpCodeArgTypes[] = Config.DEBUG_COMPILE ? new int[] {
Arguments.NON, /*OP_FINISH*/
Arguments.NON, /*OP_END*/
Arguments.SPECIAL, /*OP_EXACT1*/
Arguments.SPECIAL, /*OP_EXACT2*/
Arguments.SPECIAL, /*OP_EXACT3*/
Arguments.SPECIAL, /*OP_EXACT4*/
Arguments.SPECIAL, /*OP_EXACT5*/
Arguments.SPECIAL, /*OP_EXACTN*/
Arguments.SPECIAL, /*OP_EXACTMB2N1*/
Arguments.SPECIAL, /*OP_EXACTMB2N2*/
Arguments.SPECIAL, /*OP_EXACTMB2N3*/
Arguments.SPECIAL, /*OP_EXACTMB2N*/
Arguments.SPECIAL, /*OP_EXACTMB3N*/
Arguments.SPECIAL, /*OP_EXACTMBN*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_MB*/
Arguments.SPECIAL, /*OP_CCLASS_MIX*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
Arguments.SPECIAL, /*OP_CCLASS_NODE*/
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.NON, /*OP_BEGIN_BUF*/
Arguments.NON, /*OP_END_BUF*/
Arguments.NON, /*OP_BEGIN_LINE*/
Arguments.NON, /*OP_END_LINE*/
Arguments.NON, /*OP_SEMI_END_BUF*/
Arguments.NON, /*OP_BEGIN_POSITION*/
Arguments.NON, /*OP_BACKREF1*/
Arguments.NON, /*OP_BACKREF2*/
Arguments.MEMNUM, /*OP_BACKREFN*/
Arguments.SPECIAL, /*OP_BACKREFN_IC*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
Arguments.MEMNUM, /*OP_MEMORY_START*/
Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
Arguments.MEMNUM, /*OP_MEMORY_END*/
Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
Arguments.NON, /*OP_FAIL*/
Arguments.RELADDR, /*OP_JUMP*/
Arguments.RELADDR, /*OP_PUSH*/
Arguments.NON, /*OP_POP*/
Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_REPEAT*/
Arguments.SPECIAL, /*OP_REPEAT_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
Arguments.NON, /*OP_PUSH_POS*/
Arguments.NON, /*OP_POP_POS*/
Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
Arguments.NON, /*OP_FAIL_POS*/
Arguments.NON, /*OP_PUSH_STOP_BT*/
Arguments.NON, /*OP_POP_STOP_BT*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
Arguments.ABSADDR, /*OP_CALL*/
Arguments.NON, /*OP_RETURN*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
Arguments.OPTION, /*OP_SET_OPTION*/
// single byte versions
Arguments.NON, /*OP_ANYCHAR*/
Arguments.NON, /*OP_ANYCHAR_ML*/
Arguments.NON, /*OP_ANYCHAR_STAR*/
Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
Arguments.SPECIAL, /*OP_CCLASS*/
Arguments.SPECIAL, /*OP_CCLASS_NOT*/
Arguments.NON, /*OP_WORD*/
Arguments.NON, /*OP_NOT_WORD*/
Arguments.NON, /*OP_WORD_BOUND*/
Arguments.NON, /*OP_NOT_WORD_BOUND*/
Arguments.NON, /*OP_WORD_BEGIN*/
Arguments.NON, /*OP_WORD_END*/
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_EXACT1_IC*/
Arguments.SPECIAL, /*OP_EXACTN_IC*/
} : null;
}

View File

@ -1,61 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.constants;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.A;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.AQ;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.ASIS;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.DEL;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.PQ_Q;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.P_QQ;
import static jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce.ReduceType.QQ;
public interface Reduce {
enum ReduceType {
ASIS, /* as is */
DEL, /* delete parent */
A, /* to '*' */
AQ, /* to '*?' */
QQ, /* to '??' */
P_QQ, /* to '+)??' */
PQ_Q, /* to '+?)?' */
}
final ReduceType[][]REDUCE_TABLE = {
{DEL, A, A, QQ, AQ, ASIS}, /* '?' */
{DEL, DEL, DEL, P_QQ, P_QQ, DEL}, /* '*' */
{A, A, DEL, ASIS, P_QQ, DEL}, /* '+' */
{DEL, AQ, AQ, DEL, AQ, AQ}, /* '??' */
{DEL, DEL, DEL, DEL, DEL, DEL}, /* '*?' */
{ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
};
final String PopularQStr[] = new String[] {
"?", "*", "+", "??", "*?", "+?"
};
String ReduceQStr[]= new String[] {
"", "", "*", "*?", "??", "+ and ??", "+? and ?"
};
}

View File

@ -1,157 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public class AsciiTables {
public static final short AsciiCtypeTable[] = {
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
public static final byte ToLowerCaseTable[] = {
(byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
(byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
(byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
(byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
(byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
(byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
(byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
(byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
(byte)'\100', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
(byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
(byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
(byte)'\170', (byte)'\171', (byte)'\172', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
(byte)'\140', (byte)'\141', (byte)'\142', (byte)'\143', (byte)'\144', (byte)'\145', (byte)'\146', (byte)'\147',
(byte)'\150', (byte)'\151', (byte)'\152', (byte)'\153', (byte)'\154', (byte)'\155', (byte)'\156', (byte)'\157',
(byte)'\160', (byte)'\161', (byte)'\162', (byte)'\163', (byte)'\164', (byte)'\165', (byte)'\166', (byte)'\167',
(byte)'\170', (byte)'\171', (byte)'\172', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
(byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
(byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
(byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
(byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
(byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
(byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
(byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
(byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
(byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
(byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
(byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
(byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
(byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
(byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
(byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
(byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
};
public static final byte ToUpperCaseTable[] = {
(byte)'\000', (byte)'\001', (byte)'\002', (byte)'\003', (byte)'\004', (byte)'\005', (byte)'\006', (byte)'\007',
(byte)'\010', (byte)'\011', (byte)'\012', (byte)'\013', (byte)'\014', (byte)'\015', (byte)'\016', (byte)'\017',
(byte)'\020', (byte)'\021', (byte)'\022', (byte)'\023', (byte)'\024', (byte)'\025', (byte)'\026', (byte)'\027',
(byte)'\030', (byte)'\031', (byte)'\032', (byte)'\033', (byte)'\034', (byte)'\035', (byte)'\036', (byte)'\037',
(byte)'\040', (byte)'\041', (byte)'\042', (byte)'\043', (byte)'\044', (byte)'\045', (byte)'\046', (byte)'\047',
(byte)'\050', (byte)'\051', (byte)'\052', (byte)'\053', (byte)'\054', (byte)'\055', (byte)'\056', (byte)'\057',
(byte)'\060', (byte)'\061', (byte)'\062', (byte)'\063', (byte)'\064', (byte)'\065', (byte)'\066', (byte)'\067',
(byte)'\070', (byte)'\071', (byte)'\072', (byte)'\073', (byte)'\074', (byte)'\075', (byte)'\076', (byte)'\077',
(byte)'\100', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
(byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
(byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
(byte)'\130', (byte)'\131', (byte)'\132', (byte)'\133', (byte)'\134', (byte)'\135', (byte)'\136', (byte)'\137',
(byte)'\140', (byte)'\101', (byte)'\102', (byte)'\103', (byte)'\104', (byte)'\105', (byte)'\106', (byte)'\107',
(byte)'\110', (byte)'\111', (byte)'\112', (byte)'\113', (byte)'\114', (byte)'\115', (byte)'\116', (byte)'\117',
(byte)'\120', (byte)'\121', (byte)'\122', (byte)'\123', (byte)'\124', (byte)'\125', (byte)'\126', (byte)'\127',
(byte)'\130', (byte)'\131', (byte)'\132', (byte)'\173', (byte)'\174', (byte)'\175', (byte)'\176', (byte)'\177',
(byte)'\200', (byte)'\201', (byte)'\202', (byte)'\203', (byte)'\204', (byte)'\205', (byte)'\206', (byte)'\207',
(byte)'\210', (byte)'\211', (byte)'\212', (byte)'\213', (byte)'\214', (byte)'\215', (byte)'\216', (byte)'\217',
(byte)'\220', (byte)'\221', (byte)'\222', (byte)'\223', (byte)'\224', (byte)'\225', (byte)'\226', (byte)'\227',
(byte)'\230', (byte)'\231', (byte)'\232', (byte)'\233', (byte)'\234', (byte)'\235', (byte)'\236', (byte)'\237',
(byte)'\240', (byte)'\241', (byte)'\242', (byte)'\243', (byte)'\244', (byte)'\245', (byte)'\246', (byte)'\247',
(byte)'\250', (byte)'\251', (byte)'\252', (byte)'\253', (byte)'\254', (byte)'\255', (byte)'\256', (byte)'\257',
(byte)'\260', (byte)'\261', (byte)'\262', (byte)'\263', (byte)'\264', (byte)'\265', (byte)'\266', (byte)'\267',
(byte)'\270', (byte)'\271', (byte)'\272', (byte)'\273', (byte)'\274', (byte)'\275', (byte)'\276', (byte)'\277',
(byte)'\300', (byte)'\301', (byte)'\302', (byte)'\303', (byte)'\304', (byte)'\305', (byte)'\306', (byte)'\307',
(byte)'\310', (byte)'\311', (byte)'\312', (byte)'\313', (byte)'\314', (byte)'\315', (byte)'\316', (byte)'\317',
(byte)'\320', (byte)'\321', (byte)'\322', (byte)'\323', (byte)'\324', (byte)'\325', (byte)'\326', (byte)'\327',
(byte)'\330', (byte)'\331', (byte)'\332', (byte)'\333', (byte)'\334', (byte)'\335', (byte)'\336', (byte)'\337',
(byte)'\340', (byte)'\341', (byte)'\342', (byte)'\343', (byte)'\344', (byte)'\345', (byte)'\346', (byte)'\347',
(byte)'\350', (byte)'\351', (byte)'\352', (byte)'\353', (byte)'\354', (byte)'\355', (byte)'\356', (byte)'\357',
(byte)'\360', (byte)'\361', (byte)'\362', (byte)'\363', (byte)'\364', (byte)'\365', (byte)'\366', (byte)'\367',
(byte)'\370', (byte)'\371', (byte)'\372', (byte)'\373', (byte)'\374', (byte)'\375', (byte)'\376', (byte)'\377',
};
public static final int LowerMap[][] = {
{0x41, 0x61},
{0x42, 0x62},
{0x43, 0x63},
{0x44, 0x64},
{0x45, 0x65},
{0x46, 0x66},
{0x47, 0x67},
{0x48, 0x68},
{0x49, 0x69},
{0x4a, 0x6a},
{0x4b, 0x6b},
{0x4c, 0x6c},
{0x4d, 0x6d},
{0x4e, 0x6e},
{0x4f, 0x6f},
{0x50, 0x70},
{0x51, 0x71},
{0x52, 0x72},
{0x53, 0x73},
{0x54, 0x74},
{0x55, 0x75},
{0x56, 0x76},
{0x57, 0x77},
{0x58, 0x78},
{0x59, 0x79},
{0x5a, 0x7a}
};
}

View File

@ -30,6 +30,5 @@ public final class ObjPtr<T> {
public T p;
static final ObjPtr<Void> NULL = new ObjPtr<Void>();
}

View File

@ -1,77 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS".toCharArray(), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
import java.util.HashMap;
public class PosixBracket {
public static final char[][] PBSNamesLower = {
"alnum".toCharArray(),
"alpha".toCharArray(),
"blank".toCharArray(),
"cntrl".toCharArray(),
"digit".toCharArray(),
"graph".toCharArray(),
"lower".toCharArray(),
"print".toCharArray(),
"punct".toCharArray(),
"space".toCharArray(),
"upper".toCharArray(),
"xdigit".toCharArray(),
"ascii".toCharArray(),
"word".toCharArray()
};
public static final int PBSValues[] = {
CharacterType.ALNUM,
CharacterType.ALPHA,
CharacterType.BLANK,
CharacterType.CNTRL,
CharacterType.DIGIT,
CharacterType.GRAPH,
CharacterType.LOWER,
CharacterType.PRINT,
CharacterType.PUNCT,
CharacterType.SPACE,
CharacterType.UPPER,
CharacterType.XDIGIT,
CharacterType.ASCII,
CharacterType.WORD,
};
public static int propertyNameToCType(String name) {
name = name.toLowerCase();
if (!PBSTableUpper.containsKey(name)) {
throw new JOniException(ErrorMessages.ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
}
return PBSTableUpper.get(name);
}
private static final HashMap<String,Integer> PBSTableUpper = new HashMap<String,Integer>();
static {
for (int i=0; i<PBSValues.length; i++) PBSTableUpper.put(new String(PBSNamesLower[i]), PBSValues[i]);
}
}

View File

@ -1,35 +0,0 @@
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package jdk.nashorn.internal.runtime.regexp.joni.encoding;
public final class Ptr {
public Ptr() {
this(0);
}
public Ptr(int p) {
this.p = p;
}
public int p;
public static final Ptr NULL = new Ptr(0);
}

View File

@ -22,28 +22,16 @@ package jdk.nashorn.internal.runtime.regexp.joni.exception;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
public interface ErrorMessages {
final String MISMATCH = "mismatch";
final String NO_SUPPORT_CONFIG = "no support in this configuration";
/* from jcodings */
final String ERR_INVALID_CHAR_PROPERTY_NAME = "invalid character property name <%n>";
final String ERR_INVALID_CODE_POINT_VALUE = "invalid code point value";
final String ERR_TOO_BIG_WIDE_CHAR_VALUE = "too big wide-char value";
final String ERR_TOO_LONG_WIDE_CHAR_VALUE = "too long wide-char value";
/* internal error */
final String ERR_MEMORY = "fail to memory allocation";
final String ERR_MATCH_STACK_LIMIT_OVER = "match-stack limit over";
final String ERR_TYPE_BUG = "undefined type (bug)";
final String ERR_PARSER_BUG = "internal parser error (bug)";
final String ERR_STACK_BUG = "stack error (bug)";
final String ERR_UNDEFINED_BYTECODE = "undefined bytecode (bug)";
final String ERR_UNEXPECTED_BYTECODE = "unexpected bytecode (bug)";
final String ERR_DEFAULT_ENCODING_IS_NOT_SETTED = "default multibyte-encoding is not setted";
final String ERR_SPECIFIED_ENCODING_CANT_CONVERT_TO_WIDE_CHAR = "can't convert to wide-char on specified multibyte-encoding";
/* general error */
final String ERR_INVALID_ARGUMENT = "invalid argument";
/* syntax error */
final String ERR_END_PATTERN_AT_LEFT_BRACE = "end pattern at left brace";
@ -56,11 +44,9 @@ public interface ErrorMessages {
final String ERR_META_CODE_SYNTAX = "invalid meta-code syntax";
final String ERR_CONTROL_CODE_SYNTAX = "invalid control-code syntax";
final String ERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE = "char-class value at end of range";
final String ERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE = "char-class value at start of range";
final String ERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS = "unmatched range specifier in char-class";
final String ERR_TARGET_OF_REPEAT_OPERATOR_NOT_SPECIFIED = "target of repeat operator is not specified";
final String ERR_TARGET_OF_REPEAT_OPERATOR_INVALID = "target of repeat operator is invalid";
final String ERR_NESTED_REPEAT_OPERATOR = "nested repeat operator";
final String ERR_UNMATCHED_CLOSE_PARENTHESIS = "unmatched close parenthesis";
final String ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS = "end pattern with unmatched parenthesis";
final String ERR_END_PATTERN_IN_GROUP = "end pattern in group";
@ -74,25 +60,14 @@ public interface ErrorMessages {
final String ERR_TOO_BIG_NUMBER_FOR_REPEAT_RANGE = "too big number for repeat range";
final String ERR_UPPER_SMALLER_THAN_LOWER_IN_REPEAT_RANGE = "upper is smaller than lower in repeat range";
final String ERR_EMPTY_RANGE_IN_CHAR_CLASS = "empty range in char class";
final String ERR_MISMATCH_CODE_LENGTH_IN_CLASS_RANGE = "mismatch multibyte code length in char-class range";
final String ERR_TOO_MANY_MULTI_BYTE_RANGES = "too many multibyte code ranges are specified";
final String ERR_TOO_SHORT_MULTI_BYTE_STRING = "too short multibyte code string";
final String ERR_TOO_BIG_BACKREF_NUMBER = "too big backref number";
final String ERR_INVALID_BACKREF = Config.USE_NAMED_GROUP ? "invalid backref number/name" : "invalid backref number";
final String ERR_INVALID_BACKREF = "invalid backref number";
final String ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED = "numbered backref/call is not allowed. (use name)";
final String ERR_INVALID_WIDE_CHAR_VALUE = "invalid wide-char value";
final String ERR_EMPTY_GROUP_NAME = "group name is empty";
final String ERR_INVALID_GROUP_NAME = "invalid group name <%n>";
final String ERR_INVALID_CHAR_IN_GROUP_NAME = Config.USE_NAMED_GROUP ? "invalid char in group name <%n>" : "invalid char in group number <%n>";
final String ERR_UNDEFINED_NAME_REFERENCE = "undefined name <%n> reference";
final String ERR_UNDEFINED_GROUP_REFERENCE = "undefined group <%n> reference";
final String ERR_MULTIPLEX_DEFINED_NAME = "multiplex defined name <%n>";
final String ERR_MULTIPLEX_DEFINITION_NAME_CALL = "multiplex definition name <%n> call";
final String ERR_NEVER_ENDING_RECURSION = "never ending recursion";
final String ERR_INVALID_CHAR_IN_GROUP_NAME = "invalid char in group number <%n>";
final String ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY = "group number is too big for capture history";
final String ERR_NOT_SUPPORTED_ENCODING_COMBINATION = "not supported encoding combination";
final String ERR_INVALID_COMBINATION_OF_OPTIONS = "invalid combination of options";
final String ERR_OVER_THREAD_PASS_LIMIT_COUNT = "over thread pass limit count";
final String ERR_TOO_BIG_SB_CHAR_VALUE = "too big singlebyte char value";
}

View File

@ -30,8 +30,4 @@ public class ValueException extends SyntaxException{
super(message.replaceAll("%n", str));
}
public ValueException(String message, byte[]bytes, int p, int end) {
this(message, new String(bytes, p, end - p));
}
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime.regexp;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import jdk.nashorn.internal.runtime.ParserException;
import org.testng.annotations.Test;
/**
* Basic tests for the JDK based RegExp implementation.
*
* @test
* @run testng jdk.nashorn.internal.runtime.regexp.JdkRegExpTest
*/
public class JdkRegExpTest {
/**
* Compile a regular expression using the JDK implementation
*/
@Test
public void testMatcher() {
RegExp regexp = new RegExpFactory().compile("f(o)o", "");
RegExpMatcher matcher = regexp.match("foo");
assertNotNull(matcher);
assertTrue(matcher.search(0));
assertEquals(matcher.getInput(), "foo");
assertEquals(matcher.groupCount(), 1);
assertEquals(matcher.group(), "foo");
assertEquals(matcher.start(), 0);
assertEquals(matcher.end(), 3);
assertEquals(matcher.group(1), "o");
assertEquals(matcher.start(1), 1);
assertEquals(matcher.end(1), 2);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime.regexp.joni;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.Test;
/**
* Joni coverage tests
*
* @test
* @run testng jdk.nashorn.internal.runtime.regexp.joni.JoniTest
*/
public class JoniTest {
@Test
public void testDump() {
new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpTree();
new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpByteCode();
new Regex("(abc){4,}{2,5}").dumpTree();
new Regex("(abc){4,}{2,5}").dumpByteCode();
new Regex("aaa|aa|bbbb|ccc").dumpTree();
new Regex("aaa|aa|bbbb|ccc").dumpByteCode();
new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpTree();
new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpByteCode();
}
}