]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/RegExpConstructor.h
JavaScriptCore-1097.13.tar.gz
[apple/javascriptcore.git] / runtime / RegExpConstructor.h
index 1d02e6ff7cfc4155457931a11e925d164edb580b..0093f9484d9ffb2088526995b7490aed50f77501 100644 (file)
 
 #include "InternalFunction.h"
 #include "RegExp.h"
+#include "RegExpCachedResult.h"
+#include "RegExpObject.h"
 #include <wtf/OwnPtr.h>
 
+
 namespace JSC {
 
-    class RegExp;
     class RegExpPrototype;
-    struct RegExpConstructorPrivate;
 
-    struct RegExpConstructorPrivate {
-        WTF_MAKE_FAST_ALLOCATED;
+    class RegExpConstructor : public InternalFunction {
     public:
-        // Global search cache / settings
-        RegExpConstructorPrivate()
-            : lastNumSubPatterns(0)
-            , multiline(false)
-            , lastOvectorIndex(0)
+        typedef InternalFunction Base;
+
+        static RegExpConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, RegExpPrototype* regExpPrototype)
         {
+            RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(*exec->heap())) RegExpConstructor(globalObject, structure, regExpPrototype);
+            constructor->finishCreation(exec, regExpPrototype);
+            return constructor;
         }
 
-        const Vector<int, 32>& lastOvector() const { return ovector[lastOvectorIndex]; }
-        Vector<int, 32>& lastOvector() { return ovector[lastOvectorIndex]; }
-        Vector<int, 32>& tempOvector() { return ovector[lastOvectorIndex ? 0 : 1]; }
-        void changeLastOvector() { lastOvectorIndex = lastOvectorIndex ? 0 : 1; }
-
-        UString input;
-        UString lastInput;
-        Vector<int, 32> ovector[2];
-        unsigned lastNumSubPatterns : 30;
-        bool multiline : 1;
-        unsigned lastOvectorIndex : 1;
-    };
-
-    class RegExpConstructor : public InternalFunction {
-    public:
-        RegExpConstructor(ExecState*, JSGlobalObject*, Structure*, RegExpPrototype*);
-
-        static Structure* createStructure(JSGlobalData& globalData, JSValue prototype)
+        static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype)
         {
-            return Structure::create(globalData, prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount, &s_info);
+            return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info);
         }
 
-        virtual void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
-        virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
-        virtual bool getOwnPropertyDescriptor(ExecState*, const Identifier&, PropertyDescriptor&);
+        static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+
+        static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&);
+        static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
 
         static const ClassInfo s_info;
 
-        void performMatch(JSGlobalData&, RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0);
-        JSObject* arrayOfMatches(ExecState*) const;
+        MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset, int** ovector);
+        MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset);
+
+        void setMultiline(bool multiline) { m_multiline = multiline; }
+        bool multiline() const { return m_multiline; }
 
-        void setInput(const UString&);
-        const UString& input() const;
+        JSValue getBackref(ExecState*, unsigned);
+        JSValue getLastParen(ExecState*);
+        JSValue getLeftContext(ExecState*);
+        JSValue getRightContext(ExecState*);
 
-        void setMultiline(bool);
-        bool multiline() const;
+        void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
+        JSString* input() { return m_cachedResult.input(); }
 
-        JSValue getBackref(ExecState*, unsigned) const;
-        JSValue getLastParen(ExecState*) const;
-        JSValue getLeftContext(ExecState*) const;
-        JSValue getRightContext(ExecState*) const;
+        static void visitChildren(JSCell*, SlotVisitor&);
 
     protected:
-        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
+        void finishCreation(ExecState*, RegExpPrototype*);
+        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags;
 
     private:
-        virtual ConstructType getConstructData(ConstructData&);
-        virtual CallType getCallData(CallData&);
-
-        OwnPtr<RegExpConstructorPrivate> d;
+        RegExpConstructor(JSGlobalObject*, Structure*, RegExpPrototype*);
+        static void destroy(JSCell*);
+        static ConstructType getConstructData(JSCell*, ConstructData&);
+        static CallType getCallData(JSCell*, CallData&);
+
+        RegExpCachedResult m_cachedResult;
+        bool m_multiline;
+        Vector<int, 32> m_ovector;
     };
 
     RegExpConstructor* asRegExpConstructor(JSValue);
 
-    JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&);
+    JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
 
     inline RegExpConstructor* asRegExpConstructor(JSValue value)
     {
@@ -109,23 +101,31 @@ namespace JSC {
       expression matching through the performMatch function. We use cached results to calculate, 
       e.g., RegExp.lastMatch and RegExp.leftParen.
     */
-    ALWAYS_INLINE void RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
+    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset, int** ovector)
     {
-        position = r->match(globalData, s, startOffset, &d->tempOvector());
+        int position = regExp->match(globalData, input, startOffset, m_ovector);
 
         if (ovector)
-            *ovector = d->tempOvector().data();
+            *ovector = m_ovector.data();
 
-        if (position != -1) {
-            ASSERT(!d->tempOvector().isEmpty());
+        if (position == -1)
+            return MatchResult::failed();
 
-            length = d->tempOvector()[1] - d->tempOvector()[0];
+        ASSERT(!m_ovector.isEmpty());
+        ASSERT(m_ovector[0] == position);
+        ASSERT(m_ovector[1] >= position);
+        size_t end = m_ovector[1];
 
-            d->input = s;
-            d->lastInput = s;
-            d->changeLastOvector();
-            d->lastNumSubPatterns = r->numSubpatterns();
-        }
+        m_cachedResult.record(globalData, this, regExp, string, MatchResult(position, end));
+
+        return MatchResult(position, end);
+    }
+    ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset)
+    {
+        MatchResult result = regExp->match(globalData, input, startOffset);
+        if (result)
+            m_cachedResult.record(globalData, this, regExp, string, result);
+        return result;
     }
 
 } // namespace JSC