home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 November / PCONLINE_11_99.ISO / filesbbs / OS2 / APCHSSL2.ZIP / OS2HTTPD / jserv / com / netscape / javascript / NativeRegExp.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-04-09  |  25.4 KB  |  2,419 lines

  1. package com.netscape.javascript;
  2.  
  3. public class NativeRegExp extends RescopeableObject implements Function {
  4.    public static final int GLOB = 1;
  5.    public static final int FOLD = 2;
  6.    private static final boolean debug = false;
  7.    private static final int CCLASS_CHARSET_SIZE = 256;
  8.    private static final int PR_BITS_PER_BYTE = 8;
  9.    private static final byte REOP_EMPTY = 0;
  10.    private static final byte REOP_ALT = 1;
  11.    private static final byte REOP_BOL = 2;
  12.    private static final byte REOP_EOL = 3;
  13.    private static final byte REOP_WBDRY = 4;
  14.    private static final byte REOP_WNONBDRY = 5;
  15.    private static final byte REOP_QUANT = 6;
  16.    private static final byte REOP_STAR = 7;
  17.    private static final byte REOP_PLUS = 8;
  18.    private static final byte REOP_OPT = 9;
  19.    private static final byte REOP_LPAREN = 10;
  20.    private static final byte REOP_RPAREN = 11;
  21.    private static final byte REOP_DOT = 12;
  22.    private static final byte REOP_CCLASS = 13;
  23.    private static final byte REOP_DIGIT = 14;
  24.    private static final byte REOP_NONDIGIT = 15;
  25.    private static final byte REOP_ALNUM = 16;
  26.    private static final byte REOP_NONALNUM = 17;
  27.    private static final byte REOP_SPACE = 18;
  28.    private static final byte REOP_NONSPACE = 19;
  29.    private static final byte REOP_BACKREF = 20;
  30.    private static final byte REOP_FLAT = 21;
  31.    private static final byte REOP_FLAT1 = 22;
  32.    private static final byte REOP_JUMP = 23;
  33.    private static final byte REOP_DOTSTAR = 24;
  34.    private static final byte REOP_ANCHOR = 25;
  35.    private static final byte REOP_EOLONLY = 26;
  36.    private static final byte REOP_UCFLAT = 27;
  37.    private static final byte REOP_UCFLAT1 = 28;
  38.    private static final byte REOP_UCCLASS = 29;
  39.    private static final byte REOP_NUCCLASS = 30;
  40.    private static final byte REOP_BACKREFi = 31;
  41.    private static final byte REOP_FLATi = 32;
  42.    private static final byte REOP_FLAT1i = 33;
  43.    private static final byte REOP_UCFLATi = 34;
  44.    private static final byte REOP_UCFLAT1i = 35;
  45.    private static final byte REOP_ANCHOR1 = 36;
  46.    private static final byte REOP_END = 37;
  47.    private static final byte[] reopsize = new byte[]{1, 3, 1, 1, 1, 1, 7, 1, 1, 1, 3, 3, 1, 33, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 1, 1, 1, 2, 3, 3, 3, 2, 2, 2, 2, 3, 1, 0};
  48.    private static final int REOP_FLATLEN_MAX = 255;
  49.    private static int level;
  50.    private static final String[] reopname = new String[]{"empty", "alt", "bol", "eol", "wbdry", "wnonbdry", "quant", "star", "plus", "opt", "lparen", "rparen", "dot", "cclass", "digit", "nondigit", "alnum", "nonalnum", "space", "nonspace", "backref", "flat", "flat1", "jump", "dotstar", "anchor", "eolonly", "ucflat", "ucflat1", "ucclass", "nucclass", "backrefi", "flati", "flat1i", "ucflati", "ucflat1i", "anchor1", "end"};
  51.    static final String metachars = "|^${*+?().[\\";
  52.    static final String closurechars = "{*+?";
  53.    private String source;
  54.    private int lastIndex;
  55.    private int parenCount;
  56.    private byte flags;
  57.    private byte[] program;
  58.    // $FF: synthetic field
  59.    private static Class class$com$netscape$javascript$NativeRegExp;
  60.  
  61.    public boolean getIgnoreCase() {
  62.       return (this.flags & 2) != 0;
  63.    }
  64.  
  65.    public static Object test(Context var0, Scriptable var1, Object[] var2, Function var3) {
  66.       Object var4 = execSub(var0, var1, var2, var3, true, var3);
  67.       if (var4 == null || !var4.equals(Boolean.TRUE)) {
  68.          var4 = Boolean.FALSE;
  69.       }
  70.  
  71.       return var4;
  72.    }
  73.  
  74.    public static Object exec(Context var0, Scriptable var1, Object[] var2, Function var3) {
  75.       return execSub(var0, var1, var2, var3, false, var3);
  76.    }
  77.  
  78.    RENode parseQuantAtom(CompilerState var1) {
  79.       RENode var2 = this.parseAtom(var1);
  80.       if (var2 == null) {
  81.          return null;
  82.       } else {
  83.          char[] var8 = var1.source;
  84.          int var9 = var1.index;
  85.  
  86.          label93:
  87.          while(true) {
  88.             if (var9 < var8.length) {
  89.                switch (var8[var9]) {
  90.                   case '*':
  91.                      if ((var2.flags & 4) == 0) {
  92.                         this.reportError("msg.re.empty", "*");
  93.                         return null;
  94.                      }
  95.  
  96.                      ++var9;
  97.                      var2 = new RENode(var1, (byte)7, var2);
  98.                      continue;
  99.                   case '+':
  100.                      if ((var2.flags & 4) == 0) {
  101.                         this.reportError("msg.re.empty", "+");
  102.                         return null;
  103.                      }
  104.  
  105.                      ++var9;
  106.                      RENode var12 = new RENode(var1, (byte)8, var2);
  107.                      if ((var2.flags & 4) != 0) {
  108.                         var12.flags = (byte)(var12.flags | 4);
  109.                      }
  110.  
  111.                      var2 = var12;
  112.                      continue;
  113.                   case '?':
  114.                      ++var9;
  115.                      var2 = new RENode(var1, (byte)9, var2);
  116.                      continue;
  117.                   case '{':
  118.                      ++var9;
  119.                      char var4;
  120.                      if (var9 != var8.length && isDigit(var4 = var8[var9])) {
  121.                         int var6 = unDigit(var4);
  122.  
  123.                         do {
  124.                            ++var9;
  125.                            if (var9 >= var8.length || !isDigit(var4 = var8[var9])) {
  126.                               int var7;
  127.                               if (var8[var9] == ',') {
  128.                                  ++var9;
  129.                                  int var3 = var9;
  130.                                  if (isDigit(var8[var9])) {
  131.                                     var7 = unDigit(var8[var9]);
  132.  
  133.                                     while(true) {
  134.                                        ++var9;
  135.                                        if (!isDigit(var4 = var8[var9])) {
  136.                                           if (var7 == 0) {
  137.                                              this.reportError("msg.zero.quant", this.tail(var8, var1.index));
  138.                                              return null;
  139.                                           }
  140.  
  141.                                           if (var6 > var7) {
  142.                                              this.reportError("msg.max.lt.min", this.tail(var8, var3));
  143.                                              return null;
  144.                                           }
  145.                                           break;
  146.                                        }
  147.  
  148.                                        var7 = 10 * var7 + unDigit(var4);
  149.                                        if (var7 >> 16 != 0) {
  150.                                           this.reportError("msg.overlarge.max", String.valueOf(var8[var3]));
  151.                                           return null;
  152.                                        }
  153.                                     }
  154.                                  } else {
  155.                                     var7 = 0;
  156.                                  }
  157.                               } else {
  158.                                  if (var6 == 0) {
  159.                                     this.reportError("msg.zero.quant", this.tail(var8, var1.index));
  160.                                     return null;
  161.                                  }
  162.  
  163.                                  var7 = var6;
  164.                               }
  165.  
  166.                               if (var8[var9] != '}') {
  167.                                  this.reportError("msg.unterm.quant", String.valueOf(var8[var1.index]));
  168.                                  return null;
  169.                               }
  170.  
  171.                               ++var9;
  172.                               RENode var5 = new RENode(var1, (byte)6, var2);
  173.                               if (var6 > 0 && (var2.flags & 4) != 0) {
  174.                                  var5.flags = (byte)(var5.flags | 4);
  175.                               }
  176.  
  177.                               var5.min = (short)var6;
  178.                               var5.max = (short)var7;
  179.                               var2 = var5;
  180.                               continue label93;
  181.                            }
  182.  
  183.                            var6 = 10 * var6 + unDigit(var4);
  184.                         } while(var6 >> 16 == 0);
  185.  
  186.                         this.reportError("msg.overlarge.max", this.tail(var8, var9));
  187.                         return null;
  188.                      }
  189.  
  190.                      this.reportError("msg.bad.quant", String.valueOf(var8[var1.index]));
  191.                      return null;
  192.                }
  193.             }
  194.  
  195.             var1.index = var9;
  196.             return var2;
  197.          }
  198.       }
  199.    }
  200.  
  201.    void matchBit(char var1, int var2, int var3) {
  202.       int var4 = var1 >> 3;
  203.       byte var5 = (byte)(var1 & 7);
  204.       var5 = (byte)(1 << var5);
  205.       if (var2 != 0) {
  206.          byte[] var7 = this.program;
  207.          var7[var3 + var4] = (byte)(var7[var3 + var4] & ~var5);
  208.       } else {
  209.          byte[] var10000 = this.program;
  210.          var10000[var3 + var4] |= var5;
  211.       }
  212.    }
  213.  
  214.    public static boolean isDigit(char var0) {
  215.       return '0' <= var0 && var0 <= '9';
  216.    }
  217.  
  218.    private boolean anchorRegExp(CompilerState var1, RENode var2) {
  219.       int var5 = 0;
  220.       char[] var6 = null;
  221.       byte var7 = 0;
  222.       boolean var8 = false;
  223.       boolean var9 = false;
  224.       int var10 = 0;
  225.  
  226.       RENode var3;
  227.       for(var3 = var2; var3.op == 10; var3 = (RENode)var3.kid) {
  228.       }
  229.  
  230.       switch (var3.op) {
  231.          case 1:
  232.             var5 = this.countFirstChars(var3);
  233.             if (var5 <= 0) {
  234.                var9 = true;
  235.             } else {
  236.                var6 = new char[var5];
  237.                var5 = this.storeFirstChars(var1, var3, var6, 0);
  238.                if (var5 == 1) {
  239.                   var7 = 22;
  240.                } else if (var5 == 2 && var6[0] == '\\') {
  241.                   switch (var6[1]) {
  242.                      case '-':
  243.                      case '\\':
  244.                         ++var10;
  245.                         var7 = 22;
  246.                         break;
  247.                      case 'D':
  248.                         var7 = 15;
  249.                         break;
  250.                      case 'S':
  251.                         var7 = 19;
  252.                         break;
  253.                      case 'W':
  254.                         var7 = 17;
  255.                         break;
  256.                      case 'd':
  257.                         var7 = 14;
  258.                         break;
  259.                      case 's':
  260.                         var7 = 18;
  261.                         break;
  262.                      case 'w':
  263.                         var7 = 16;
  264.                         break;
  265.                      default:
  266.                         var7 = 13;
  267.                   }
  268.                } else {
  269.                   var7 = 13;
  270.                }
  271.  
  272.                if (var6.length != var5) {
  273.                   char[] var11 = new char[var5 - var10];
  274.                   System.arraycopy(var6, var10, var11, 0, var5 - var10);
  275.                   var6 = var11;
  276.                }
  277.  
  278.                var8 = true;
  279.             }
  280.             break;
  281.          case 21:
  282.             var10 = (Integer)var3.kid;
  283.             var6 = new char[]{(var3.s != null ? var3.s : var1.source)[var10]};
  284.             var7 = 22;
  285.             var8 = true;
  286.             break;
  287.          case 22:
  288.             var6 = new char[]{var3.chr};
  289.             var7 = 22;
  290.             var8 = true;
  291.          case 24:
  292.             break;
  293.          default:
  294.             var9 = true;
  295.       }
  296.  
  297.       if (var8) {
  298.          RENode var4 = new RENode(var1, var7, new Integer(0));
  299.          var4.s = var6;
  300.          var4.flags = 6;
  301.          if (var7 == 22) {
  302.             var4.chr = var6[0];
  303.          } else if (var7 == 13) {
  304.             var4.kid2 = var5;
  305.          }
  306.  
  307.          var3 = new RENode(var1, var2.op, var2.kid);
  308.          var3.flags = (byte)(var2.flags | 8);
  309.          var3.next = var2.next;
  310.          var3.kid2 = var2.kid2;
  311.          var3.num = var2.num;
  312.          var3.chr = var2.chr;
  313.          var3.min = var2.min;
  314.          var3.max = var2.max;
  315.          var2.op = 36;
  316.          var2.flags = 16;
  317.          var2.next = var3;
  318.          var2.kid = var4;
  319.          var2.kid2 = 0;
  320.       }
  321.  
  322.       if (var9) {
  323.          if (var3.op == 25 || (var3.flags & 8) != 0) {
  324.             throw new RuntimeException();
  325.          }
  326.  
  327.          if ((var3.flags & 5) == 4) {
  328.             var3 = new RENode(var1, var2.op, var2.kid);
  329.             var3.flags = (byte)(var2.flags | 8);
  330.             var3.next = var2.next;
  331.             var3.kid2 = var2.kid2;
  332.             var3.num = var2.num;
  333.             var3.chr = var2.chr;
  334.             var3.min = var2.min;
  335.             var3.max = var2.max;
  336.             var2.op = 25;
  337.             var2.flags = 16;
  338.             var2.next = var3;
  339.             var2.kid = null;
  340.             var2.kid2 = 0;
  341.          }
  342.       }
  343.  
  344.       return true;
  345.    }
  346.  
  347.    private void optimizeRegExp(CompilerState var1, RENode var2) {
  348.       RENode var6 = null;
  349.       int var23 = 0;
  350.       char[] var10 = var1.source;
  351.       boolean var11 = false;
  352.       StringBuffer var12 = null;
  353.  
  354.       do {
  355.          switch (var2.op) {
  356.             case 7:
  357.                RENode var20 = (RENode)var2.kid;
  358.                if ((var20.flags & 2) == 0) {
  359.                   var2.op = 1;
  360.                   var6 = var2.next;
  361.                   RENode var22 = new RENode(var1, (byte)23, (Object)null);
  362.                   this.fixNext(var1, var20, var22, var6);
  363.                   var22.next = var2;
  364.                   if ((var2.flags & 8) != 0) {
  365.                      var2.flags = (byte)(var2.flags | 32);
  366.                   }
  367.  
  368.                   this.closeTail(var1, var2, var6);
  369.                }
  370.                break;
  371.             case 8:
  372.                RENode var19 = (RENode)var2.kid;
  373.                if ((var19.flags & 2) == 0) {
  374.                   var6 = var2.next;
  375.                   int var7 = var2.flags & 16;
  376.                   var2.copy(var19);
  377.                   RENode var21 = new RENode(var1, (byte)23, (Object)null);
  378.                   RENode var5 = new RENode(var1, (byte)1, var21);
  379.                   this.fixNext(var1, var2, var5, var6);
  380.                   var5.flags = (byte)(var5.flags | var7);
  381.                   var21.next = var2;
  382.                   if ((var2.flags & 8) != 0) {
  383.                      var2.flags = (byte)(var2.flags | 32);
  384.                   }
  385.  
  386.                   this.closeTail(var1, var5, var6);
  387.                }
  388.                break;
  389.             case 9:
  390.                RENode var3 = (RENode)var2.kid;
  391.                if ((var3.flags & 2) == 0) {
  392.                   var2.op = 1;
  393.                   var6 = var2.next;
  394.                   RENode var4 = new RENode(var1, (byte)23, (Object)null);
  395.                   this.fixNext(var1, var3, var4, var6);
  396.                   var4.next = var6;
  397.                   this.closeTail(var1, var2, var6);
  398.                   var6.flags = (byte)(var6.flags | 32);
  399.                }
  400.                break;
  401.             case 22:
  402.                var6 = var2.next;
  403.                if (var6 == null || (var6.flags & 32) != 0 || var6.op != 21 && var6.op != 22) {
  404.                   var11 = false;
  405.                   break;
  406.                } else {
  407.                   var12 = new StringBuffer();
  408.                   var12.append(var2.chr);
  409.                   if (var6.op == 21) {
  410.                      int var13 = (Integer)var6.kid;
  411.                      var23 = var6.kid2 - var13;
  412.                      var12.append(var10, var13, var23);
  413.                   } else {
  414.                      var12.append(var6.chr);
  415.                      var23 = 1;
  416.                   }
  417.  
  418.                   ++var23;
  419.                   var2.op = 21;
  420.                   var2.flags = (byte)(var2.flags | 64);
  421.                   var11 = true;
  422.                }
  423.             case 21:
  424.                while(var11 || (var6 = var2.next) != null && (var6.flags & 32) == 0 && (var6.op == 21 || var6.op == 22)) {
  425.                   if (!var11) {
  426.                      var12 = new StringBuffer();
  427.                      int var24 = (Integer)var2.kid;
  428.                      var23 = var2.kid2 - var24;
  429.                      var12.append(var2.s != null ? var2.s : var10, var24, var23);
  430.                      int var8;
  431.                      if (var6.op == 21) {
  432.                         int var14 = (Integer)var6.kid;
  433.                         var8 = var6.kid2 - var14;
  434.                         var12.append(var10, var14, var8);
  435.                      } else {
  436.                         var8 = 1;
  437.                         var12.append(var6.chr);
  438.                      }
  439.  
  440.                      if (var23 + var8 > 255) {
  441.                         break;
  442.                      }
  443.  
  444.                      var23 += var8;
  445.                   }
  446.  
  447.                   var11 = false;
  448.                   var2.kid = new Integer(0);
  449.                   if ((var2.flags & 16) == 0) {
  450.                      throw new RuntimeException();
  451.                   }
  452.  
  453.                   if ((var6.flags & 16) == 0) {
  454.                      var2.flags &= -17;
  455.                   }
  456.  
  457.                   var2.kid2 = var23;
  458.                   var2.next = var6.next;
  459.                   var2.s = var12.toString().toCharArray();
  460.                   var6.op = 0;
  461.                }
  462.          }
  463.  
  464.          var2.offset = (short)var1.progLength;
  465.          var1.progLength += reopsize[var2.op];
  466.          switch (var2.op) {
  467.             case 1:
  468.             case 6:
  469.             case 7:
  470.             case 8:
  471.             case 9:
  472.             case 10:
  473.             case 36:
  474.                this.optimizeRegExp(var1, (RENode)var2.kid);
  475.                break;
  476.             case 13:
  477.                int var27 = (Integer)var2.kid;
  478.                int var29 = var2.kid2;
  479.                var23 = var29 - var27;
  480.                char var30 = 0;
  481.                char[] var16 = var2.s != null ? var2.s : var1.source;
  482.  
  483.                while(var27 < var29) {
  484.                   char var17 = var16[var27++];
  485.                   if (var17 == '\\') {
  486.                      if (var27 + 5 > var29 || var16[var27] != 'u' || !isHex(var16[var27 + 1]) || !isHex(var16[var27 + 2]) || !isHex(var16[var27 + 3]) || !isHex(var16[var27 + 4])) {
  487.                         continue;
  488.                      }
  489.  
  490.                      int var18 = (((unHex(var16[var27]) << 4) + unHex(var16[var27 + 1]) << 4) + unHex(var16[var27 + 2]) << 4) + unHex(var16[var27 + 3]);
  491.                      var17 = (char)var18;
  492.                      var27 += 5;
  493.                   }
  494.  
  495.                   if ((var1.flags & 2) != 0) {
  496.                      char var32;
  497.                      if ((var32 = Character.toUpperCase(var17)) > var30) {
  498.                         var30 = var32;
  499.                      }
  500.  
  501.                      if ((var32 = Character.toLowerCase(var32)) > var30) {
  502.                         var30 = var32;
  503.                      }
  504.                   }
  505.  
  506.                   if (var17 > var30) {
  507.                      var30 = var17;
  508.                   }
  509.                }
  510.  
  511.                if (var30 >= 256) {
  512.                   var2.op = 29;
  513.                   int var31 = (var30 + 8) / 8;
  514.                   var2.kidlen = (short)var23;
  515.                   var2.bmsize = (short)var31;
  516.                   var1.progLength -= reopsize[13];
  517.                   var1.progLength += reopsize[29] + var31;
  518.                }
  519.                break;
  520.             case 21:
  521.                int var26 = (Integer)var2.kid;
  522.                int var28 = var2.kid2;
  523.                var23 = var28 - var26;
  524.  
  525.                while(var26 < var28) {
  526.                   char var15 = var10[var26++];
  527.                   if (var15 >>> 8 != 0) {
  528.                      var2.op = 27;
  529.                      var23 *= 2;
  530.                      break;
  531.                   }
  532.                }
  533.  
  534.                var1.progLength += var23;
  535.                break;
  536.             case 22:
  537.                char var25 = var2.chr;
  538.                if (var25 >>> 8 != 0) {
  539.                   var2.op = 28;
  540.                   ++var1.progLength;
  541.                }
  542.                break;
  543.             case 23:
  544.                while((var6 = var2.next) != null && var6.op == 23) {
  545.                   var2.next = var6.next;
  546.                }
  547.                break;
  548.             case 37:
  549.                return;
  550.          }
  551.       } while((var2.flags & 16) != 0 && (var2 = var2.next) != null);
  552.  
  553.    }
  554.  
  555.    private void setNext(CompilerState var1, RENode var2, RENode var3) {
  556.       this.fixNext(var1, var2, var3, (RENode)null);
  557.    }
  558.  
  559.    private int matchRegExp(MatchState var1, byte[] var2, int var3, char[] var4, int var5) {
  560.       boolean var9 = false;
  561.       int var10 = 0;
  562.       Context var12 = Context.getContext();
  563.       RegExpStatics var13 = var12.getRegExpStatics();
  564.       int[] var14 = new int[1];
  565.       int var15 = var1.pcend;
  566.       int var16 = var1.cpbegin;
  567.       int var17 = var1.cpend;
  568.  
  569.       while(var3 < var15) {
  570.          int var19;
  571.          byte var18 = var2[var3];
  572.          var19 = reopsize[var18];
  573.          label511:
  574.          switch (var18) {
  575.             case 0:
  576.                var3 += var19;
  577.                continue;
  578.             case 1:
  579.                short var90 = this.readShort(var2, var3);
  580.                int var42 = var3 + var19;
  581.                if (var3 + var90 < var2.length && var2[var3 + var90] == 1) {
  582.                   int var53 = this.matchRegExp(var1, var2, var42, var4, var5);
  583.                   if (var53 != -1) {
  584.                      return var53;
  585.                   }
  586.  
  587.                   var3 += var90;
  588.                   continue;
  589.                }
  590.  
  591.                var3 = var42;
  592.                continue;
  593.             case 2:
  594.                var9 = var5 == var16;
  595.                if (var13.multiline) {
  596.                   if (var1.anchoring) {
  597.                      if (!var9) {
  598.                         var9 = var4[var5 - 1] == '\n';
  599.                      }
  600.                   } else {
  601.                      var1.anchoring = true;
  602.  
  603.                      for(int var52 = var5; var52 < var17; ++var52) {
  604.                         if (var52 == var16 || var4[var52 - 1] == '\n') {
  605.                            int var60 = this.matchRegExp(var1, var2, var3, var4, var52);
  606.                            if (var60 != -1) {
  607.                               var1.skipped = var52 - var5;
  608.                               var1.anchoring = false;
  609.                               return var60;
  610.                            }
  611.                         }
  612.                      }
  613.  
  614.                      var1.anchoring = false;
  615.                   }
  616.                }
  617.  
  618.                var10 = 0;
  619.                break;
  620.             case 3:
  621.             case 26:
  622.                var9 = var5 == var17;
  623.                if (var18 != 3 && !var1.anchoring) {
  624.                   var1.anchoring = true;
  625.  
  626.                   for(int var51 = var5; var51 <= var17; ++var51) {
  627.                      if (var51 == var17 || var4[var51] == '\n') {
  628.                         int var59 = this.matchRegExp(var1, var2, var3, var4, var51);
  629.                         if (var59 != -1) {
  630.                            var1.anchoring = false;
  631.                            var1.skipped = var51 - var5;
  632.                            return var59;
  633.                         }
  634.                      }
  635.                   }
  636.  
  637.                   var1.anchoring = false;
  638.                } else if (!var9 && var13.multiline) {
  639.                   var9 = var4[var5] == '\n';
  640.                }
  641.  
  642.                var10 = 0;
  643.                break;
  644.             case 4:
  645.                var9 = (var5 == var16 || !isWord(var4[var5 - 1])) ^ (var5 >= var4.length || !isWord(var4[var5]));
  646.                var10 = 0;
  647.                break;
  648.             case 5:
  649.                var9 = (var5 == var16 || !isWord(var4[var5 - 1])) ^ (var5 < var4.length && isWord(var4[var5]));
  650.                var10 = 0;
  651.                break;
  652.             case 6:
  653.                var19 = this.readShort(this.program, var3);
  654.                int var39 = var3 + 2;
  655.                short var89 = this.readShort(this.program, var39);
  656.                var39 += 2;
  657.                short var97 = this.readShort(this.program, var39);
  658.                var39 += 3;
  659.                var1.pcend = var3 + var19;
  660.  
  661.                int var69;
  662.                for(var69 = 0; var69 < var89; ++var69) {
  663.                   var5 = this.matchRegExp(var1, this.program, var39, var4, var5);
  664.                   if (var5 == -1) {
  665.                      var1.pcend = var15;
  666.                      return -1;
  667.                   }
  668.                }
  669.  
  670.                while(var97 == 0 || var69 < var97) {
  671.                   int var50 = this.matchRegExp(var1, this.program, var39, var4, var5);
  672.                   if (var50 == -1) {
  673.                      break;
  674.                   }
  675.  
  676.                   var5 = var50;
  677.                   ++var69;
  678.                }
  679.  
  680.                var1.pcend = var15;
  681.                var9 = var89 <= var69 && (var97 == 0 || var69 <= var97);
  682.                var10 = 0;
  683.                break;
  684.             case 7:
  685.                ++var3;
  686.                var18 = this.program[var3];
  687.                var19 = reopsize[var18];
  688.  
  689.                int var49;
  690.                for(var49 = var5; var5 < var17; ++var5) {
  691.                   var14[0] = var19;
  692.                   var9 = this.matchSingleCases(var18, var4, var5, var17, this.program, var3, var14);
  693.                   var19 = var14[0];
  694.                   var10 = 1;
  695.                   if (!var9) {
  696.                      break;
  697.                   }
  698.                }
  699.  
  700.                var3 += var19;
  701.  
  702.                do {
  703.                   int var58 = this.matchRegExp(var1, this.program, var3, var4, var5);
  704.                   if (var58 != -1) {
  705.                      return var58;
  706.                   }
  707.  
  708.                   --var5;
  709.                } while(var5 >= var49);
  710.  
  711.                return -1;
  712.             case 8:
  713.                ++var3;
  714.                var18 = this.program[var3];
  715.                var19 = reopsize[var18];
  716.  
  717.                int var47;
  718.                for(var47 = var5; var5 < var17; ++var5) {
  719.                   var14[0] = var19;
  720.                   var9 = this.matchSingleCases(var18, var4, var5, var17, this.program, var3, var14);
  721.                   var19 = var14[0];
  722.                   var10 = 1;
  723.                   if (!var9) {
  724.                      break;
  725.                   }
  726.                }
  727.  
  728.                if (var5 == var47) {
  729.                   return -1;
  730.                }
  731.  
  732.                ++var47;
  733.                var3 += var19;
  734.  
  735.                do {
  736.                   int var57 = this.matchRegExp(var1, this.program, var3, var4, var5);
  737.                   if (var57 != -1) {
  738.                      return var57;
  739.                   }
  740.  
  741.                   --var5;
  742.                } while(var5 >= var47);
  743.  
  744.                return -1;
  745.             case 9:
  746.                ++var3;
  747.                var18 = this.program[var3];
  748.                var14[0] = reopsize[var18];
  749.                var9 = this.matchSingleCases(var18, var4, var5, var17, this.program, var3, var14);
  750.                var19 = var14[0];
  751.                var10 = 1;
  752.                var3 += var19;
  753.                if (var9) {
  754.                   int var46 = this.matchRegExp(var1, this.program, var3, var4, var5 + 1);
  755.                   if (var46 != -1) {
  756.                      return var46;
  757.                   }
  758.                }
  759.                continue;
  760.             case 10:
  761.                short var68 = this.readShort(this.program, var3);
  762.                SubString var87 = var1.maybeParens[var68];
  763.                if (var87 == null) {
  764.                   var87 = var1.maybeParens[var68] = new SubString();
  765.                }
  766.  
  767.                int var96 = var87.index;
  768.                var87.charArray = var4;
  769.                var87.index = var5;
  770.                var3 += var19;
  771.                int var56 = this.matchRegExp(var1, this.program, var3, var4, var5);
  772.                if (var56 == -1) {
  773.                   var87.index = var96;
  774.                   return -1;
  775.                }
  776.  
  777.                var87 = var1.parens[var68];
  778.                if (var87 == null) {
  779.                   var87 = var1.parens[var68] = new SubString();
  780.                }
  781.  
  782.                if (var87.index == 0) {
  783.                   var87.charArray = var4;
  784.                   int var45 = var16 + var1.start + var1.skipped;
  785.                   if (var5 < var45) {
  786.                      var87.index = var45;
  787.                      var87.length -= var45 - var5;
  788.                   } else {
  789.                      var87.index = var5;
  790.                   }
  791.                }
  792.  
  793.                return var56;
  794.             case 11:
  795.                short var67 = this.readShort(this.program, var3);
  796.                SubString var85 = var1.maybeParens[var67];
  797.                if (var85 == null) {
  798.                   var85 = var1.maybeParens[var67] = new SubString();
  799.                }
  800.  
  801.                int var95 = var5 - var85.index;
  802.                var85.length = var95;
  803.                var3 += var19;
  804.                var5 = this.matchRegExp(var1, this.program, var3, var4, var5);
  805.                if (var5 != -1) {
  806.                   var85 = var1.parens[var67];
  807.                   if (var85 == null) {
  808.                      var85 = var1.parens[var67] = new SubString();
  809.                   }
  810.  
  811.                   if (var85.index == 0) {
  812.                      var85.length = var95;
  813.                   }
  814.  
  815.                   if (var67 >= var1.parenCount) {
  816.                      var1.parenCount = var67 + 1;
  817.                   }
  818.                }
  819.  
  820.                return var5;
  821.             case 12:
  822.             case 13:
  823.             case 14:
  824.             case 15:
  825.             case 16:
  826.             case 17:
  827.             case 18:
  828.             case 19:
  829.             case 22:
  830.             case 28:
  831.             case 29:
  832.             case 30:
  833.             case 33:
  834.             case 35:
  835.                var14[0] = var19;
  836.                var9 = this.matchSingleCases(var18, var4, var5, var17, this.program, var3, var14);
  837.                var19 = var14[0];
  838.                var10 = 1;
  839.                break;
  840.             case 20:
  841.                byte var66 = this.program[var3 + 1];
  842.                SubString var84 = var1.maybeParens[var66];
  843.                if (var84 == null) {
  844.                   var84 = var1.maybeParens[var66] = new SubString();
  845.                }
  846.  
  847.                var10 = var84.length;
  848.                var9 = var17 - var5 >= var10;
  849.                if (var9) {
  850.                   for(int var94 = 0; var94 < var10; ++var94) {
  851.                      if (var4[var5 + var94] != var84.charArray[var84.index + var94]) {
  852.                         var9 = false;
  853.                         break label511;
  854.                      }
  855.                   }
  856.                }
  857.                break;
  858.             case 21:
  859.                var10 = this.program[var3 + 1];
  860.                var19 += var10;
  861.                var9 = var5 + var10 <= var17;
  862.                if (var9) {
  863.                   for(int var83 = 0; var83 < var10; ++var83) {
  864.                      if (var4[var5 + var83] != (char)(this.program[var3 + 2 + var83] & 255)) {
  865.                         var9 = false;
  866.                         break;
  867.                      }
  868.                   }
  869.                }
  870.                break;
  871.             case 23:
  872.                var19 = this.readShort(this.program, var3);
  873.                var3 += var19;
  874.                continue;
  875.             case 24:
  876.                int var44;
  877.                for(var44 = var5; var44 < var17 && var4[var44] != '\n'; ++var44) {
  878.                }
  879.  
  880.                for(int var38 = var3 + var19; var44 >= var5; --var44) {
  881.                   int var55 = this.matchRegExp(var1, this.program, var38, var4, var44);
  882.                   if (var55 != -1) {
  883.                      return var55;
  884.                   }
  885.                }
  886.  
  887.                return -1;
  888.             case 25:
  889.                int var37 = var3 + var19;
  890.                if (var37 != var15) {
  891.                   for(int var43 = var5; var43 < var17; ++var43) {
  892.                      int var54 = this.matchRegExp(var1, this.program, var37, var4, var43);
  893.                      if (var54 != -1) {
  894.                         var1.skipped = var43 - var5;
  895.                         return var54;
  896.                      }
  897.                   }
  898.  
  899.                   return -1;
  900.                }
  901.                break;
  902.             case 27:
  903.                var10 = this.program[var3 + 1];
  904.                var19 += 2 * var10;
  905.                var9 = var5 + var10 <= var17;
  906.                if (var9) {
  907.                   int var35 = var3 + 2;
  908.  
  909.                   for(int var82 = 0; var82 < var10; ++var82) {
  910.                      char var93 = var4[var5 + var82];
  911.                      char var101 = (char)(this.program[var35++] << 8);
  912.                      var101 = (char)(var101 | this.program[var35++] & 255);
  913.                      var9 = var93 == var101;
  914.                      if (!var9) {
  915.                         break;
  916.                      }
  917.                   }
  918.                }
  919.                break;
  920.             case 31:
  921.                byte var11 = this.program[var3 + 1];
  922.                SubString var81 = var1.maybeParens[var11];
  923.                if (var81 == null) {
  924.                   var81 = var1.maybeParens[var11] = new SubString();
  925.                }
  926.  
  927.                var10 = var81.length;
  928.                var9 = var17 - var5 >= var10;
  929.                if (var9) {
  930.                   for(int var92 = 0; var92 < var10; ++var92) {
  931.                      char var100 = var4[var5 + var92];
  932.                      char var23 = var81.charArray[var81.index + var92];
  933.                      var9 = var100 == var23 || this.matchCharsIgnoringCase(var100, var23);
  934.                      if (!var9) {
  935.                         break label511;
  936.                      }
  937.                   }
  938.                }
  939.                break;
  940.             case 32:
  941.                var10 = this.program[var3 + 1];
  942.                var19 += var10;
  943.                var9 = var5 + var10 <= var17;
  944.                if (var9) {
  945.                   for(int var80 = 0; var80 < var10; ++var80) {
  946.                      char var91 = var4[var5 + var80];
  947.                      char var99 = (char)(this.program[var3 + 2 + var80] & 255);
  948.                      var9 = var91 == var99 || this.matchCharsIgnoringCase(var91, var99);
  949.                      if (!var9) {
  950.                         break;
  951.                      }
  952.                   }
  953.                }
  954.                break;
  955.             case 34:
  956.                var10 = this.program[var3 + 1];
  957.                var19 += 2 * var10;
  958.                var9 = var5 + var10 <= var17;
  959.                if (var9) {
  960.                   int var33 = var3 + 2;
  961.  
  962.                   for(int var20 = 0; var20 < var10; ++var20) {
  963.                      char var21 = var4[var5 + var20];
  964.                      char var22 = (char)(this.program[var33++] << 8);
  965.                      var22 = (char)(var22 | this.program[var33++] & 255);
  966.                      var9 = var21 == var22 || this.matchCharsIgnoringCase(var21, var22);
  967.                      if (!var9) {
  968.                         break;
  969.                      }
  970.                   }
  971.                }
  972.                break;
  973.             case 36:
  974.                ++var3;
  975.                var18 = this.program[var3];
  976.  
  977.                for(int var7 = var5; var5 < var17; ++var5) {
  978.                   var19 = reopsize[var18];
  979.                   var14[0] = var19;
  980.                   var9 = this.matchSingleCases(var18, var4, var5, var17, this.program, var3, var14);
  981.                   if (var9) {
  982.                      var19 = var14[0];
  983.                      int var6 = var3 + var19;
  984.                      if (var6 >= var15) {
  985.                         throw new RuntimeException();
  986.                      }
  987.  
  988.                      int var8 = this.matchRegExp(var1, this.program, var6, var4, var5);
  989.                      if (var8 != -1) {
  990.                         var1.skipped = var5 - var7;
  991.                         return var8;
  992.                      }
  993.                   }
  994.                }
  995.  
  996.                return -1;
  997.             default:
  998.                throw new RuntimeException("Unexpected op");
  999.          }
  1000.  
  1001.          if (!var9) {
  1002.             return -1;
  1003.          }
  1004.  
  1005.          var3 += var19;
  1006.          if (var10 != 0) {
  1007.             var5 += var10;
  1008.             if (var5 > var17) {
  1009.                var5 = var17;
  1010.             }
  1011.          }
  1012.       }
  1013.  
  1014.       return var5;
  1015.    }
  1016.  
  1017.    Object executeRegExp(Scriptable var1, String var2, int[] var3, boolean var4) {
  1018.       Context var6 = Context.getContext();
  1019.       RegExpStatics var7 = var6.getRegExpStatics();
  1020.       MatchState var8 = new MatchState();
  1021.       var8.anchoring = false;
  1022.       var8.pcend = this.program.length;
  1023.       char[] var9 = var2.toCharArray();
  1024.       int var10 = var3[0];
  1025.       if (var10 > var9.length) {
  1026.          var10 = var9.length;
  1027.       }
  1028.  
  1029.       var8.cpbegin = 0;
  1030.       var8.cpend = var9.length;
  1031.       var8.start = var10;
  1032.       var8.skipped = 0;
  1033.       var8.parenCount = 0;
  1034.       var8.maybeParens = new SubString[this.parenCount];
  1035.       var8.parens = new SubString[this.parenCount];
  1036.       int var11 = this.matchRegExp(var8, this.program, 0, var9, var10);
  1037.       if (var11 == -1) {
  1038.          return null;
  1039.       } else {
  1040.          int var12 = var11 - var8.cpbegin;
  1041.          var3[0] = var12;
  1042.          int var13 = var12 - (var10 + var8.skipped);
  1043.          var11 -= var13;
  1044.          Object var15;
  1045.          Scriptable var16;
  1046.          if (var4) {
  1047.             var15 = Boolean.TRUE;
  1048.             var16 = null;
  1049.          } else {
  1050.             Scriptable var17 = ScriptableObject.getTopLevelScope(var1);
  1051.             var15 = ScriptRuntime.newObject(var6, var17, "Array", (Object[])null);
  1052.             var16 = (Scriptable)var15;
  1053.             String var18 = new String(var9, var11, var13);
  1054.             var16.put(0, var16, var18);
  1055.          }
  1056.  
  1057.          if (var8.parenCount > this.parenCount) {
  1058.             throw new RuntimeException();
  1059.          } else {
  1060.             if (var8.parenCount == 0) {
  1061.                var7.parens.setSize(0);
  1062.                var7.lastParen = SubString.emptySubString;
  1063.             } else {
  1064.                SubString var21 = null;
  1065.                var7.parens.setSize(var8.parenCount);
  1066.  
  1067.                for(int var22 = 0; var22 < var8.parenCount; ++var22) {
  1068.                   var21 = var8.parens[var22];
  1069.                   var7.parens.setElementAt(var21, var22);
  1070.                   if (!var4) {
  1071.                      String var19 = var21 == null ? "" : var21.toString();
  1072.                      var16.put(var22 + 1, var16, var19);
  1073.                   }
  1074.                }
  1075.  
  1076.                var7.lastParen = var21;
  1077.             }
  1078.  
  1079.             if (!var4) {
  1080.                var16.put("index", var16, new Integer(var10 + var8.skipped));
  1081.                var16.put("input", var16, var2);
  1082.             }
  1083.  
  1084.             if (var7.lastMatch == null) {
  1085.                var7.lastMatch = new SubString();
  1086.                var7.leftContext = new SubString();
  1087.                var7.rightContext = new SubString();
  1088.             }
  1089.  
  1090.             var7.lastMatch.charArray = var9;
  1091.             var7.lastMatch.index = var11;
  1092.             var7.lastMatch.length = var13;
  1093.             var7.leftContext.charArray = var9;
  1094.             if (var6.getLanguageVersion() == 120) {
  1095.                var7.leftContext.index = var10;
  1096.                var7.leftContext.length = var8.skipped;
  1097.             } else {
  1098.                var7.leftContext.index = 0;
  1099.                var7.leftContext.length = var10 + var8.skipped;
  1100.             }
  1101.  
  1102.             var7.rightContext.charArray = var9;
  1103.             var7.rightContext.index = var11;
  1104.             var7.rightContext.length = var8.cpend - var11;
  1105.             return var15;
  1106.          }
  1107.       }
  1108.    }
  1109.  
  1110.    private boolean matchCharsIgnoringCase(char var1, char var2) {
  1111.       var1 = Character.toUpperCase(var1);
  1112.       var2 = Character.toUpperCase(var2);
  1113.       return var1 == var2 || Character.toLowerCase(var1) == Character.toLowerCase(var2);
  1114.    }
  1115.  
  1116.    private void write(int var1, char var2) {
  1117.       this.program[var1 + 1] = (byte)(var2 >>> 8 & 255);
  1118.       this.program[var1 + 2] = (byte)(var2 & 255);
  1119.    }
  1120.  
  1121.    private static Object execSub(Context var0, Scriptable var1, Object[] var2, Scriptable var3, boolean var4, Function var5) {
  1122.       if (!(var1 instanceof NativeRegExp)) {
  1123.          Object[] var11 = new Object[]{((NativeFunction)var5).names[0]};
  1124.          throw Context.reportRuntimeError(Context.getMessage("msg.incompat.call", var11));
  1125.       } else {
  1126.          NativeRegExp var6 = (NativeRegExp)var1;
  1127.          String var7;
  1128.          if (var2.length == 0) {
  1129.             var7 = var0.getRegExpStatics().input;
  1130.             if (var7 == null) {
  1131.                Object[] var8 = new Object[]{var6.toString()};
  1132.                throw Context.reportRuntimeError(Context.getMessage("msg.no.re.input.for", var8));
  1133.             }
  1134.          } else {
  1135.             var7 = ScriptRuntime.toString(var2[0]);
  1136.          }
  1137.  
  1138.          int var12;
  1139.          if ((var6.flags & 1) != 0) {
  1140.             var12 = var6.lastIndex;
  1141.          } else {
  1142.             var12 = 0;
  1143.          }
  1144.  
  1145.          int[] var9 = new int[]{var12};
  1146.          Object var10 = var6.executeRegExp(var3, var7, var9, var4);
  1147.          if ((var6.flags & 1) != 0) {
  1148.             var6.lastIndex = var10 == null ? 0 : var9[0];
  1149.          }
  1150.  
  1151.          return var10;
  1152.       }
  1153.    }
  1154.  
  1155.    private void write(int var1, short var2) {
  1156.       this.program[var1 + 1] = (byte)(var2 >>> 8 & 255);
  1157.       this.program[var1 + 2] = (byte)(var2 & 255);
  1158.    }
  1159.  
  1160.    private void reportError(String var1, String var2) {
  1161.       Object[] var3 = new Object[]{var2};
  1162.       String var4 = Context.getMessage(var1, var3);
  1163.       Context.reportRuntimeError(var4);
  1164.    }
  1165.  
  1166.    private RENode parseAltern(CompilerState var1) {
  1167.       RENode var2 = this.parseItem(var1);
  1168.       if (var2 == null) {
  1169.          return null;
  1170.       } else {
  1171.          RENode var3 = var2;
  1172.          int var4 = 0;
  1173.          char[] var5 = var1.source;
  1174.  
  1175.          char var7;
  1176.          for(int var6 = var1.index; var6 != var5.length && (var7 = var5[var6]) != '|' && var7 != ')'; var6 = var1.index) {
  1177.             RENode var8 = this.parseItem(var1);
  1178.             if (var8 == null) {
  1179.                return null;
  1180.             }
  1181.  
  1182.             this.setNext(var1, var3, var8);
  1183.             var4 |= var8.flags;
  1184.             var3 = var8;
  1185.          }
  1186.  
  1187.          var2.flags = (byte)(var2.flags | var4 & 4);
  1188.          return var2;
  1189.       }
  1190.    }
  1191.  
  1192.    private int storeChar(char[] var1, int var2, char var3, boolean var4) {
  1193.       for(int var5 = 0; var5 < var2; ++var5) {
  1194.          if (var1[var5] == '\\') {
  1195.             ++var5;
  1196.          }
  1197.  
  1198.          if (var1[var5] == var3 && (!var4 || var5 > 0 && var1[var5 - 1] == '\\')) {
  1199.             return var2;
  1200.          }
  1201.       }
  1202.  
  1203.       if (var4 || var3 == '\\' || var3 == '-') {
  1204.          var1[var2++] = '\\';
  1205.       }
  1206.  
  1207.       var1[var2++] = var3;
  1208.       return var2;
  1209.    }
  1210.  
  1211.    private boolean matchSingleCases(int var1, char[] var2, int var3, int var4, byte[] var5, int var6, int[] var7) {
  1212.       if (var3 >= var2.length) {
  1213.          return false;
  1214.       } else {
  1215.          char var8 = var2[var3];
  1216.          switch (var1) {
  1217.             case 12:
  1218.                if (var3 != var4 && var8 != '\n') {
  1219.                   return true;
  1220.                }
  1221.  
  1222.                return false;
  1223.             case 13:
  1224.                int var14 = var8 >> 3;
  1225.                int var15 = var8 & 7;
  1226.                var15 = 1 << var15;
  1227.                if ((var5[var6 + 1 + var14] & var15) == 0) {
  1228.                   return false;
  1229.                }
  1230.  
  1231.                return true;
  1232.             case 14:
  1233.                return isDigit(var8);
  1234.             case 15:
  1235.                if (isDigit(var8)) {
  1236.                   return false;
  1237.                }
  1238.  
  1239.                return true;
  1240.             case 16:
  1241.                return isWord(var8);
  1242.             case 17:
  1243.                if (isWord(var8)) {
  1244.                   return false;
  1245.                }
  1246.  
  1247.                return true;
  1248.             case 18:
  1249.                return Character.isWhitespace(var8);
  1250.             case 19:
  1251.                if (Character.isWhitespace(var8)) {
  1252.                   return false;
  1253.                }
  1254.  
  1255.                return true;
  1256.             case 22:
  1257.                if (var8 != (char)(var5[var6 + 1] & 255)) {
  1258.                   return false;
  1259.                }
  1260.  
  1261.                return true;
  1262.             case 28:
  1263.                if (var8 != (char)(var5[var6 + 1] << 8 | var5[var6 + 2] & 255)) {
  1264.                   return false;
  1265.                }
  1266.  
  1267.                return true;
  1268.             case 29:
  1269.             case 30:
  1270.                int var10 = var5[var6 + 1] << 8 | var5[var6 + 2] & 255;
  1271.                var7[0] += var10;
  1272.                int var11 = var8 >>> 3;
  1273.                if (var11 >= var10) {
  1274.                   if (var1 != 30) {
  1275.                      return false;
  1276.                   }
  1277.  
  1278.                   return true;
  1279.                } else {
  1280.                   int var12 = var8 & 7;
  1281.                   var12 = 1 << var12;
  1282.                   if ((var5[var6 + 3 + var11] & var12) == 0) {
  1283.                      return false;
  1284.                   }
  1285.  
  1286.                   return true;
  1287.                }
  1288.             case 33:
  1289.                char var13 = (char)(var5[var6 + 1] & 255);
  1290.                if (var8 != var13 && !this.matchCharsIgnoringCase(var8, var13)) {
  1291.                   return false;
  1292.                }
  1293.  
  1294.                return true;
  1295.             case 35:
  1296.                char var9 = (char)(var5[var6 + 1] << 8 | var5[var6 + 2] & 255);
  1297.                if (var8 != var9 && !this.matchCharsIgnoringCase(var8, var9)) {
  1298.                   return false;
  1299.                }
  1300.  
  1301.                return true;
  1302.             default:
  1303.                throw new RuntimeException("Unexpected op");
  1304.          }
  1305.       }
  1306.    }
  1307.  
  1308.    RENode parseAtom(CompilerState var1) {
  1309.       RENode var4 = null;
  1310.       boolean var7 = false;
  1311.       boolean var8 = false;
  1312.       char[] var9 = var1.source;
  1313.       int var28 = var1.index;
  1314.       int var11 = var28;
  1315.       if (var28 == var9.length) {
  1316.          var1.index = var28;
  1317.          return new RENode(var1, (byte)0, (Object)null);
  1318.       } else {
  1319.          label184:
  1320.          switch (var9[var28]) {
  1321.             case '(':
  1322.                int var17 = var1.parenCount++;
  1323.                var1.index = var28 + 1;
  1324.                RENode var5 = this.parseRegExp(var1);
  1325.                if (var5 == null) {
  1326.                   return null;
  1327.                }
  1328.  
  1329.                var28 = var1.index;
  1330.                if (var28 >= var9.length || var9[var28] != ')') {
  1331.                   this.reportError("msg.unterm.paren", this.tail(var9, var11));
  1332.                   return null;
  1333.                }
  1334.  
  1335.                ++var28;
  1336.                var4 = new RENode(var1, (byte)10, var5);
  1337.                var4.flags = (byte)(var5.flags & 5);
  1338.                var4.num = var17;
  1339.                var5 = new RENode(var1, (byte)11, (Object)null);
  1340.                this.setNext(var1, var4, var5);
  1341.                var5.num = var17;
  1342.                break;
  1343.             case '.':
  1344.                ++var28;
  1345.                if (var28 < var9.length && var9[var28] == '*') {
  1346.                   ++var28;
  1347.                   var4 = new RENode(var1, (byte)24, (Object)null);
  1348.                } else {
  1349.                   var4 = new RENode(var1, (byte)12, (Object)null);
  1350.                }
  1351.  
  1352.                if (var4.op == 12) {
  1353.                   var4.flags = 6;
  1354.                }
  1355.                break;
  1356.             case '[':
  1357.                ++var28;
  1358.                if (var28 == var9.length) {
  1359.                   this.reportError("msg.unterm.class", this.tail(var9, var11));
  1360.                   return null;
  1361.                }
  1362.  
  1363.                char var22 = var9[var28];
  1364.                var4 = new RENode(var1, (byte)13, new Integer(var28));
  1365.                if (var22 == '^') {
  1366.                   ++var28;
  1367.                   if (var28 == var9.length) {
  1368.                      this.reportError("msg.unterm.class", this.tail(var9, var11));
  1369.                      return null;
  1370.                   }
  1371.                }
  1372.  
  1373.                while(true) {
  1374.                   ++var28;
  1375.                   if (var28 == var9.length) {
  1376.                      this.reportError("msg.unterm.paren", this.tail(var9, var11));
  1377.                      return null;
  1378.                   }
  1379.  
  1380.                   var22 = var9[var28];
  1381.                   if (var22 == ']') {
  1382.                      var4.kid2 = var28++;
  1383.                      var4.flags = 6;
  1384.                      break label184;
  1385.                   }
  1386.  
  1387.                   if (var22 == '\\' && var28 + 1 != var9.length) {
  1388.                      ++var28;
  1389.                   }
  1390.                }
  1391.             case '\\':
  1392.                ++var28;
  1393.                if (var28 == var9.length) {
  1394.                   Context.reportError(Context.getMessage("msg.trail.backslash", (Object[])null));
  1395.                   return null;
  1396.                }
  1397.  
  1398.                char var6;
  1399.                var6 = var9[var28];
  1400.                label173:
  1401.                switch (var6) {
  1402.                   case '0':
  1403.                      var1.index = var28;
  1404.                      int var16 = this.doOctal(var1);
  1405.                      var28 = var1.index;
  1406.                      var4 = new RENode(var1, (byte)22, (Object)null);
  1407.                      var6 = (char)var16;
  1408.                      break;
  1409.                   case '1':
  1410.                   case '2':
  1411.                   case '3':
  1412.                   case '4':
  1413.                   case '5':
  1414.                   case '6':
  1415.                   case '7':
  1416.                   case '8':
  1417.                   case '9':
  1418.                      int var14 = unDigit(var6);
  1419.  
  1420.                      while(true) {
  1421.                         ++var28;
  1422.                         if (var28 >= var9.length || !isDigit(var6 = var9[var28])) {
  1423.                            if (var14 <= 9 && var14 <= var1.parenCount) {
  1424.                               --var28;
  1425.                               var4 = new RENode(var1, (byte)20, (Object)null);
  1426.                               var4.num = var14 - 1;
  1427.                               var4.flags = 4;
  1428.                               var7 = true;
  1429.                            } else {
  1430.                               var1.index = var11;
  1431.                               var14 = this.doOctal(var1);
  1432.                               var28 = var1.index;
  1433.                               var4 = new RENode(var1, (byte)22, (Object)null);
  1434.                               var6 = (char)var14;
  1435.                            }
  1436.                            break label173;
  1437.                         }
  1438.  
  1439.                         var14 = 10 * var14 - unDigit(var6);
  1440.                      }
  1441.                   case 'D':
  1442.                      var4 = new RENode(var1, (byte)15, (Object)null);
  1443.                      break;
  1444.                   case 'S':
  1445.                      var4 = new RENode(var1, (byte)19, (Object)null);
  1446.                      break;
  1447.                   case 'W':
  1448.                      var4 = new RENode(var1, (byte)17, (Object)null);
  1449.                      break;
  1450.                   case 'c':
  1451.                      ++var28;
  1452.                      var6 = var9[var28];
  1453.                      if ('A' <= var6 && var6 <= 'Z' || 'a' <= var6 && var6 <= 'z') {
  1454.                         var6 = Character.toUpperCase(var6);
  1455.                         var6 = (char)(var6 ^ 64);
  1456.                         var4 = new RENode(var1, (byte)22, (Object)null);
  1457.                         break;
  1458.                      }
  1459.  
  1460.                      var28 -= 2;
  1461.                      var11 = var28;
  1462.                      var8 = true;
  1463.                      var7 = true;
  1464.                      break;
  1465.                   case 'd':
  1466.                      var4 = new RENode(var1, (byte)14, (Object)null);
  1467.                      break;
  1468.                   case 'f':
  1469.                   case 'n':
  1470.                   case 'r':
  1471.                   case 't':
  1472.                   case 'v':
  1473.                      var6 = this.getEscape(var6);
  1474.                      var4 = new RENode(var1, (byte)22, (Object)null);
  1475.                      break;
  1476.                   case 's':
  1477.                      var4 = new RENode(var1, (byte)18, (Object)null);
  1478.                      break;
  1479.                   case 'u':
  1480.                      if (var28 + 4 < var9.length && isHex(var9[var28 + 1]) && isHex(var9[var28 + 2]) && isHex(var9[var28 + 3]) && isHex(var9[var28 + 4])) {
  1481.                         int var13 = (((unHex(var9[var28 + 1]) << 4) + unHex(var9[var28 + 2]) << 4) + unHex(var9[var28 + 3]) << 4) + unHex(var9[var28 + 4]);
  1482.                         var6 = (char)var13;
  1483.                         var28 += 4;
  1484.                         var4 = new RENode(var1, (byte)22, (Object)null);
  1485.                         break;
  1486.                      }
  1487.  
  1488.                      var11 = var28;
  1489.                      var8 = true;
  1490.                      var7 = true;
  1491.                      break;
  1492.                   case 'w':
  1493.                      var4 = new RENode(var1, (byte)16, (Object)null);
  1494.                      break;
  1495.                   case 'x':
  1496.                      var11 = var28++;
  1497.                      int var2;
  1498.                      if (var28 < var9.length && isHex(var6 = var9[var28])) {
  1499.                         var2 = unHex(var6);
  1500.                         ++var28;
  1501.                         if (var28 < var9.length && isHex(var6 = var9[var28])) {
  1502.                            var2 <<= 4;
  1503.                            var2 += unHex(var6);
  1504.                         } else {
  1505.                            --var28;
  1506.                         }
  1507.                      } else {
  1508.                         var28 = var11;
  1509.                         var2 = 120;
  1510.                      }
  1511.  
  1512.                      var4 = new RENode(var1, (byte)22, (Object)null);
  1513.                      var6 = (char)var2;
  1514.                      break;
  1515.                   default:
  1516.                      var11 = var28;
  1517.                      var8 = true;
  1518.                      var7 = true;
  1519.                }
  1520.  
  1521.                if (var4 != null && !var7) {
  1522.                   var4.chr = var6;
  1523.                   var4.flags = 6;
  1524.                }
  1525.  
  1526.                var7 = false;
  1527.                if (!var8) {
  1528.                   ++var28;
  1529.                   break;
  1530.                } else {
  1531.                   var8 = false;
  1532.                }
  1533.             default:
  1534.                while(true) {
  1535.                   ++var28;
  1536.                   if (var28 == var9.length || "|^${*+?().[\\".indexOf(var9[var28]) != -1) {
  1537.                      int var3 = var28 - var11;
  1538.                      if (var28 != var9.length && var3 > 1 && "{*+?".indexOf(var9[var28]) != -1) {
  1539.                         --var28;
  1540.                         --var3;
  1541.                      }
  1542.  
  1543.                      if (var3 > 255) {
  1544.                         var3 = 255;
  1545.                         var28 = var11 + var3;
  1546.                      }
  1547.  
  1548.                      var4 = new RENode(var1, (byte)(var3 == 1 ? 22 : 21), new Integer(var11));
  1549.                      var4.flags = 4;
  1550.                      if (var3 > 1) {
  1551.                         var4.kid2 = var28;
  1552.                      } else {
  1553.                         var4.flags = (byte)(var4.flags | 2);
  1554.                         var4.chr = var9[var11];
  1555.                      }
  1556.                      break;
  1557.                   }
  1558.                }
  1559.          }
  1560.  
  1561.          var1.index = var28;
  1562.          return var4;
  1563.       }
  1564.    }
  1565.  
  1566.    RENode parseItem(CompilerState var1) {
  1567.       char[] var4 = var1.source;
  1568.       int var5 = var1.index;
  1569.       switch (var5 < var4.length ? var4[var5] : '\u0000') {
  1570.          case '$':
  1571.             var1.index = var5 + 1;
  1572.             return new RENode(var1, (byte)(var5 != var1.indexBegin && (var4[var5 - 1] != '(' && var4[var5 - 1] != '|' || var5 - 1 != var1.indexBegin && var4[var5 - 2] == '\\') ? 3 : 26), (Object)null);
  1573.          case '\\':
  1574.             ++var5;
  1575.             byte var3;
  1576.             switch (var5 < var4.length ? var4[var5] : '\u0000') {
  1577.                case 'B':
  1578.                   var3 = 5;
  1579.                   break;
  1580.                case 'b':
  1581.                   var3 = 4;
  1582.                   break;
  1583.                default:
  1584.                   return this.parseQuantAtom(var1);
  1585.             }
  1586.  
  1587.             var1.index = var5 + 1;
  1588.             RENode var6 = new RENode(var1, var3, (Object)null);
  1589.             var6.flags = (byte)(var6.flags | 4);
  1590.             return var6;
  1591.          case '^':
  1592.             var1.index = var5 + 1;
  1593.             RENode var2 = new RENode(var1, (byte)2, (Object)null);
  1594.             var2.flags = (byte)(var2.flags | 1);
  1595.             return var2;
  1596.          default:
  1597.             return this.parseQuantAtom(var1);
  1598.       }
  1599.    }
  1600.  
  1601.    private int countFirstChars(RENode var1) {
  1602.       int var7 = 0;
  1603.  
  1604.       while(true) {
  1605.          RENode var3;
  1606.          for(var3 = (RENode)var1.kid; var3.op == 10; var3 = (RENode)var3.kid) {
  1607.          }
  1608.  
  1609.          switch (var3.op) {
  1610.             case 6:
  1611.                if (var3.min == 0) {
  1612.                   return -1;
  1613.                }
  1614.             case 1:
  1615.             case 8:
  1616.                int var2 = this.countFirstChars(var3);
  1617.                if (var2 < 0) {
  1618.                   return var2;
  1619.                }
  1620.  
  1621.                var7 += var2;
  1622.                break;
  1623.             case 13:
  1624.                int var5 = (Integer)var3.kid;
  1625.                if (this.source.charAt(var5) == '^') {
  1626.                   return -1;
  1627.                }
  1628.  
  1629.                int var6 = var3.kid2;
  1630.                var7 += var6 - var5;
  1631.                break;
  1632.             case 14:
  1633.             case 15:
  1634.             case 16:
  1635.             case 17:
  1636.             case 18:
  1637.             case 19:
  1638.                var7 += 2;
  1639.                break;
  1640.             case 21:
  1641.                char var8 = this.source.charAt((Integer)var3.kid);
  1642.                if (var8 != '\\' && var8 != '-') {
  1643.                   ++var7;
  1644.                } else {
  1645.                   var7 += 2;
  1646.                }
  1647.                break;
  1648.             case 22:
  1649.                char var4 = var3.chr;
  1650.                if (var4 != '\\' && var4 != '-') {
  1651.                   ++var7;
  1652.                } else {
  1653.                   var7 += 2;
  1654.                }
  1655.                break;
  1656.             default:
  1657.                return -1;
  1658.          }
  1659.  
  1660.          if (var1.op == 1) {
  1661.             var1 = var1.next;
  1662.             if (var1 != null && var1.op == 1) {
  1663.                continue;
  1664.             }
  1665.          }
  1666.  
  1667.          return var7;
  1668.       }
  1669.    }
  1670.  
  1671.    public boolean getGlobal() {
  1672.       return (this.flags & 1) != 0;
  1673.    }
  1674.  
  1675.    static int unHex(char var0) {
  1676.       return '0' <= var0 && var0 <= '9' ? var0 - 48 : 10 + Character.toLowerCase(var0) - 97;
  1677.    }
  1678.  
  1679.    public String getSource() {
  1680.       return this.source;
  1681.    }
  1682.  
  1683.    private char getEscape(char var1) {
  1684.       switch (var1) {
  1685.          case 'b':
  1686.             return '\b';
  1687.          case 'f':
  1688.             return '\f';
  1689.          case 'n':
  1690.             return '\n';
  1691.          case 'r':
  1692.             return '\r';
  1693.          case 't':
  1694.             return '\t';
  1695.          case 'v':
  1696.             return '\u000b';
  1697.          default:
  1698.             throw new RuntimeException();
  1699.       }
  1700.    }
  1701.  
  1702.    public Scriptable construct(Context var1, Scriptable var2, Object[] var3) {
  1703.       return (Scriptable)this.call(var1, var2, (Scriptable)null, var3);
  1704.    }
  1705.  
  1706.    private int doOctal(CompilerState var1) {
  1707.       char[] var2 = var1.source;
  1708.       int var3 = var1.index;
  1709.       int var4 = 0;
  1710.  
  1711.       while(true) {
  1712.          ++var3;
  1713.          char var5;
  1714.          if (var3 >= var2.length || '0' > (var5 = var2[var3]) || var5 > '7') {
  1715.             break;
  1716.          }
  1717.  
  1718.          var4 = 8 * var4 + (var5 - 48);
  1719.          if (var4 > 255) {
  1720.             this.reportError("msg.overlarge.octal", this.tail(var2, var1.index));
  1721.             var4 = 0;
  1722.             break;
  1723.          }
  1724.       }
  1725.  
  1726.       --var3;
  1727.       var1.index = var3;
  1728.       return var4;
  1729.    }
  1730.  
  1731.    public String toString() {
  1732.       StringBuffer var1 = new StringBuffer();
  1733.       var1.append('/');
  1734.       var1.append(this.source);
  1735.       var1.append('/');
  1736.       if ((this.flags & 1) != 0) {
  1737.          var1.append('g');
  1738.       }
  1739.  
  1740.       if ((this.flags & 2) != 0) {
  1741.          var1.append('i');
  1742.       }
  1743.  
  1744.       return var1.toString();
  1745.    }
  1746.  
  1747.    public NativeRegExp(Scriptable var1, String var2, String var3) {
  1748.       this.init(var1, var2, var3);
  1749.    }
  1750.  
  1751.    public NativeRegExp() {
  1752.    }
  1753.  
  1754.    private void dumpRegExp(CompilerState var1, RENode var2) {
  1755.    }
  1756.  
  1757.    private RENode parseRegExp(CompilerState var1) {
  1758.       RENode var2 = this.parseAltern(var1);
  1759.       if (var2 == null) {
  1760.          return null;
  1761.       } else {
  1762.          char[] var3 = var1.source;
  1763.          int var4 = var1.index;
  1764.          if (var4 < var3.length && var3[var4] == '|') {
  1765.             RENode var5 = var2;
  1766.             var2 = new RENode(var1, (byte)1, var2);
  1767.             if (var2 == null) {
  1768.                return null;
  1769.             }
  1770.  
  1771.             var2.flags = (byte)(var5.flags & 5);
  1772.             RENode var6 = var2;
  1773.  
  1774.             do {
  1775.                ++var4;
  1776.                var1.index = var4;
  1777.                if (var4 >= var3.length || var3[var4] != '|' && var3[var4] != ')') {
  1778.                   var5 = this.parseAltern(var1);
  1779.                   var4 = var1.index;
  1780.                } else {
  1781.                   var5 = new RENode(var1, (byte)0, (Object)null);
  1782.                }
  1783.  
  1784.                if (var5 == null) {
  1785.                   return null;
  1786.                }
  1787.  
  1788.                RENode var7 = new RENode(var1, (byte)1, var5);
  1789.                if (var7 == null) {
  1790.                   return null;
  1791.                }
  1792.  
  1793.                var6.next = var7;
  1794.                var6.flags = (byte)(var6.flags | 16);
  1795.                var7.flags = (byte)(var5.flags & 5 | 8);
  1796.                var6 = var7;
  1797.             } while(var4 < var3.length && var3[var4] == '|');
  1798.          }
  1799.  
  1800.          return var2;
  1801.       }
  1802.    }
  1803.  
  1804.    public static Scriptable compile(Context var0, Scriptable var1, Object[] var2, Function var3) {
  1805.       NativeRegExp var4 = (NativeRegExp)var1;
  1806.       String var5 = var2.length == 0 ? "" : ScriptRuntime.toString(var2[0]);
  1807.       String var6 = var2.length > 1 ? ScriptRuntime.toString(var2[1]) : null;
  1808.       var4.init(var3, var5, var6);
  1809.       return var4;
  1810.    }
  1811.  
  1812.    private short readShort(byte[] var1, int var2) {
  1813.       return (short)(var1[var2 + 1] << 8 | var1[var2 + 2] & 255);
  1814.    }
  1815.  
  1816.    static boolean isWord(char var0) {
  1817.       return Character.isLetter(var0) || isDigit(var0) || var0 == '_';
  1818.    }
  1819.  
  1820.    private void checkRange(char var1, int var2, int var3) {
  1821.       this.matchBit(var1, var2, var3);
  1822.       this.matchBit('-', var2, var3);
  1823.    }
  1824.  
  1825.    static int unDigit(char var0) {
  1826.       return var0 - 48;
  1827.    }
  1828.  
  1829.    private RENode closeTail(CompilerState var1, RENode var2, RENode var3) {
  1830.       RENode var4 = new RENode(var1, (byte)0, (Object)null);
  1831.       RENode var5 = new RENode(var1, (byte)1, var4);
  1832.       var2.next = var5;
  1833.       var5.next = var4.next = var3;
  1834.       if ((var2.flags & 16) != 0) {
  1835.          var5.flags = (byte)(var5.flags | 16);
  1836.       } else {
  1837.          var2.flags = (byte)(var2.flags | 16);
  1838.       }
  1839.  
  1840.       var5.flags = (byte)(var5.flags | 8);
  1841.       return var5;
  1842.    }
  1843.  
  1844.    private String tail(char[] var1, int var2) {
  1845.       return new String(var1, var2, var1.length - var2);
  1846.    }
  1847.  
  1848.    String getPrintableString(String var1) {
  1849.       return "";
  1850.    }
  1851.  
  1852.    public int getLastIndex() {
  1853.       return this.lastIndex;
  1854.    }
  1855.  
  1856.    public void setLastIndex(int var1) {
  1857.       this.lastIndex = var1;
  1858.    }
  1859.  
  1860.    private void fixNext(CompilerState var1, RENode var2, RENode var3, RENode var4) {
  1861.       boolean var5;
  1862.       RENode var6;
  1863.       for(var5 = var3 != null && (var3.flags & 8) == 0; (var6 = var2.next) != null && var6 != var4; var2 = var6) {
  1864.          if (var2.op == 1) {
  1865.             RENode var7 = (RENode)var2.kid;
  1866.             if (var7.op != 23) {
  1867.                RENode var8;
  1868.                for(var8 = var7; var8.next != null; var8 = var8.next) {
  1869.                   if (var8.op == 1) {
  1870.                      throw new RuntimeException("REOP_ALT not expected");
  1871.                   }
  1872.                }
  1873.  
  1874.                var8.next = new RENode(var1, (byte)23, (Object)null);
  1875.                RENode var10000 = var8.next;
  1876.                var10000.flags = (byte)(var10000.flags | 8);
  1877.                var8.flags = (byte)(var8.flags | 16);
  1878.                this.fixNext(var1, var7, var3, var4);
  1879.             }
  1880.          }
  1881.       }
  1882.  
  1883.       if (var3 != null) {
  1884.          if ((var3.flags & 8) == 0) {
  1885.             var3.flags = (byte)(var3.flags | 8);
  1886.          } else {
  1887.             var3.flags = (byte)(var3.flags | 32);
  1888.          }
  1889.       }
  1890.  
  1891.       var2.next = var3;
  1892.       if (var5) {
  1893.          var2.flags = (byte)(var2.flags | 16);
  1894.       }
  1895.  
  1896.       switch (var2.op) {
  1897.          case 1:
  1898.          case 6:
  1899.          case 7:
  1900.          case 8:
  1901.          case 9:
  1902.          case 10:
  1903.             this.fixNext(var1, (RENode)var2.kid, var3, var4);
  1904.             return;
  1905.          case 2:
  1906.          case 3:
  1907.          case 4:
  1908.          case 5:
  1909.          default:
  1910.       }
  1911.    }
  1912.  
  1913.    static boolean isHex(char var0) {
  1914.       return '0' <= var0 && var0 <= '9' || 'a' <= var0 && var0 <= 'f' || 'A' <= var0 && var0 <= 'F';
  1915.    }
  1916.  
  1917.    public Object call(Context var1, Scriptable var2, Scriptable var3, Object[] var4) {
  1918.       return execSub(var1, this, var4, var2, false, this);
  1919.    }
  1920.  
  1921.    // $FF: synthetic method
  1922.    private static Class class$(String var0) {
  1923.       try {
  1924.          return Class.forName(var0);
  1925.       } catch (ClassNotFoundException var2) {
  1926.          throw new NoClassDefFoundError(((Throwable)var2).getMessage());
  1927.       }
  1928.    }
  1929.  
  1930.    private int storeFirstChars(CompilerState var1, RENode var2, char[] var3, int var4) {
  1931.       while(true) {
  1932.          RENode var5;
  1933.          for(var5 = (RENode)var2.kid; var5.op == 10; var5 = (RENode)var5.kid) {
  1934.          }
  1935.  
  1936.          switch (var5.op) {
  1937.             case 6:
  1938.                if (var5.min == 0) {
  1939.                   throw new RuntimeException();
  1940.                }
  1941.             case 1:
  1942.             case 8:
  1943.                var4 = this.storeFirstChars(var1, var5, var3, var4);
  1944.                break;
  1945.             case 13:
  1946.                int var7 = var5.kid2;
  1947.                char[] var9 = var5.s != null ? var5.s : var1.source;
  1948.  
  1949.                for(int var6 = (Integer)var5.kid; var6 < var7; ++var6) {
  1950.                   var3[var4++] = var9[var6];
  1951.                }
  1952.                break;
  1953.             case 14:
  1954.                var4 = this.storeChar(var3, var4, 'd', true);
  1955.                break;
  1956.             case 15:
  1957.                var4 = this.storeChar(var3, var4, 'D', true);
  1958.                break;
  1959.             case 16:
  1960.                var4 = this.storeChar(var3, var4, 'w', true);
  1961.                break;
  1962.             case 17:
  1963.                var4 = this.storeChar(var3, var4, 'W', true);
  1964.                break;
  1965.             case 18:
  1966.                var4 = this.storeChar(var3, var4, 's', true);
  1967.                break;
  1968.             case 19:
  1969.                var4 = this.storeChar(var3, var4, 'S', true);
  1970.                break;
  1971.             case 21:
  1972.                char[] var8 = var5.s != null ? var5.s : var1.source;
  1973.                var4 = this.storeChar(var3, var4, var8[(Integer)var5.kid], false);
  1974.                break;
  1975.             case 22:
  1976.                var4 = this.storeChar(var3, var4, var5.chr, false);
  1977.                break;
  1978.             default:
  1979.                throw new RuntimeException();
  1980.          }
  1981.  
  1982.          if (var2.op == 1) {
  1983.             var2 = var2.next;
  1984.             if (var2 != null && var2.op == 1) {
  1985.                continue;
  1986.             }
  1987.          }
  1988.  
  1989.          return var4;
  1990.       }
  1991.    }
  1992.  
  1993.    public static void init(Scriptable var0) throws PropertyException {
  1994.       NativeRegExp var1 = new NativeRegExp();
  1995.       ((ScriptableObject)var1).setParentScope(var0);
  1996.       ((ScriptableObject)var1).setPrototype(ScriptableObject.getObjectPrototype(var0));
  1997.       String[] var2 = new String[]{"compile", "toString", "exec", "test"};
  1998.       ((ScriptableObject)var1).defineFunctionProperties(var2, class$com$netscape$javascript$NativeRegExp != null ? class$com$netscape$javascript$NativeRegExp : (class$com$netscape$javascript$NativeRegExp = class$("com.netscape.javascript.NativeRegExp")), 2);
  1999.       String[] var3 = new String[]{"lastIndex", "source", "global", "ignoreCase"};
  2000.       int[] var4 = new int[]{4, 5, 5, 5};
  2001.  
  2002.       for(int var5 = 0; var5 < var3.length; ++var5) {
  2003.          ((ScriptableObject)var1).defineProperty(var3[var5], class$com$netscape$javascript$NativeRegExp != null ? class$com$netscape$javascript$NativeRegExp : (class$com$netscape$javascript$NativeRegExp = class$("com.netscape.javascript.NativeRegExp")), var4[var5]);
  2004.       }
  2005.  
  2006.       Scriptable var6 = NativeRegExpCtor.init(var0);
  2007.       var6.put("prototype", var6, var1);
  2008.    }
  2009.  
  2010.    public void init(Scriptable var1, String var2, String var3) {
  2011.       this.source = var2;
  2012.       this.flags = 0;
  2013.       if (var3 != null) {
  2014.          for(int var4 = 0; var4 < var3.length(); ++var4) {
  2015.             char var5 = var3.charAt(var4);
  2016.             if (var5 == 'g') {
  2017.                this.flags = (byte)(this.flags | 1);
  2018.             } else {
  2019.                if (var5 != 'i') {
  2020.                   Object[] var6 = new Object[]{new Character(var5)};
  2021.                   throw Context.reportRuntimeError(Context.getMessage("msg.invalid.re.flag", var6));
  2022.                }
  2023.  
  2024.                this.flags = (byte)(this.flags | 2);
  2025.             }
  2026.          }
  2027.       }
  2028.  
  2029.       CompilerState var10 = new CompilerState(var2, this.flags);
  2030.       RENode var11 = this.parseRegExp(var10);
  2031.       if (var11 != null) {
  2032.          RENode var12 = new RENode(var10, (byte)37, (Object)null);
  2033.          this.setNext(var10, var11, var12);
  2034.          this.anchorRegExp(var10, var11);
  2035.          this.optimizeRegExp(var10, var11);
  2036.          this.program = new byte[var10.progLength];
  2037.          this.lastIndex = 0;
  2038.          this.parenCount = var10.parenCount;
  2039.          this.flags = this.flags;
  2040.          var10.progLength = 0;
  2041.          this.emitRegExp(var10, var11);
  2042.          var1 = ScriptableObject.getTopLevelScope(var1);
  2043.          ((ScriptableObject)this).setPrototype(ScriptableObject.getClassPrototype(var1, "RegExp"));
  2044.          ((ScriptableObject)this).setParentScope(var1);
  2045.       }
  2046.    }
  2047.  
  2048.    private void emitRegExp(CompilerState var1, RENode var2) {
  2049.       NativeRegExp var12 = this;
  2050.  
  2051.       while(true) {
  2052.          byte var17 = var2.op;
  2053.          if (var17 == 37) {
  2054.             return;
  2055.          }
  2056.  
  2057.          int var18 = var1.progLength;
  2058.          var1.progLength += reopsize[var2.op];
  2059.          var12.program[var18] = var2.op;
  2060.          RENode var4 = var2.next;
  2061.          char[] var19 = var2.s != null ? var2.s : var1.source;
  2062.          switch (var17) {
  2063.             case 1:
  2064.                int var23 = var4.offset - var2.offset;
  2065.                this.write(var18, (short)var23);
  2066.                this.emitRegExp(var1, (RENode)var2.kid);
  2067.                break;
  2068.             case 6:
  2069.                int var22 = var4.offset - var2.offset;
  2070.                this.write(var18, (short)var22);
  2071.                var18 += 2;
  2072.                this.write(var18, var2.min);
  2073.                var18 += 2;
  2074.                this.write(var18, var2.max);
  2075.                this.emitRegExp(var1, (RENode)var2.kid);
  2076.                break;
  2077.             case 7:
  2078.             case 8:
  2079.             case 9:
  2080.             case 36:
  2081.                this.emitRegExp(var1, (RENode)var2.kid);
  2082.                break;
  2083.             case 10:
  2084.                this.write(var18, (short)var2.num);
  2085.                this.emitRegExp(var1, (RENode)var2.kid);
  2086.                break;
  2087.             case 11:
  2088.                this.write(var18, (short)var2.num);
  2089.                break;
  2090.             case 13:
  2091.             case 29:
  2092.                int var24 = (Integer)var2.kid;
  2093.                byte var3;
  2094.                if (var19[var24] == '^') {
  2095.                   if (var17 == 29) {
  2096.                      this.program[var18] = 30;
  2097.                   }
  2098.  
  2099.                   var3 = -1;
  2100.                   ++var24;
  2101.                } else {
  2102.                   var3 = 0;
  2103.                }
  2104.  
  2105.                ++var18;
  2106.                int var7;
  2107.                int var16;
  2108.                if (var17 == 13) {
  2109.                   var7 = var2.kid2;
  2110.                   int var27 = 0;
  2111.  
  2112.                   do {
  2113.                      this.program[var18 + var27] = var3;
  2114.                      ++var27;
  2115.                   } while(var27 < 32);
  2116.  
  2117.                   var16 = 256;
  2118.                } else {
  2119.                   var7 = var24 + var2.kidlen;
  2120.                   short var10 = var2.bmsize;
  2121.                   this.program[var18++] = (byte)(var10 >>> 8);
  2122.                   this.program[var18++] = (byte)var10;
  2123.                   var1.progLength += var10;
  2124.  
  2125.                   for(int var26 = 0; var26 < var10; ++var26) {
  2126.                      this.program[var18 + var26] = var3;
  2127.                   }
  2128.  
  2129.                   var16 = var10 * 8;
  2130.                }
  2131.  
  2132.                char var14 = (char)var16;
  2133.                boolean var11 = false;
  2134.  
  2135.                label267:
  2136.                while(var24 < var7) {
  2137.                   char var34 = var19[var24++];
  2138.                   if (var34 == '\\') {
  2139.                      var34 = var19[var24++];
  2140.                      switch (var34) {
  2141.                         case '0':
  2142.                         case '1':
  2143.                         case '2':
  2144.                         case '3':
  2145.                         case '4':
  2146.                         case '5':
  2147.                         case '6':
  2148.                         case '7':
  2149.                            int var32 = unDigit(var34);
  2150.                            int var25 = var24 - 2;
  2151.                            var34 = var19[var24];
  2152.                            if ('0' <= var34 && var34 <= '7') {
  2153.                               ++var24;
  2154.                               var32 = 8 * var32 + unDigit(var34);
  2155.                               var34 = var19[var24];
  2156.                               if ('0' <= var34 && var34 <= '7') {
  2157.                                  ++var24;
  2158.                                  int var28 = 8 * var32 + unDigit(var34);
  2159.                                  if (var28 <= 255) {
  2160.                                     var32 = var28;
  2161.                                  } else {
  2162.                                     --var24;
  2163.                                  }
  2164.                               }
  2165.                            }
  2166.  
  2167.                            var34 = (char)var32;
  2168.                            break;
  2169.                         case 'D':
  2170.                            if (var11) {
  2171.                               this.checkRange(var14, var3, var18);
  2172.                            }
  2173.  
  2174.                            var14 = (char)var16;
  2175.  
  2176.                            for(char var44 = 0; var44 < '0'; ++var44) {
  2177.                               this.matchBit(var44, var3, var18);
  2178.                            }
  2179.  
  2180.                            var34 = ':';
  2181.  
  2182.                            while(true) {
  2183.                               if (var34 >= var16) {
  2184.                                  continue label267;
  2185.                               }
  2186.  
  2187.                               this.matchBit(var34, var3, var18);
  2188.                               ++var34;
  2189.                            }
  2190.                         case 'S':
  2191.                            if (var11) {
  2192.                               this.checkRange(var14, var3, var18);
  2193.                            }
  2194.  
  2195.                            var14 = (char)var16;
  2196.                            var34 = '\u0000';
  2197.  
  2198.                            while(true) {
  2199.                               if (var34 >= var16) {
  2200.                                  continue label267;
  2201.                               }
  2202.  
  2203.                               if (!Character.isWhitespace(var34)) {
  2204.                                  this.matchBit(var34, var3, var18);
  2205.                               }
  2206.  
  2207.                               ++var34;
  2208.                            }
  2209.                         case 'W':
  2210.                            if (var11) {
  2211.                               this.checkRange(var14, var3, var18);
  2212.                            }
  2213.  
  2214.                            var14 = (char)var16;
  2215.                            var34 = '\u0000';
  2216.  
  2217.                            while(true) {
  2218.                               if (var34 >= var16) {
  2219.                                  continue label267;
  2220.                               }
  2221.  
  2222.                               if (!isWord(var34)) {
  2223.                                  this.matchBit(var34, var3, var18);
  2224.                               }
  2225.  
  2226.                               ++var34;
  2227.                            }
  2228.                         case 'b':
  2229.                         case 'f':
  2230.                         case 'n':
  2231.                         case 'r':
  2232.                         case 't':
  2233.                         case 'v':
  2234.                            var34 = this.getEscape(var34);
  2235.                            break;
  2236.                         case 'c':
  2237.                            var34 = var19[var24++];
  2238.                            var34 = Character.toUpperCase(var34);
  2239.                            var34 = (char)(var34 ^ 64);
  2240.                            break;
  2241.                         case 'd':
  2242.                            if (var11) {
  2243.                               this.checkRange(var14, var3, var18);
  2244.                            }
  2245.  
  2246.                            var14 = (char)var16;
  2247.                            var34 = '0';
  2248.  
  2249.                            while(true) {
  2250.                               if (var34 > '9') {
  2251.                                  continue label267;
  2252.                               }
  2253.  
  2254.                               this.matchBit(var34, var3, var18);
  2255.                               ++var34;
  2256.                            }
  2257.                         case 's':
  2258.                            if (var11) {
  2259.                               this.checkRange(var14, var3, var18);
  2260.                            }
  2261.  
  2262.                            var14 = (char)var16;
  2263.                            var34 = '\u0000';
  2264.  
  2265.                            while(true) {
  2266.                               if (var34 >= var16) {
  2267.                                  continue label267;
  2268.                               }
  2269.  
  2270.                               if (Character.isWhitespace(var34)) {
  2271.                                  this.matchBit(var34, var3, var18);
  2272.                               }
  2273.  
  2274.                               ++var34;
  2275.                            }
  2276.                         case 'u':
  2277.                            if (var19.length > var24 + 3 && isHex(var19[var24]) && isHex(var19[var24 + 1]) && isHex(var19[var24 + 2]) && isHex(var19[var24 + 3])) {
  2278.                               int var31 = (((unHex(var19[var24]) << 4) + unHex(var19[var24 + 1]) << 4) + unHex(var19[var24 + 2]) << 4) + unHex(var19[var24 + 3]);
  2279.                               var34 = (char)var31;
  2280.                               var24 += 4;
  2281.                            }
  2282.                            break;
  2283.                         case 'w':
  2284.                            if (var11) {
  2285.                               this.checkRange(var14, var3, var18);
  2286.                            }
  2287.  
  2288.                            var14 = (char)var16;
  2289.  
  2290.                            for(char var37 = 0; var37 < var16; ++var37) {
  2291.                               if (isWord(var37)) {
  2292.                                  this.matchBit(var37, var3, var18);
  2293.                               }
  2294.                            }
  2295.                            continue;
  2296.                         case 'x':
  2297.                            int var8 = var24;
  2298.                            int var29;
  2299.                            if (var24 < var19.length && isHex(var34 = var19[var24++])) {
  2300.                               var29 = unHex(var34);
  2301.                               if (var24 < var19.length && isHex(var34 = var19[var24++])) {
  2302.                                  var29 <<= 4;
  2303.                                  var29 += unHex(var34);
  2304.                               }
  2305.                            } else {
  2306.                               var24 = var8;
  2307.                               var29 = 120;
  2308.                            }
  2309.  
  2310.                            var34 = (char)var29;
  2311.                      }
  2312.                   }
  2313.  
  2314.                   if (var11) {
  2315.                      if (var14 > var34) {
  2316.                         throw Context.reportRuntimeError(Context.getMessage("msg.bad.range", (Object[])null));
  2317.                      }
  2318.  
  2319.                      var11 = false;
  2320.                   } else {
  2321.                      var14 = var34;
  2322.                      if (var24 + 1 < var7 && var19[var24] == '-' && var19[var24 + 1] != ']') {
  2323.                         ++var24;
  2324.                         var11 = true;
  2325.                         continue;
  2326.                      }
  2327.                   }
  2328.  
  2329.                   for(; var14 <= var34; ++var14) {
  2330.                      this.matchBit(var14, var3, var18);
  2331.                      if ((var1.flags & 2) != 0) {
  2332.                         char var15 = Character.toUpperCase(var14);
  2333.                         this.matchBit(var15, var3, var18);
  2334.                         var15 = Character.toLowerCase(var15);
  2335.                         this.matchBit(var15, var3, var18);
  2336.                      }
  2337.                   }
  2338.  
  2339.                   var14 = var34;
  2340.                }
  2341.                break;
  2342.             case 20:
  2343.                if ((var1.flags & 2) != 0) {
  2344.                   this.program[var18] = 31;
  2345.                }
  2346.  
  2347.                this.program[var18 + 1] = (byte)var2.num;
  2348.                break;
  2349.             case 21:
  2350.             case 27:
  2351.                if ((var1.flags & 2) != 0) {
  2352.                   this.program[var18] = (byte)(var17 == 21 ? 32 : 34);
  2353.                }
  2354.  
  2355.                int var6 = (Integer)var2.kid;
  2356.                int var21 = var2.kid2 - var6;
  2357.                this.program[var18 + 1] = (byte)var21;
  2358.                var18 += 2;
  2359.                var1.progLength += var21;
  2360.                if (var17 == 27) {
  2361.                   var1.progLength += var21;
  2362.                }
  2363.  
  2364.                int var20 = 0;
  2365.  
  2366.                for(int var9 = 0; var9 < var21; ++var20) {
  2367.                   char var33 = var19[var6 + var9];
  2368.                   if (var17 == 27) {
  2369.                      this.program[var18 + var20] = (byte)(var33 >> 8);
  2370.                      ++var20;
  2371.                      this.program[var18 + var20] = (byte)var33;
  2372.                   } else {
  2373.                      this.program[var18 + var20] = (byte)var33;
  2374.                   }
  2375.  
  2376.                   ++var9;
  2377.                }
  2378.                break;
  2379.             case 22:
  2380.                if ((var1.flags & 2) != 0) {
  2381.                   this.program[var18] = 33;
  2382.                }
  2383.  
  2384.                this.program[var18 + 1] = (byte)var2.chr;
  2385.                break;
  2386.             case 23:
  2387.                int var5 = var4.offset - var2.offset;
  2388.                this.write(var18, (short)var5);
  2389.                break;
  2390.             case 28:
  2391.                if ((var1.flags & 2) != 0) {
  2392.                   this.program[var18] = 35;
  2393.                }
  2394.  
  2395.                char var13 = var2.chr;
  2396.                this.program[var18 + 1] = (byte)(var13 >> 8);
  2397.                this.program[var18 + 2] = (byte)var13;
  2398.          }
  2399.  
  2400.          if ((var2.flags & 16) != 0) {
  2401.             var2 = var4;
  2402.             if (var4 != null) {
  2403.                continue;
  2404.             }
  2405.          }
  2406.  
  2407.          return;
  2408.       }
  2409.    }
  2410.  
  2411.    public byte getFlags() {
  2412.       return this.flags;
  2413.    }
  2414.  
  2415.    public String getClassName() {
  2416.       return "RegExp";
  2417.    }
  2418. }
  2419.