nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
changeset 18884 b2032ab50ac4
parent 17753 4800f03fbfc4
child 24588 36f65e9b2f4c
equal deleted inserted replaced
18883:30a82ef1bdf7 18884:b2032ab50ac4
    39 import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
    39 import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
    40 import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
    40 import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
    41 import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
    41 import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
    42 import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
    42 import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
    43 import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
    43 import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
    44 import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
       
    45 import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
    44 import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
    46 import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
    45 import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
    47 import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
    46 import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
       
    47 import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
       
    48 import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
       
    49 import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
    48 
    50 
    49 final class Analyser extends Parser {
    51 final class Analyser extends Parser {
    50 
    52 
    51     protected Analyser(ScanEnvironment env, char[] chars, int p, int end) {
    53     protected Analyser(ScanEnvironment env, char[] chars, int p, int end) {
    52         super(env, chars, p, end);
    54         super(env, chars, p, end);
    53     }
    55     }
    54 
    56 
    55     protected final void compile() {
    57     protected final void compile() {
    56         regex.state = RegexState.COMPILING;
       
    57 
       
    58         if (Config.DEBUG) {
    58         if (Config.DEBUG) {
    59             Config.log.println(new String(chars, getBegin(), getEnd()));
    59             Config.log.println(new String(chars, getBegin(), getEnd()));
    60         }
    60         }
    61 
    61 
    62         reset();
    62         reset();
   113             Config.log.println("stack used: " + regex.stackNeeded);
   113             Config.log.println("stack used: " + regex.stackNeeded);
   114             if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
   114             if (Config.USE_STRING_TEMPLATES) Config.log.print("templates: " + regex.templateNum + "\n");
   115             Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
   115             Config.log.println(new ByteCodePrinter(regex).byteCodeListToString());
   116 
   116 
   117         } // DEBUG_COMPILE
   117         } // DEBUG_COMPILE
   118 
       
   119         regex.state = RegexState.NORMAL;
       
   120     }
   118     }
   121 
   119 
   122     private void swap(Node a, Node b) {
   120     private void swap(Node a, Node b) {
   123         a.swap(b);
   121         a.swap(b);
   124 
   122 
   185         switch (node.getType()) {
   183         switch (node.getType()) {
   186         case NodeType.BREF:
   184         case NodeType.BREF:
   187             BackRefNode br = (BackRefNode)node;
   185             BackRefNode br = (BackRefNode)node;
   188             if (br.isRecursion()) break;
   186             if (br.isRecursion()) break;
   189 
   187 
   190             if (br.back[0] > env.numMem) newValueException(ERR_INVALID_BACKREF);
   188             if (br.backRef > env.numMem) {
   191             min = getMinMatchLength(env.memNodes[br.back[0]]);
   189                 throw new ValueException(ERR_INVALID_BACKREF);
   192 
   190             }
   193             for (int i=1; i<br.backNum; i++) {
   191             min = getMinMatchLength(env.memNodes[br.backRef]);
   194                 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
   192 
   195                 int tmin = getMinMatchLength(env.memNodes[br.back[i]]);
       
   196                 if (min > tmin) min = tmin;
       
   197             }
       
   198             break;
   193             break;
   199 
   194 
   200         case NodeType.LIST:
   195         case NodeType.LIST:
   201             ConsAltNode can = (ConsAltNode)node;
   196             ConsAltNode can = (ConsAltNode)node;
   202             do {
   197             do {
   304             if (br.isRecursion()) {
   299             if (br.isRecursion()) {
   305                 max = MinMaxLen.INFINITE_DISTANCE;
   300                 max = MinMaxLen.INFINITE_DISTANCE;
   306                 break;
   301                 break;
   307             }
   302             }
   308 
   303 
   309             for (int i=0; i<br.backNum; i++) {
   304             if (br.backRef > env.numMem) {
   310                 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
   305                 throw new ValueException(ERR_INVALID_BACKREF);
   311                 int tmax = getMaxMatchLength(env.memNodes[br.back[i]]);
   306             }
   312                 if (max < tmax) max = tmax;
   307             int tmax = getMaxMatchLength(env.memNodes[br.backRef]);
   313             }
   308             if (max < tmax) max = tmax;
   314             break;
   309             break;
   315 
   310 
   316         case NodeType.QTFR:
   311         case NodeType.QTFR:
   317             QuantifierNode qn = (QuantifierNode)node;
   312             QuantifierNode qn = (QuantifierNode)node;
   318             if (qn.upper != 0) {
   313             if (qn.upper != 0) {
   415                 returnCode = GET_CHAR_LEN_VARLEN;
   410                 returnCode = GET_CHAR_LEN_VARLEN;
   416             }
   411             }
   417             break;
   412             break;
   418 
   413 
   419         case NodeType.CTYPE:
   414         case NodeType.CTYPE:
   420             len = 1;
       
   421 
       
   422         case NodeType.CCLASS:
   415         case NodeType.CCLASS:
   423         case NodeType.CANY:
   416         case NodeType.CANY:
   424             len = 1;
   417             len = 1;
   425             break;
   418             break;
   426 
   419 
   710         switch(returnCode) {
   703         switch(returnCode) {
   711         case 0:
   704         case 0:
   712             an.charLength = len;
   705             an.charLength = len;
   713             break;
   706             break;
   714         case GET_CHAR_LEN_VARLEN:
   707         case GET_CHAR_LEN_VARLEN:
   715             newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
   708             throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
   716             break;
       
   717         case GET_CHAR_LEN_TOP_ALT_VARLEN:
   709         case GET_CHAR_LEN_TOP_ALT_VARLEN:
   718             if (syntax.differentLengthAltLookBehind()) {
   710             if (syntax.differentLengthAltLookBehind()) {
   719                 return divideLookBehindAlternatives(node);
   711                 return divideLookBehindAlternatives(node);
   720             } else {
   712             } else {
   721                 newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
   713                 throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
   722             }
   714             }
   723         }
   715         }
   724         return node;
   716         return node;
   725     }
   717     }
   726 
   718 
   953         case NodeType.CANY:
   945         case NodeType.CANY:
   954             break;
   946             break;
   955 
   947 
   956         case NodeType.BREF:
   948         case NodeType.BREF:
   957             BackRefNode br = (BackRefNode)node;
   949             BackRefNode br = (BackRefNode)node;
   958             for (int i=0; i<br.backNum; i++) {
   950             if (br.backRef > env.numMem) {
   959                 if (br.back[i] > env.numMem) newValueException(ERR_INVALID_BACKREF);
   951                 throw new ValueException(ERR_INVALID_BACKREF);
   960                 env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
   952             }
   961                 env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
   953             env.backrefedMem = bsOnAt(env.backrefedMem, br.backRef);
   962                 ((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
   954             env.btMemStart = bsOnAt(env.btMemStart, br.backRef);
   963             }
   955             ((EncloseNode)env.memNodes[br.backRef]).setMemBackrefed();
   964             break;
   956             break;
   965 
   957 
   966         case NodeType.QTFR:
   958         case NodeType.QTFR:
   967             QuantifierNode qn = (QuantifierNode)node;
   959             QuantifierNode qn = (QuantifierNode)node;
   968             Node target = qn.target;
   960             Node target = qn.target;
  1062             case AnchorType.PREC_READ_NOT:
  1054             case AnchorType.PREC_READ_NOT:
  1063                 setupTree(an.target, (state | IN_NOT));
  1055                 setupTree(an.target, (state | IN_NOT));
  1064                 break;
  1056                 break;
  1065 
  1057 
  1066             case AnchorType.LOOK_BEHIND:
  1058             case AnchorType.LOOK_BEHIND:
  1067                 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
  1059                 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) {
       
  1060                     throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
       
  1061                 }
  1068                 node = setupLookBehind(node);
  1062                 node = setupLookBehind(node);
  1069                 if (node.getType() != NodeType.ANCHOR) continue restart;
  1063                 if (node.getType() != NodeType.ANCHOR) continue restart;
  1070                 setupTree(((AnchorNode)node).target, state);
  1064                 setupTree(((AnchorNode)node).target, state);
  1071                 break;
  1065                 break;
  1072 
  1066 
  1073             case AnchorType.LOOK_BEHIND_NOT:
  1067             case AnchorType.LOOK_BEHIND_NOT:
  1074                 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) newSyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
  1068                 if (checkTypeTree(an.target, NodeType.ALLOWED_IN_LB, EncloseType.ALLOWED_IN_LB, AnchorType.ALLOWED_IN_LB)) {
       
  1069                     throw new SyntaxException(ERR_INVALID_LOOK_BEHIND_PATTERN);
       
  1070                 }
  1075                 node = setupLookBehind(node);
  1071                 node = setupLookBehind(node);
  1076                 if (node.getType() != NodeType.ANCHOR) continue restart;
  1072                 if (node.getType() != NodeType.ANCHOR) continue restart;
  1077                 setupTree(((AnchorNode)node).target, (state | IN_NOT));
  1073                 setupTree(((AnchorNode)node).target, (state | IN_NOT));
  1078                 break;
  1074                 break;
  1079 
  1075 
  1216                 break;
  1212                 break;
  1217             }
  1213             }
  1218 
  1214 
  1219             Node[]nodes = oenv.scanEnv.memNodes;
  1215             Node[]nodes = oenv.scanEnv.memNodes;
  1220 
  1216 
  1221             int min = getMinMatchLength(nodes[br.back[0]]);
  1217             int min = getMinMatchLength(nodes[br.backRef]);
  1222             int max = getMaxMatchLength(nodes[br.back[0]]);
  1218             int max = getMaxMatchLength(nodes[br.backRef]);
  1223 
  1219 
  1224             for (int i=1; i<br.backNum; i++) {
       
  1225                 int tmin = getMinMatchLength(nodes[br.back[i]]);
       
  1226                 int tmax = getMaxMatchLength(nodes[br.back[i]]);
       
  1227                 if (min > tmin) min = tmin;
       
  1228                 if (max < tmax) max = tmax;
       
  1229             }
       
  1230             opt.length.set(min, max);
  1220             opt.length.set(min, max);
  1231             break;
  1221             break;
  1232         }
  1222         }
  1233 
  1223 
  1234 
  1224 
  1312             } // inner switch
  1302             } // inner switch
  1313             break;
  1303             break;
  1314         }
  1304         }
  1315 
  1305 
  1316         default:
  1306         default:
  1317             newInternalException(ERR_PARSER_BUG);
  1307             throw new InternalException(ERR_PARSER_BUG);
  1318         } // switch
  1308         } // switch
  1319     }
  1309     }
  1320 
  1310 
  1321     protected final void setOptimizedInfoFromTree(Node node) {
  1311     protected final void setOptimizedInfoFromTree(Node node) {
  1322         NodeOptInfo opt = new NodeOptInfo();
  1312         NodeOptInfo opt = new NodeOptInfo();