Bug 56041 - RexExp constructor should only accept flags "gim"
We also should be passing the flags around as a bitfield rather than a string,
and should not have redundant, incompatible code for converting the string to a bitfield!

Reviewed by Darin Adler.

Source/JavaScriptCore: 

* JavaScriptCore.exp:
* bytecompiler/NodesCodegen.cpp:
(JSC::RegExpNode::emitBytecode):
    - Need to parse flags string to enum.
* runtime/RegExp.cpp:
(JSC::regExpFlags):
(JSC::RegExp::RegExp):
(JSC::RegExp::create):
    - Add method to parse flags string to enum, change constructor/create args to take enum.
* runtime/RegExp.h:
(JSC::RegExp::global):
(JSC::RegExp::ignoreCase):
(JSC::RegExp::multiline):
    - Change to use new enum values.
* runtime/RegExpCache.cpp:
(JSC::RegExpCache::lookupOrCreate):
(JSC::RegExpCache::create):
* runtime/RegExpCache.h:
    - Changed to use regExpFlags enum instead of int/const UString&.
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
    - Add use new enum parsing, check for error.
* runtime/RegExpKey.h:
(JSC::RegExpKey::RegExpKey):
* runtime/RegExpPrototype.cpp:
(JSC::RegExpPrototype::RegExpPrototype):
    - Pass NoFlags value instead of empty string.
(JSC::regExpProtoFuncCompile):
    - Add use new enum parsing, check for error.
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncMatch):
(JSC::stringProtoFuncSearch):
    - Pass NoFlags value instead of empty string.

Source/WebCore: 

* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::readTerminal):
    - Need to parse flags string back to enum.

LayoutTests: 

* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T1-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T2-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T3-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T4-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T5-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T6-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T7-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T8-expected.txt:
* sputnik/Conformance/15_Native_Objects/15.10_RegExp/15.10.4/S15.10.4.1_A5_T9-expected.txt:
    - Check in passing results!



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@80667 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index f46a1c5..3b92e14 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,45 @@
+2011-03-09  Gavin Barraclough  <barraclough@apple.com>
+
+        Reviewed by Darin Adler.
+
+        Bug 56041 - RexExp constructor should only accept flags "gim"
+        We also should be passing the flags around as a bitfield rather than a string,
+        and should not have redundant, incompatible code for converting the string to a bitfield!
+
+        * JavaScriptCore.exp:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::RegExpNode::emitBytecode):
+            - Need to parse flags string to enum.
+        * runtime/RegExp.cpp:
+        (JSC::regExpFlags):
+        (JSC::RegExp::RegExp):
+        (JSC::RegExp::create):
+            - Add method to parse flags string to enum, change constructor/create args to take enum.
+        * runtime/RegExp.h:
+        (JSC::RegExp::global):
+        (JSC::RegExp::ignoreCase):
+        (JSC::RegExp::multiline):
+            - Change to use new enum values.
+        * runtime/RegExpCache.cpp:
+        (JSC::RegExpCache::lookupOrCreate):
+        (JSC::RegExpCache::create):
+        * runtime/RegExpCache.h:
+            - Changed to use regExpFlags enum instead of int/const UString&.
+        * runtime/RegExpConstructor.cpp:
+        (JSC::constructRegExp):
+            - Add use new enum parsing, check for error.
+        * runtime/RegExpKey.h:
+        (JSC::RegExpKey::RegExpKey):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::RegExpPrototype::RegExpPrototype):
+            - Pass NoFlags value instead of empty string.
+        (JSC::regExpProtoFuncCompile):
+            - Add use new enum parsing, check for error.
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncMatch):
+        (JSC::stringProtoFuncSearch):
+            - Pass NoFlags value instead of empty string.
+
 2011-03-08  Gavin Barraclough  <barraclough@apple.com>
 
         Reviewed by Sam Weinig
