]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/RegExpConstructor.h
JavaScriptCore-576.tar.gz
[apple/javascriptcore.git] / runtime / RegExpConstructor.h
index 6823f3fb709801be9300064eb40a8ec7adf3821b..8f4be71687a0f3177738060bcdbb9bcea02fca65 100644 (file)
@@ -22,6 +22,7 @@
 #define RegExpConstructor_h
 
 #include "InternalFunction.h"
+#include "RegExp.h"
 #include <wtf/OwnPtr.h>
 
 namespace JSC {
@@ -30,17 +31,40 @@ namespace JSC {
     class RegExpPrototype;
     struct RegExpConstructorPrivate;
 
+    struct RegExpConstructorPrivate : FastAllocBase {
+        // Global search cache / settings
+        RegExpConstructorPrivate()
+            : lastNumSubPatterns(0)
+            , multiline(false)
+            , lastOvectorIndex(0)
+        {
+        }
+
+        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*, PassRefPtr<Structure>, RegExpPrototype*);
+        RegExpConstructor(ExecState*, NonNullPassRefPtr<Structure>, RegExpPrototype*);
 
         static PassRefPtr<Structure> createStructure(JSValue prototype)
         {
-            return Structure::create(prototype, TypeInfo(ObjectType, ImplementsHasInstance));
+            return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
         }
 
         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 const ClassInfo info;
 
@@ -58,6 +82,9 @@ namespace JSC {
         JSValue getLeftContext(ExecState*) const;
         JSValue getRightContext(ExecState*) const;
 
+    protected:
+        static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | InternalFunction::StructureFlags;
+
     private:
         virtual ConstructType getConstructData(ConstructData&);
         virtual CallType getCallData(CallData&);
@@ -77,6 +104,30 @@ namespace JSC {
         return static_cast<RegExpConstructor*>(asObject(value));
     }
 
+    /* 
+      To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
+      expression matching through the performMatch function. We use cached results to calculate, 
+      e.g., RegExp.lastMatch and RegExp.leftParen.
+    */
+    inline void RegExpConstructor::performMatch(RegExp* r, const UString& s, int startOffset, int& position, int& length, int** ovector)
+    {
+        position = r->match(s, startOffset, &d->tempOvector());
+
+        if (ovector)
+            *ovector = d->tempOvector().data();
+
+        if (position != -1) {
+            ASSERT(!d->tempOvector().isEmpty());
+
+            length = d->tempOvector()[1] - d->tempOvector()[0];
+
+            d->input = s;
+            d->lastInput = s;
+            d->changeLastOvector();
+            d->lastNumSubPatterns = r->numSubpatterns();
+        }
+    }
+
 } // namespace JSC
 
 #endif // RegExpConstructor_h