Reviewed by Mitz.

        - http://bugs.webkit.org/show_bug.cgi?id=17256
          Change RegExp to start its ref count at 1, not 0

        We'll want to do this to every RefCounted class, one at a time.

        * kjs/nodes.h:
        (KJS::RegExpNode::RegExpNode): Use RegExp::create instead of new RegExp.
        * kjs/regexp.cpp:
        (KJS::RegExp::RegExp): Marked inline, set initial ref count to 1.
        (KJS::RegExp::create): Added. Calls new RegExp then adopts the initial ref.
        * kjs/regexp.h: Reformatted. Made the constructors private. Added static
        create functions that return objects already wrapped in PassRefPtr.
        * kjs/regexp_object.cpp:
        (KJS::regExpProtoFuncCompile): Use RegExp::create instead of new RegExp.
        (KJS::RegExpObjectImp::construct): Ditto.
        * kjs/string_object.cpp:
        (KJS::stringProtoFuncMatch): Ditto.
        (KJS::stringProtoFuncSearch): Ditto.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@30109 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index a2be240..bae61eb 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,26 @@
+2008-02-09  Darin Adler  <darin@apple.com>
+
+        Reviewed by Mitz.
+
+        - http://bugs.webkit.org/show_bug.cgi?id=17256
+          Change RegExp to start its ref count at 1, not 0
+
+        We'll want to do this to every RefCounted class, one at a time.
+
+        * kjs/nodes.h:
+        (KJS::RegExpNode::RegExpNode): Use RegExp::create instead of new RegExp.
+        * kjs/regexp.cpp:
+        (KJS::RegExp::RegExp): Marked inline, set initial ref count to 1.
+        (KJS::RegExp::create): Added. Calls new RegExp then adopts the initial ref.
+        * kjs/regexp.h: Reformatted. Made the constructors private. Added static
+        create functions that return objects already wrapped in PassRefPtr.
+        * kjs/regexp_object.cpp:
+        (KJS::regExpProtoFuncCompile): Use RegExp::create instead of new RegExp.
+        (KJS::RegExpObjectImp::construct): Ditto.
+        * kjs/string_object.cpp:
+        (KJS::stringProtoFuncMatch): Ditto.
+        (KJS::stringProtoFuncSearch): Ditto.
+
 2008-02-08  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by Maciej.