diff --git a/Source/JavaScriptCore/JavaScriptCore.exp b/Source/JavaScriptCore/JavaScriptCore.exp
index 914c2ac..060f6612 100644
--- a/Source/JavaScriptCore/JavaScriptCore.exp
+++ b/Source/JavaScriptCore/JavaScriptCore.exp
@@ -1,4 +1,3 @@
-__ZN3JSC22objectConstructorTableE
 _JSCheckScriptSyntax
 _JSClassCreate
 _JSClassRelease
@@ -120,6 +119,7 @@
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC11regExpFlagsERKNS_7UStringE
 __ZN3JSC12DateInstance6s_infoE
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
@@ -201,6 +201,7 @@
 __ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
 __ZN3JSC20createReferenceErrorEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC22globalMemoryStatisticsEv
+__ZN3JSC22objectConstructorTableE
 __ZN3JSC23AbstractSamplingCounter4dumpEv
 __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateE
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
@@ -248,7 +249,7 @@
 __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringENS_11RegExpFlagsE
 __ZN3JSC6RegExpD1Ev
 __ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
 __ZN3JSC7JSArray15setSubclassDataEPv
@@ -446,10 +447,10 @@
 __ZN3WTF3MD58addBytesEPKhm
 __ZN3WTF3MD58checksumERNS_6VectorIhLm16EEE
 __ZN3WTF3MD5C1Ev
-__ZN3WTF4dtoaEPcdRbRiRj
 __ZN3WTF4SHA111computeHashERNS_6VectorIhLm20EEE
 __ZN3WTF4SHA18addBytesEPKhm
 __ZN3WTF4SHA1C1Ev
+__ZN3WTF4dtoaEPcdRbRiRj
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
 __ZN3WTF5Mutex7tryLockEv
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2875434..4b6bb3e 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -125,7 +125,9 @@
 {
     if (dst == generator.ignoredResult())
         return 0;
-    RefPtr<RegExp> regExp = generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), m_flags.ustring());
+    RegExpFlags flags = regExpFlags(m_flags.ustring());
+    ASSERT(flags != InvalidFlags);
+    RefPtr<RegExp> regExp = generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), flags);
     ASSERT(regExp->isValid());
     return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
 }
diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp
index 95ce5e9..25cb2d5 100644
--- a/Source/JavaScriptCore/runtime/RegExp.cpp
+++ b/Source/JavaScriptCore/runtime/RegExp.cpp
@@ -34,6 +34,38 @@
 
 namespace JSC {
 
+RegExpFlags regExpFlags(const UString& string)
+{
+    RegExpFlags flags = NoFlags;
+
+    for (unsigned i = 0; i < string.length(); ++i) {
+        switch (string.characters()[i]) {
+        case 'g':
+            if (flags & FlagGlobal)
+                return InvalidFlags;
+            flags = static_cast<RegExpFlags>(flags | FlagGlobal);
+            break;
+
+        case 'i':
+            if (flags & FlagIgnoreCase)
+                return InvalidFlags;
+            flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
+            break;
+
+        case 'm':
+            if (flags & FlagMultiline)
+                return InvalidFlags;
+            flags = static_cast<RegExpFlags>(flags | FlagMultiline);
+            break;
+
+        default:
+            return InvalidFlags;
+        }
+    }
+
+    return flags;
+}
+  
 struct RegExpRepresentation {
 #if ENABLE(YARR_JIT)
     Yarr::YarrCodeBlock m_regExpJITCode;
@@ -41,9 +73,9 @@
     OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
 };
 
-inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+inline RegExp::RegExp(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
     : m_patternString(patternString)
-    , m_flagBits(0)
+    , m_flags(flags)
     , m_constructionError(0)
     , m_numSubpatterns(0)
 #if ENABLE(REGEXP_TRACING)
@@ -52,17 +84,6 @@
 #endif
     , m_representation(adoptPtr(new RegExpRepresentation))
 {
-    // NOTE: The global flag is handled on a case-by-case basis by functions like
-    // String::match and RegExpObject::match.
-    if (!flags.isNull()) {
-        if (flags.find('g') != notFound)
-            m_flagBits |= Global;
-        if (flags.find('i') != notFound)
-            m_flagBits |= IgnoreCase;
-        if (flags.find('m') != notFound)
-            m_flagBits |= Multiline;
-    }
-
     m_state = compile(globalData);
 }
 
@@ -70,7 +91,7 @@
 {
 }
 
-PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExp::create(JSGlobalData* globalData, const UString& patternString, RegExpFlags flags)
 {
     RefPtr<RegExp> res = adoptRef(new RegExp(globalData, patternString, flags));
 #if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h
index d99befb..f7fc4bf 100644
--- a/Source/JavaScriptCore/runtime/RegExp.h
+++ b/Source/JavaScriptCore/runtime/RegExp.h
@@ -24,6 +24,7 @@
 
 #include "UString.h"
 #include "ExecutableAllocator.h"
+#include "RegExpKey.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 
@@ -32,14 +33,16 @@
     struct RegExpRepresentation;
     class JSGlobalData;
 
+    RegExpFlags regExpFlags(const UString&);
+
     class RegExp : public RefCounted<RegExp> {
     public:
-        static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+        static PassRefPtr<RegExp> create(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
         ~RegExp();
 
-        bool global() const { return m_flagBits & Global; }
-        bool ignoreCase() const { return m_flagBits & IgnoreCase; }
-        bool multiline() const { return m_flagBits & Multiline; }
+        bool global() const { return m_flags & FlagGlobal; }
+        bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
+        bool multiline() const { return m_flags & FlagMultiline; }
 
         const UString& pattern() const { return m_patternString; }
 
@@ -54,7 +57,7 @@
 #endif
 
     private:
-        RegExp(JSGlobalData* globalData, const UString& pattern, const UString& flags);
+        RegExp(JSGlobalData* globalData, const UString& pattern, RegExpFlags);
 
         enum RegExpState {
             ParseError,
@@ -68,9 +71,8 @@
         void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult);
 #endif
 
-        enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
         UString m_patternString;
-        int m_flagBits;
+        RegExpFlags m_flags;
         const char* m_constructionError;
         unsigned m_numSubpatterns;
 #if ENABLE(REGEXP_TRACING)
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp
index d101758..c96b047 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp
@@ -31,7 +31,7 @@
 
 namespace JSC {
 
-PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags)
+PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, RegExpFlags flags)
 {
     if (patternString.length() < maxCacheablePatternLength) {
         pair<RegExpCacheMap::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0);
@@ -43,7 +43,7 @@
     return create(patternString, flags, m_cacheMap.end());
 }
 
-PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator) 
+PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, RegExpFlags flags, RegExpCacheMap::iterator iterator) 
 {
     RefPtr<RegExp> regExp = RegExp::create(m_globalData, patternString, flags);
 
diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h
index b5b637f..b4a6ae5 100644
--- a/Source/JavaScriptCore/runtime/RegExpCache.h
+++ b/Source/JavaScriptCore/runtime/RegExpCache.h
@@ -41,8 +41,8 @@
 typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap;
 
 public:
-    PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags);
-    PassRefPtr<RegExp> create(const UString& patternString, const UString& flags, RegExpCacheMap::iterator iterator);
+    PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, RegExpFlags);
+    PassRefPtr<RegExp> create(const UString& patternString, RegExpFlags, RegExpCacheMap::iterator);
     RegExpCache(JSGlobalData* globalData);
 
 private:
diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
index c06fdc4..348f38a 100644
--- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -291,7 +291,7 @@
 {
     asRegExpConstructor(baseObject)->setMultiline(value.toBoolean(exec));
 }
-  
+
 // ECMA 15.10.4
 JSObject* constructRegExp(ExecState* exec, const ArgList& args)
 {
@@ -305,7 +305,17 @@
     }
 
     UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
-    UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+    if (exec->hadException())
+        return 0;
+
+    RegExpFlags flags = NoFlags;
+    if (!arg1.isUndefined()) {
+        flags = regExpFlags(arg1.toString(exec));
+        if (exec->hadException())
+            return 0;
+        if (flags == InvalidFlags)
+            return throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+    }
 
     RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
     if (!regExp->isValid())
diff --git a/Source/JavaScriptCore/runtime/RegExpKey.h b/Source/JavaScriptCore/runtime/RegExpKey.h
index cd1368d..756fabc 100644
--- a/Source/JavaScriptCore/runtime/RegExpKey.h
+++ b/Source/JavaScriptCore/runtime/RegExpKey.h
@@ -25,63 +25,53 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "UString.h"
-#include <wtf/text/StringHash.h>
-
 #ifndef RegExpKey_h
 #define RegExpKey_h
 
+#include "UString.h"
+#include <wtf/text/StringHash.h>
+
 namespace JSC {
 
+enum RegExpFlags {
+    NoFlags = 0,
+    FlagGlobal = 1,
+    FlagIgnoreCase = 2,
+    FlagMultiline = 4,
+    InvalidFlags = 8
+};
+
 struct RegExpKey {
-    int flagsValue;
+    RegExpFlags flagsValue;
     RefPtr<StringImpl> pattern;
 
     RegExpKey()
-        : flagsValue(0)
+        : flagsValue(NoFlags)
     {
     }
 
-    RegExpKey(int flags)
+    RegExpKey(RegExpFlags flags)
         : flagsValue(flags)
     {
     }
 
-    RegExpKey(int flags, const UString& pattern)
+    RegExpKey(RegExpFlags flags, const UString& pattern)
         : flagsValue(flags)
         , pattern(pattern.impl())
     {
     }
 
-    RegExpKey(int flags, const PassRefPtr<StringImpl> pattern)
+    RegExpKey(RegExpFlags flags, const PassRefPtr<StringImpl> pattern)
         : flagsValue(flags)
         , pattern(pattern)
     {
     }
 
-    RegExpKey(int flags, const RefPtr<StringImpl>& pattern)
+    RegExpKey(RegExpFlags flags, const RefPtr<StringImpl>& pattern)
         : flagsValue(flags)
         , pattern(pattern)
     {
     }
-
-    RegExpKey(const UString& flags, const UString& pattern)
-        : pattern(pattern.impl())
-    {
-        flagsValue = getFlagsValue(flags);
-    }
-
-    int getFlagsValue(const UString flags) 
-    {
-        flagsValue = 0;
-        if (flags.find('g') != notFound)
-            flagsValue += 4;
-        if (flags.find('i') != notFound)
-            flagsValue += 2;
-        if (flags.find('m') != notFound)
-            flagsValue += 1;
-        return flagsValue;
-    }
 };
 
 inline bool operator==(const RegExpKey& a, const RegExpKey& b) 
@@ -112,8 +102,8 @@
 };
 
 template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> {
-    static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = -1; }
-    static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == -1; }
+    static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::InvalidFlags; }
+    static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::InvalidFlags; }
 };
 } // namespace WTF
 
diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
index 106006c..35c3389 100644
--- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -48,7 +48,7 @@
 // ECMA 15.10.5
 
 RegExpPrototype::RegExpPrototype(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, Structure* functionStructure)
-    : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", ""))
+    : RegExpObject(globalObject, structure, RegExp::create(&exec->globalData(), "", NoFlags))
 {
     putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) JSFunction(exec, globalObject, functionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum);
@@ -90,7 +90,17 @@
         regExp = asRegExpObject(arg0)->regExp();
     } else {
         UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec);
-        UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
+        if (exec->hadException())
+            return JSValue::encode(jsUndefined());
+
+        RegExpFlags flags = NoFlags;
+        if (!arg1.isUndefined()) {
+            flags = regExpFlags(arg1.toString(exec));
+            if (exec->hadException())
+                return JSValue::encode(jsUndefined());
+            if (flags == InvalidFlags)
+                return throwVMError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
+        }
         regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
     }
 
diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp
index aa37122..41707b8 100644
--- a/Source/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp
@@ -615,7 +615,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 = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+        reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;
@@ -668,7 +668,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 = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString());
+        reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), NoFlags);
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;