JavaScriptCore:

        Reviewed by Darin Adler.
        
        Fixed part of http://bugs.webkit.org/show_bug.cgi?id=15861 
        15% of string-validate-input.js is spent compiling the same regular expression.

        Put RegExpImp properties into a static hashtable to avoid a slew of
        PropertyMap churn when creating a RegExpImp.
        
        Factored important bits of regular expression implementation out of
        RegExpImp (the JS object) and into RegExp (the PCRE wrapper class), 
        making RegExp a ref-counted class. (This will help later.)

        Removed PCRE_POSIX support because I didn't quite know how to test it 
        and keep it working with these changes.
        
        1.1% SunSpider speedup. 5.8% speedup on string-validate-input.js.

        * kjs/regexp.h: A few interface changes:
        1. Renamed "subpatterns()" => "numSubpatterns()"
        2. Made flag enumeration private and replaced it with public getters for
        specific flags.
        3. Made RegExp ref-counted so RegExps can be shared by RegExpImps.
        4. Made RegExp take a string of flags instead of an int, eliminating 
        duplicated flag parsing code elsewhere.

        * kjs/regexp_object.cpp:
        (KJS::RegExpProtoFunc::callAsFunction): For RegExp.compile: 
        - Fixed a bug where compile(undefined) would throw an exception. 
        - Removed some now-redundant code.
        - Used RegExp sharing to eliminate an allocation and a bunch of 
        PropertyMap thrash. (Not a big win since compile is a deprecated 
        function. I mainly did this to test the plubming.)

LayoutTests:

        Reviewed by Darin Adler.
        
        Beefed up the RegExp.compile testcase to cover a mistake in the 
        original check-in and a mistake I made while developing my new patch.

        * fast/js/resources/regexp-compile.js:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@27571 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 39dd761..e59694e 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -276,13 +276,13 @@
     } else if (ref >= '0' && ref <= '9') {
         // 1- and 2-digit back references are allowed
         unsigned backrefIndex = ref - '0';
-        if (backrefIndex > (unsigned)reg->subPatterns())
+        if (backrefIndex > reg->numSubpatterns())
             continue;
         if (substitutedReplacement.size() > i + 2) {
             ref = substitutedReplacement[i+2].unicode();
             if (ref >= '0' && ref <= '9') {
                 backrefIndex = 10 * backrefIndex + ref - '0';
-                if (backrefIndex > (unsigned)reg->subPatterns())
+                if (backrefIndex > reg->numSubpatterns())
                     backrefIndex = backrefIndex / 10;   // Fall back to the 1-digit reference
                 else
                     advance = 1;
@@ -334,7 +334,7 @@
 
   if (pattern->isObject() && static_cast<JSObject *>(pattern)->inherits(&RegExpImp::info)) {
     RegExp *reg = static_cast<RegExpImp *>(pattern)->regExp();
-    bool global = reg->flags() & RegExp::Global;
+    bool global = reg->global();
 
     RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
 
@@ -364,7 +364,7 @@
           int completeMatchStart = ovector[0];
           List args;
 
-          for (unsigned i = 0; i < reg->subPatterns() + 1; i++) {
+          for (unsigned i = 0; i < reg->numSubpatterns() + 1; i++) {
               int matchStart = ovector[i * 2];
               int matchLen = ovector[i * 2 + 1] - matchStart;
 
@@ -519,7 +519,7 @@
        *  If regexp is not an object whose [[Class]] property is "RegExp", it is
        *  replaced with the result of the expression new RegExp(regexp).
        */
-      reg = tmpReg = new RegExp(a0->toString(exec), RegExp::None);
+      reg = tmpReg = new RegExp(a0->toString(exec));
     }
     RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalInterpreter()->builtinRegExp());
     int pos;
@@ -529,7 +529,7 @@
       result = jsNumber(pos);
     } else {
       // Match
-      if ((reg->flags() & RegExp::Global) == 0) {
+      if (!(reg->global())) {
         // case without 'g' flag is handled like RegExp.prototype.exec
         if (pos < 0)
           result = jsNull();
@@ -546,7 +546,7 @@
           regExpObj->performMatch(reg, u, pos, pos, matchLength);
         }
         if (imp)
-          imp->put(exec, "lastIndex", jsNumber(lastIndex), DontDelete|DontEnum);
+          imp->put(exec, exec->propertyNames().lastIndex, jsNumber(lastIndex), DontDelete|DontEnum);
         if (list.isEmpty()) {
           // if there are no matches at all, it's important to return
           // Null instead of an empty array, because this matches
@@ -613,7 +613,7 @@
           p0 = mpos + mlen;
           i++;
         }
-        for (unsigned si = 1; si <= reg->subPatterns(); ++si) {
+        for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) {
           int spos = ovector[si * 2];
           if (spos < 0)
             res->put(exec, i++, jsUndefined());