diff --git a/JavaScriptCore/kjs/nodes.h b/JavaScriptCore/kjs/nodes.h
index 3bea104..f366557 100644
--- a/JavaScriptCore/kjs/nodes.h
+++ b/JavaScriptCore/kjs/nodes.h
@@ -334,7 +334,7 @@
     class RegExpNode : public ExpressionNode {
     public:
         RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
-            : m_regExp(new RegExp(pattern, flags))
+            : m_regExp(RegExp::create(pattern, flags))
         {
         }
 
diff --git a/JavaScriptCore/kjs/regexp.cpp b/JavaScriptCore/kjs/regexp.cpp
index 4839c86..87f67f0 100644
--- a/JavaScriptCore/kjs/regexp.cpp
+++ b/JavaScriptCore/kjs/regexp.cpp
@@ -1,8 +1,7 @@
 // -*- c-basic-offset: 2 -*-
 /*
- *  This file is part of the KDE libraries
  *  Copyright (C) 1999-2001, 2004 Harri Porten (porten@kde.org)
- *  Copyright (c) 2007, Apple Inc.
+ *  Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -24,15 +23,18 @@
 #include "regexp.h"
 
 #include "lexer.h"
+#include <pcre/pcre.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <wtf/Assertions.h>
+#include <wtf/OwnArrayPtr.h>
 
 namespace KJS {
 
-RegExp::RegExp(const UString& pattern)
-  : m_pattern(pattern)
+inline RegExp::RegExp(const UString& pattern)
+  : RefCounted<RegExp>(1)
+  , m_pattern(pattern)
   , m_flagBits(0)
   , m_constructionError(0)
   , m_numSubpatterns(0)
@@ -41,8 +43,14 @@
         JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, &m_numSubpatterns, &m_constructionError);
 }
 
-RegExp::RegExp(const UString& pattern, const UString& flags)
-  : m_pattern(pattern)
+PassRefPtr<RegExp> RegExp::create(const UString& pattern)
+{
+    return adoptRef(new RegExp(pattern));
+}
+
+inline RegExp::RegExp(const UString& pattern, const UString& flags)
+  : RefCounted<RegExp>(1)
+  , m_pattern(pattern)
   , m_flags(flags)
   , m_flagBits(0)
   , m_constructionError(0)
@@ -70,6 +78,11 @@
         ignoreCaseOption, multilineOption, &m_numSubpatterns, &m_constructionError);
 }
 
+PassRefPtr<RegExp> RegExp::create(const UString& pattern, const UString& flags)
+{
+    return adoptRef(new RegExp(pattern, flags));
+}
+
 RegExp::~RegExp()
 {
     jsRegExpFree(m_regExp);
diff --git a/JavaScriptCore/kjs/regexp.h b/JavaScriptCore/kjs/regexp.h
index 2c62085..1930ac9 100644
--- a/JavaScriptCore/kjs/regexp.h
+++ b/JavaScriptCore/kjs/regexp.h
@@ -1,7 +1,6 @@
-// -*- c-basic-offset: 2 -*-
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -23,53 +22,48 @@
 #define KJS_REGEXP_H
 
 #include "ustring.h"
-#include <pcre/pcre.h>
-#include <sys/types.h>
-#include <wtf/OwnArrayPtr.h>
+#include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 
+struct JSRegExp;
+
 namespace KJS {
 
-  class RegExp : public RefCounted<RegExp> {
-  private:
-    enum { 
-        Global = 1, 
-        IgnoreCase = 2, 
-        Multiline = 4 
+    class RegExp : public RefCounted<RegExp> {
+    public:
+        static PassRefPtr<RegExp> create(const UString& pattern);
+        static PassRefPtr<RegExp> create(const UString& pattern, const UString& flags);
+        ~RegExp();
+
+        bool global() const { return m_flagBits & Global; }
+        bool ignoreCase() const { return m_flagBits & IgnoreCase; }
+        bool multiline() const { return m_flagBits & Multiline; }
+
+        const UString& pattern() const { return m_pattern; }
+        const UString& flags() const { return m_flags; }
+
+        bool isValid() const { return !m_constructionError; }
+        const char* errorMessage() const { return m_constructionError; }
+
+        int match(const UString&, int offset, OwnArrayPtr<int>* ovector = 0);
+        unsigned numSubpatterns() const { return m_numSubpatterns; }
+
+    private:
+        RegExp(const UString& pattern);
+        RegExp(const UString& pattern, const UString& flags);
+
+        void compile();
+
+        enum FlagBits { Global = 1, IgnoreCase = 2, Multiline = 4 };
+
+        UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
+        UString m_flags; // FIXME: Just decompile m_regExp instead of storing this.
+        int m_flagBits;
+        JSRegExp* m_regExp;
+        const char* m_constructionError;
+        unsigned m_numSubpatterns;
     };
 
-  public:
-    RegExp(const UString& pattern);
-    RegExp(const UString& pattern, const UString& flags);
-    ~RegExp();
-    
-    bool global() const { return m_flagBits & Global; }
-    bool ignoreCase() const { return m_flagBits & IgnoreCase; }
-    bool multiline() const { return m_flagBits & Multiline; }
-
-    const UString& pattern() const { return m_pattern; }
-    const UString& flags() const { return m_flags; }
-
-    bool isValid() const { return !m_constructionError; }
-    const char* errorMessage() const { return m_constructionError; }
-
-    int match(const UString&, int offset, OwnArrayPtr<int>* ovector = 0);
-    unsigned numSubpatterns() const { return m_numSubpatterns; }
-
-  private:
-    void compile();
-    
-    // Data supplied by caller.
-    UString m_pattern; // FIXME: Just decompile m_regExp instead of storing this.
-    UString m_flags; // FIXME: Just decompile m_regExp instead of storing this.
-    int m_flagBits;
-
-    // Data supplied by PCRE.
-    JSRegExp* m_regExp;
-    const char* m_constructionError;
-    unsigned m_numSubpatterns;
-  };
-
 } // namespace
 
 #endif
diff --git a/JavaScriptCore/kjs/regexp_object.cpp b/JavaScriptCore/kjs/regexp_object.cpp
index 217c8db..20ec7ea 100644
--- a/JavaScriptCore/kjs/regexp_object.cpp
+++ b/JavaScriptCore/kjs/regexp_object.cpp
@@ -95,7 +95,7 @@
     } else {
         UString pattern = args.isEmpty() ? UString("") : arg0->toString(exec);
         UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
-        regExp = new RegExp(pattern, flags);
+        regExp = RegExp::create(pattern, flags);
     }
 
     if (!regExp->isValid())
@@ -449,7 +449,7 @@
   UString pattern = arg0->isUndefined() ? UString("") : arg0->toString(exec);
   UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
   
-  return createRegExpImp(exec, new RegExp(pattern, flags));
+  return createRegExpImp(exec, RegExp::create(pattern, flags));
 }
 
 JSObject* RegExpObjectImp::createRegExpImp(ExecState* exec, PassRefPtr<RegExp> regExp)
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 53b6ada..37535f0 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -533,8 +533,7 @@
     JSValue* a0 = args[0];
 
     UString u = s;
-    RegExp* reg;
-    RegExp* tmpReg = 0;
+    RefPtr<RegExp> reg;
     RegExpImp* imp = 0;
     if (a0->isObject() && static_cast<JSObject *>(a0)->inherits(&RegExpImp::info)) {
       reg = static_cast<RegExpImp *>(a0)->regExp();
@@ -544,12 +543,12 @@
        *  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));
+      reg = RegExp::create(a0->toString(exec));
     }
     RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalGlobalObject()->regExpConstructor());
     int pos;
     int matchLength;
-    regExpObj->performMatch(reg, u, 0, pos, matchLength);
+    regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
     JSValue* result;
     if (!(reg->global())) {
       // case without 'g' flag is handled like RegExp.prototype.exec
@@ -565,7 +564,7 @@
         list.append(jsString(u.substr(pos, matchLength)));
         lastIndex = pos;
         pos += matchLength == 0 ? 1 : matchLength;
-        regExpObj->performMatch(reg, u, pos, pos, matchLength);
+        regExpObj->performMatch(reg.get(), u, pos, pos, matchLength);
       }
       if (imp)
         imp->setLastIndex(lastIndex);
@@ -578,7 +577,6 @@
         result = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, list);
       }
     }
-    delete tmpReg;
     return result;
 }
 
@@ -590,23 +588,21 @@
     JSValue* a0 = args[0];
 
     UString u = s;
-    RegExp* reg;
-    RegExp* tmpReg = 0;
-    if (a0->isObject() && static_cast<JSObject *>(a0)->inherits(&RegExpImp::info)) {
-      reg = static_cast<RegExpImp *>(a0)->regExp();
+    RefPtr<RegExp> reg;
+    if (a0->isObject() && static_cast<JSObject*>(a0)->inherits(&RegExpImp::info)) {
+      reg = static_cast<RegExpImp*>(a0)->regExp();
     } else { 
       /*
        *  ECMA 15.5.4.12 String.prototype.search (regexp)
        *  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));
+      reg = RegExp::create(a0->toString(exec));
     }
     RegExpObjectImp* regExpObj = static_cast<RegExpObjectImp*>(exec->lexicalGlobalObject()->regExpConstructor());
     int pos;
     int matchLength;
-    regExpObj->performMatch(reg, u, 0, pos, matchLength);
-    delete tmpReg;
+    regExpObj->performMatch(reg.get(), u, 0, pos, matchLength);
     return jsNumber(pos);
 }