JavaScriptCore:
authorggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jul 2006 22:39:58 +0000 (22:39 +0000)
committerggaren <ggaren@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 14 Jul 2006 22:39:58 +0000 (22:39 +0000)
        Reviewed by Maciej.

        - Implemented ref-counting of JSContexts by splitting into two datatypes:
        JSGlobalContext, which you can create/retain/release, and JSContext, which
        you can't.

        Internally, you retain a JSGlobalContext/ExecState by retaining its
        interpreter, which, in the case of a global ExecState, owns it.

        - Also made ~Interpreter() protected to catch places where Interpreter
        is manually deleted. (Can't make it private because some crazy fool
        decided it would be a good idea to subclass Interpreter in other frameworks.
        I pity da fool.)

        * API/APICast.h:
        (toJS): Added cast for new JSGlobalContext
        * API/JSStringRef.h: Changed vague "you must" language to more specific
        (but, ultimately, equally vague) "behavior is undefined if you don't"
        language.
        (KJS::Interpreter::Interpreter): Factored more common initialization into
        init()
        * kjs/interpreter.h:
        (KJS::Interpreter::ref): new
        (KJS::Interpreter::deref): new
        (KJS::Interpreter::refCount): new
        * kjs/testkjs.cpp:
        (doIt): Ref-count the interpreter.

JavaScriptGlue:

        Reviewed by Maciej.

        - Updated JSInterpreter to work with Interpreter ref-counting in JavaScriptCore.

        (JSInterpreter::JSInterpreter::~JSInterpreter): Now protected to catch
        manual delete.

WebCore:

        Reviewed by Maciej.

        - Updated ScriptInterpreter to work with Interpreter ref-counting in
        JavaScriptCore.

        (KJS::ScriptInterpreter::~ScriptInterpreter): Now protected to catch
        manual delete.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@15437 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
JavaScriptCore/API/APICast.h
JavaScriptCore/API/JSBase.h
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/API/JSContextRef.h
JavaScriptCore/API/JSStringRef.h
JavaScriptCore/API/minidom.c
JavaScriptCore/API/testapi.c
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/interpreter.h
JavaScriptCore/kjs/testkjs.cpp
JavaScriptGlue/ChangeLog
JavaScriptGlue/JSRun.cpp
JavaScriptGlue/JSRun.h
JavaScriptGlue/JSUtils.h
JavaScriptGlue/JSValueWrapper.cpp
WebCore/ChangeLog
WebCore/bindings/js/kjs_binding.cpp
WebCore/bindings/js/kjs_binding.h
WebCore/bindings/js/kjs_proxy.cpp
WebCore/bindings/js/kjs_proxy.h

index a50937194d83322e4051be64171dfde7cb1023e2..0f961a0e6f31c94f55d4c86c85143aa1f4b719f1 100644 (file)
@@ -40,6 +40,11 @@ namespace KJS {
 /* Opaque typing convenience methods */
 
 inline KJS::ExecState* toJS(JSContextRef c)
+{
+    return reinterpret_cast<KJS::ExecState*>(const_cast<__JSContext*>(c));
+}
+
+inline KJS::ExecState* toJS(JSGlobalContextRef c)
 {
     return reinterpret_cast<KJS::ExecState*>(c);
 }
index 7b9ad57c527241cd29413644708afdc0dee0e59a..b9fc487292bc892735ce4b3bc4e4c70b22586814 100644 (file)
 /* JavaScript engine interface */
 
 /*! @typedef JSContextRef A JavaScript execution context. Holds the global object and other execution state. */
-typedef struct __JSContext* JSContextRef;
+typedef const struct __JSContext* JSContextRef;
+
+/*! @typedef JSGlobalContextRef A global JavaScript execution context. A JSGlobalContext is a JSContext. */
+typedef struct __JSContext* JSGlobalContextRef;
+
 /*! @typedef JSString A UTF16 character buffer. The fundamental string representation in JavaScript. */
 typedef struct __JSString* JSStringRef;
+
 /*! @typedef JSClassRef A JavaScript class. Used with JSObjectMake to construct objects with custom behavior. */
 typedef struct __JSClass* JSClassRef;
+
 /*! @typedef JSPropertyListRef A JavaScript property list. Used for listing the properties in an object so they can be enumerated. */
 typedef struct __JSPropertyList* JSPropertyListRef;
+
 /*! @typedef JSPropertyEnumeratorRef A JavaScript property enumerator. Used for enumerating the properties in an object. */
 typedef struct __JSPropertyEnumerator* JSPropertyEnumeratorRef;
 
@@ -47,6 +54,7 @@ typedef struct __JSPropertyEnumerator* JSPropertyEnumeratorRef;
 
 /*! @typedef JSValueRef A JavaScript value. The base type for all JavaScript values, and polymorphic functions on them. */
 typedef const struct __JSValue* JSValueRef;
+
 /*! @typedef JSObjectRef A JavaScript object. A JSObject is a JSValue. */
 typedef struct __JSValue* JSObjectRef;
 
index 61431f662caea51b40b89c9a57783d48d131a9cf..72583396dbca38291f2cdfba22902882ffca8a12 100644 (file)
@@ -34,7 +34,7 @@
 
 using namespace KJS;
 
-JSContextRef JSContextCreate(JSClassRef globalObjectClass)
+JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass)
 {
     JSLock lock;
 
@@ -46,14 +46,23 @@ JSContextRef JSContextCreate(JSClassRef globalObjectClass)
         globalObject = new JSObject();
 
     Interpreter* interpreter = new Interpreter(globalObject); // adds the built-in object prototype to the global object
-    return toRef(interpreter->globalExec());
+    JSGlobalContextRef context = reinterpret_cast<JSGlobalContextRef>(interpreter->globalExec());
+    return JSGlobalContextRetain(context);
 }
 
-void JSContextDestroy(JSContextRef context)
+JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef context)
 {
     JSLock lock;
     ExecState* exec = toJS(context);
-    delete exec->dynamicInterpreter();
+    exec->dynamicInterpreter()->ref();
+    return context;
+}
+
+void JSGlobalContextRelease(JSGlobalContextRef context)
+{
+    JSLock lock;
+    ExecState* exec = toJS(context);
+    exec->dynamicInterpreter()->deref();
 }
 
 JSObjectRef JSContextGetGlobalObject(JSContextRef context)
index eda584d92c634ffba880a575885f86f23d927d72..2b177ec430ad0695340ac34c24ded7e5c187343f 100644 (file)
@@ -38,27 +38,35 @@ extern "C" {
 
 /*!
 @function
-@abstract Creates a JavaScript execution context.
-@discussion JSContextCreate allocates a global object and populates it with all the
+@abstract Creates a global JavaScript execution context.
+@discussion JSGlobalContextCreate allocates a global object and populates it with all the
  built-in JavaScript objects, such as Object, Function, String, and Array.
-@param globalObjectClass The class to use when creating the JSContext's global object.
Pass NULL to use the default object class.
-@result A JSContext with a global object of class globalObjectClass.
+@param globalObjectClass The class to use when creating the global object. Pass 
+ NULL to use the default object class.
+@result A JSGlobalContext with a global object of class globalObjectClass.
 */
-JSContextRef JSContextCreate(JSClassRef globalObjectClass);
+JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass);
 
 /*!
 @function
-@abstract       Destroys a JavaScript execution context, freeing its resources.
-@param context  The JSContext to destroy.
+@abstract Retains a global JavaScript execution context.
+@param context The JSGlobalContext to retain.
+@result A JSGlobalContext that is the same as context.
 */
-void JSContextDestroy(JSContextRef context);
+JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef context);
 
 /*!
 @function
-@abstract       Gets the global object of a JavaScript execution context.
-@param context  The JSContext whose global object you want to get.
-@result         context's global object.
+@abstract Releases a global JavaScript execution context.
+@param context The JSGlobalContext to release.
+*/
+void JSGlobalContextRelease(JSGlobalContextRef context);
+
+/*!
+@function
+@abstract Gets the global object of a JavaScript execution context.
+@param context The JSContext whose global object you want to get.
+@result context's global object.
 */
 JSObjectRef JSContextGetGlobalObject(JSContextRef context);
 
index 21149310f470a4e7d3ec34cd3de5236b1246919c..3fb2ec4034c57d60e9248d5ef625655b875b2833 100644 (file)
@@ -110,9 +110,10 @@ size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string);
  and copies the result into an external byte buffer.
 @param string The source JSString.
 @param buffer The destination byte buffer into which to copy a null-terminated 
- UTF8 string representation of string. The buffer must be at least bufferSize 
- bytes in size. On return, buffer contains a UTF8 string representation of string. 
- If bufferSize is too small, buffer will contain only partial results.
+ UTF8 representation of string. On return, buffer contains a UTF8 string 
+ representation of string. If bufferSize is too small, buffer will contain only 
+ partial results. If buffer is not at least bufferSize bytes in size, 
+ behavior is undefined. 
 @param bufferSize The size of the external buffer in bytes.
 @result The number of bytes written into buffer (including the null-terminator byte).
 */
index 745801cc07073fbe7ebfcaa5cac34ba4017035d1..f622b8629314c0f7c04a8daabe092f13d7789fef 100644 (file)
@@ -36,7 +36,7 @@ int main(int argc, char* argv[])
     UNUSED_PARAM(argc);
     UNUSED_PARAM(argv);
     
-    JSContextRef context = JSContextCreate(NULL);
+    JSGlobalContextRef context = JSGlobalContextCreate(NULL);
     JSObjectRef globalObject = JSContextGetGlobalObject(context);
     
     JSStringRef printIString = JSStringCreateWithUTF8CString("print");
@@ -73,7 +73,7 @@ int main(int argc, char* argv[])
     JSGarbageCollect();
 #endif
     
-    JSContextDestroy(context);
+    JSGlobalContextRelease(context);
     printf("PASS: Program exited normally.\n");
     return 0;
 }
index 5e1754c739c07b4bdeb6583445822ad602aeee4b..d022224081fd70561170acacd4b3a580062b679a 100644 (file)
@@ -34,7 +34,7 @@
 #include <assert.h>
 #include <math.h>
 
-static JSContextRef context = 0;
+static JSGlobalContextRef context = 0;
 
 static void assertEqualsAsBoolean(JSValueRef value, bool expectedValue)
 {
@@ -301,7 +301,7 @@ int main(int argc, char* argv[])
     UNUSED_PARAM(argc);
     UNUSED_PARAM(argv);
     
-    context = JSContextCreate(NULL);
+    context = JSGlobalContextCreate(NULL);
     
     JSObjectRef globalObject = JSContextGetGlobalObject(context);
     assert(JSValueIsObject(globalObject));
@@ -604,7 +604,7 @@ int main(int argc, char* argv[])
     JSStringRelease(goodSyntax);
     JSStringRelease(badSyntax);
     
-    JSContextDestroy(context);
+    JSGlobalContextRelease(context);
     printf("PASS: Program exited normally.\n");
     return 0;
 }
index b88d252cd070a6f2d81362b30e78fafcf7ef98b8..e9fd589243e9d9a9fd1e1f0e2afea88428075d4e 100644 (file)
@@ -1,3 +1,33 @@
+2006-07-14  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Maciej.
+        
+        - Implemented ref-counting of JSContexts by splitting into two datatypes:
+        JSGlobalContext, which you can create/retain/release, and JSContext, which
+        you can't.
+        
+        Internally, you retain a JSGlobalContext/ExecState by retaining its
+        interpreter, which, in the case of a global ExecState, owns it.
+        
+        - Also made ~Interpreter() protected to catch places where Interpreter
+        is manually deleted. (Can't make it private because some crazy fool
+        decided it would be a good idea to subclass Interpreter in other frameworks.
+        I pity da fool.)
+
+        * API/APICast.h: 
+        (toJS): Added cast for new JSGlobalContext
+        * API/JSStringRef.h: Changed vague "you must" language to more specific
+        (but, ultimately, equally vague) "behavior is undefined if you don't" 
+        language.
+        (KJS::Interpreter::Interpreter): Factored more common initialization into
+        init()
+        * kjs/interpreter.h:
+        (KJS::Interpreter::ref): new
+        (KJS::Interpreter::deref): new
+        (KJS::Interpreter::refCount): new
+        * kjs/testkjs.cpp: 
+        (doIt): Ref-count the interpreter.
+
 2006-07-14  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Geoff.
index ebeed090b1536d5793f99a7e026d5fea0417a0b8..877145f4e95a4c376ccfb052d79c257ee815c318 100644 (file)
@@ -5,11 +5,12 @@ _JSCheckScriptSyntax
 _JSClassCreate
 _JSClassRelease
 _JSClassRetain
-_JSContextCreate
-_JSContextDestroy
 _JSContextGetGlobalObject
 _JSEvaluateScript
 _JSGarbageCollect
+_JSGlobalContextCreate
+_JSGlobalContextRelease
+_JSGlobalContextRetain
 _JSObjectCallAsConstructor
 _JSObjectCallAsFunction
 _JSObjectCreatePropertyEnumerator
index 3429a613c801af35448a439e39b667cf98d95ac2..30163c94af9f366f1120d53da012fe30087dc74e 100644 (file)
@@ -207,29 +207,15 @@ static inline InterpreterMap &interpreterMap()
 }
     
 Interpreter::Interpreter(JSObject* globalObject)
-    : m_timeoutTime(0)
-    , m_globalExec(this, 0)
+    : m_globalExec(this, 0)
     , m_globalObject(globalObject)
-    , m_argumentsPropertyName(&argumentsPropertyName)
-    , m_specialPrototypePropertyName(&specialPrototypePropertyName)
-    , m_timeoutChecker(0)
-    , m_timedOut(false)
-    , m_startTimeoutCheckCount(0)
-    , m_pauseTimeoutCheckCount(0)
 {
     init();
 }
 
 Interpreter::Interpreter()
-    : m_timeoutTime(0)
-    , m_globalExec(this, 0)
+    : m_globalExec(this, 0)
     , m_globalObject(new JSObject())
-    , m_argumentsPropertyName(&argumentsPropertyName)
-    , m_specialPrototypePropertyName(&specialPrototypePropertyName)
-    , m_timeoutChecker(0)
-    , m_timedOut(false)
-    , m_startTimeoutCheckCount(0)
-    , m_pauseTimeoutCheckCount(0)
 {
     init();
 }
@@ -238,10 +224,18 @@ void Interpreter::init()
 {
     JSLock lock;
 
+    m_refCount = 0;
+    m_timeoutTime = 0;
     m_recursion = 0;
     m_debugger= 0;
     m_context = 0;
+    m_timedOut = false;
+    m_timeoutChecker = 0;
+    m_startTimeoutCheckCount = 0;
+    m_pauseTimeoutCheckCount = 0;
     m_compatMode = NativeMode;
+    m_argumentsPropertyName = &argumentsPropertyName;
+    m_specialPrototypePropertyName = &specialPrototypePropertyName;
 
     interpreterMap().set(m_globalObject, this);
 
index 8c916fda59dac1655cc6352e2e4554b65c0bc748..73ba781be745b3769ab3ce37923e48fd85261938 100644 (file)
@@ -74,7 +74,6 @@ namespace KJS {
      * initialized with the standard global properties.
      */
     Interpreter();
-    virtual ~Interpreter();
 
     /**
      * Returns the object that is used as the global object during all script
@@ -337,8 +336,14 @@ namespace KJS {
     
     bool checkTimeout();
     
+    void ref() { ++m_refCount; }
+    void deref() { if (--m_refCount <= 0) delete this; }
+    int refCount() const { return m_refCount; }
+    
 protected:
+    virtual ~Interpreter(); // only deref should delete us
     virtual bool shouldInterruptScript() const { return true; }
+
     long m_timeoutTime;
 
 private:
@@ -359,6 +364,8 @@ private:
      */
     Interpreter operator=(const Interpreter&);
     
+    int m_refCount;
+    
     ExecState m_globalExec;
     JSObject* m_globalObject;
 
index 0de94a21a9665bfdb144d67623f73cffdd253b5d..a0efe8aca047d986efb8edbf2db956b28c2bf3e0 100644 (file)
@@ -212,18 +212,18 @@ bool doIt(int argc, char** argv)
   GlobalImp* global = new GlobalImp();
 
   // create interpreter
-  Interpreter interp(global);
+  RefPtr<Interpreter> interp = new Interpreter(global);
   // add debug() function
-  global->put(interp.globalExec(), "debug", new TestFunctionImp(TestFunctionImp::Debug, 1));
+  global->put(interp->globalExec(), "debug", new TestFunctionImp(TestFunctionImp::Debug, 1));
   // add "print" for compatibility with the mozilla js shell
-  global->put(interp.globalExec(), "print", new TestFunctionImp(TestFunctionImp::Print, 1));
+  global->put(interp->globalExec(), "print", new TestFunctionImp(TestFunctionImp::Print, 1));
   // add "quit" for compatibility with the mozilla js shell
-  global->put(interp.globalExec(), "quit", new TestFunctionImp(TestFunctionImp::Quit, 0));
+  global->put(interp->globalExec(), "quit", new TestFunctionImp(TestFunctionImp::Quit, 0));
   // add "gc" for compatibility with the mozilla js shell
-  global->put(interp.globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
+  global->put(interp->globalExec(), "gc", new TestFunctionImp(TestFunctionImp::GC, 0));
   // add "version" for compatibility with the mozilla js shell 
-  global->put(interp.globalExec(), "version", new TestFunctionImp(TestFunctionImp::Version, 1));
-  global->put(interp.globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
+  global->put(interp->globalExec(), "version", new TestFunctionImp(TestFunctionImp::Version, 1));
+  global->put(interp->globalExec(), "run", new TestFunctionImp(TestFunctionImp::Run, 1));
   
   Interpreter::setShouldPrintExceptions(true);
   
@@ -238,7 +238,7 @@ bool doIt(int argc, char** argv)
       break; // fail early so we can catch missing files
     }
     
-    Completion completion = interp.evaluate(fileName, 0, script);
+    Completion completion = interp->evaluate(fileName, 0, script);
     success = success && completion.complType() != Throw;
     free(script);
   }
index 00ea8a6d59774a798e8c246e6394d74e628ea449..93abf7cd50c0a61708fe587925b63e86fbb89617 100644 (file)
@@ -1,3 +1,12 @@
+2006-07-14  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Maciej.
+        
+        - Updated JSInterpreter to work with Interpreter ref-counting in JavaScriptCore.
+
+        (JSInterpreter::JSInterpreter::~JSInterpreter): Now protected to catch
+        manual delete.
+
 2006-07-12  Anders Carlsson  <acarlsson@apple.com>
 
         Build fix
index 3decffdad8b771629828e0e66aef1683756f948f..d7e69cc529657ca11793dd02cd1446cbceef6e77 100644 (file)
@@ -33,7 +33,7 @@ JSRun::JSRun(CFStringRef source, JSFlags inFlags)
     :   JSBase(kJSRunTypeID),
         fSource(CFStringToUString(source)),
         fGlobalObject(new JSObject()),
-        fInterpreter(fGlobalObject, inFlags),
+        fInterpreter(new JSInterpreter(fGlobalObject, inFlags)),
         fFlags(inFlags)
 {
 }
@@ -59,15 +59,15 @@ JSObject *JSRun::GlobalObject() const
 
 JSInterpreter* JSRun::GetInterpreter()
 {
-    return &fInterpreter;
+    return fInterpreter.get();
 }
 
 Completion JSRun::Evaluate()
 {
-    return fInterpreter.evaluate(UString(), 0, fSource.data(), fSource.size());
+    return fInterpreter->evaluate(UString(), 0, fSource.data(), fSource.size());
 }
 
 bool JSRun::CheckSyntax()
 {
-    return fInterpreter.checkSyntax(UString(), 0, fSource.data(), fSource.size()).complType() != Throw;
+    return fInterpreter->checkSyntax(UString(), 0, fSource.data(), fSource.size()).complType() != Throw;
 }
index 4f0b3cc050cb034790cd2c4e3e59660e352e7b5c..def0835316a89c999d0231c370a54fec5427269c 100644 (file)
@@ -37,8 +37,11 @@ class JSInterpreter : public Interpreter {
         JSInterpreter(JSObject *global, JSFlags flags) : Interpreter(global), fJSFlags(flags) { }
         JSInterpreter(JSObject *global) : Interpreter(global), fJSFlags(kJSFlagNone) { }
         JSInterpreter() : Interpreter(), fJSFlags(kJSFlagNone) { }
-        JSInterpreter::~JSInterpreter() { }
         JSFlags Flags() const { return fJSFlags; }
+
+    protected:
+        virtual JSInterpreter::~JSInterpreter() { } // only deref on the base class should delete us
+
     private:
         JSFlags fJSFlags;
 };
@@ -57,7 +60,7 @@ class JSRun : public JSBase {
     private:
         UString fSource;
         ProtectedPtr<JSObject> fGlobalObject;
-        JSInterpreter fInterpreter;
+        RefPtr<JSInterpreter> fInterpreter;
         JSFlags fFlags;
 };
 
index dd1745fb1764d4d0c1149e73ed10ed2a49fb2e11..470c68c498d20faee38f33ffe7a65c71535a4463 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef JSUtils_h
 #define JSUtils_h
 
-#include <JavaScriptGlue/JavaScriptGlue.h>
+#include "JavaScriptGlue.h"
 
 #include <JavaScriptCore/value.h>
 #include <JavaScriptCore/object.h>
@@ -39,6 +39,8 @@
 #include <JavaScriptCore/collector.h>
 #include <JavaScriptCore/ustring.h>
 
+#include <wtf/RefPtr.h>
+
 using namespace KJS;
 
 class JSBase;
index 4a3569edf80b22f4d9a7fe9899d1a343cb1f4a24..b4b6dd299ed6935e81feabec5dfb269e889a93a9 100644 (file)
@@ -63,14 +63,14 @@ JSValue *JSValueWrapper::GetValue()
 pthread_key_t interpreterKey;
 pthread_once_t interpreterKeyOnce = PTHREAD_ONCE_INIT;
 
-static void destroyInterpreter(void* data) 
+static void derefInterpreter(void* data) 
 {
-    delete static_cast<Interpreter*>(data);
+    static_cast<Interpreter*>(data)->deref();
 }
 
 static void initializeInterpreterKey()
 {
-    pthread_key_create(&interpreterKey, destroyInterpreter);
+    pthread_key_create(&interpreterKey, derefInterpreter);
 }
 
 static ExecState* getThreadGlobalExecState()
@@ -79,6 +79,7 @@ static ExecState* getThreadGlobalExecState()
     Interpreter* interpreter = static_cast<Interpreter*>(pthread_getspecific(interpreterKey));
     if (!interpreter) {
         interpreter = new Interpreter();
+        interpreter->ref();
         pthread_setspecific(interpreterKey, interpreter);
     }
 
index edb92705aa847c0912dcc7f2500e12106ae1e49a..d68c35152183bdd9205621f6b379b0cdce622b5b 100644 (file)
@@ -1,3 +1,13 @@
+2006-07-14  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Maciej.
+
+        - Updated ScriptInterpreter to work with Interpreter ref-counting in 
+        JavaScriptCore.
+
+        (KJS::ScriptInterpreter::~ScriptInterpreter): Now protected to catch
+        manual delete.
+
 2006-07-14  Anders Carlsson  <acarlsson@apple.com>
 
         Reviewed by Adele and Justin.
index a05c798fd77ff4c6f8cd165001370cbf4c8ecb00..8ffe17721e72358b807f051fa8f07790b7c02193 100644 (file)
@@ -74,10 +74,6 @@ ScriptInterpreter::ScriptInterpreter( JSObject *global, Frame *frame )
     setTimeoutTime(ScriptTimeoutTimeMS);
 }
 
-ScriptInterpreter::~ScriptInterpreter()
-{
-}
-
 DOMObject* ScriptInterpreter::getDOMObject(void* objectHandle) 
 {
     return domObjects()->get(objectHandle);
index 59d8b8b7246745ab9236abebcf29dd2eff6a380e..e9e2e19bd06657f8bbd1baa0026454c1a346da84 100644 (file)
@@ -63,7 +63,6 @@ namespace KJS {
   {
   public:
     ScriptInterpreter(JSObject *global, WebCore::Frame *frame);
-    virtual ~ScriptInterpreter();
 
     static DOMObject* getDOMObject(void* objectHandle);
     static void putDOMObject(void* objectHandle, DOMObject* obj);
@@ -103,6 +102,9 @@ namespace KJS {
 
     virtual bool shouldInterruptScript() const;
 
+  protected:
+    virtual ~ScriptInterpreter() { } // only deref on the base class should delete us
+    
   private:
     WebCore::Frame* m_frame;
 
index e13a152db0c498cead9fd502e2448a484dc716b5..60c18abd3f1e4d0eeabb6db1331511dfbc6123a7 100644 (file)
@@ -36,7 +36,6 @@ namespace WebCore {
 
 KJSProxy::KJSProxy(Frame* frame)
 {
-    m_script = 0;
     m_frame = frame;
     m_handlerLineno = 0;
 }
@@ -44,7 +43,6 @@ KJSProxy::KJSProxy(Frame* frame)
 KJSProxy::~KJSProxy()
 {
     JSLock lock;
-    delete m_script;
     Collector::collect();
 }
 
@@ -123,7 +121,7 @@ ScriptInterpreter* KJSProxy::interpreter()
 {
   initScriptIfNeeded();
   assert(m_script);
-  return m_script;
+  return m_script.get();
 }
 
 void KJSProxy::initScriptIfNeeded()
index 2fbac545dc21549e61ecf9c8738fc70568318ac5..d8390674ad8c4b0beb250718d7649edf929bceeb 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef KJS_PROXY_H
 #define KJS_PROXY_H
 
+#include <wtf/RefPtr.h>
+
 namespace KJS {
     class JSValue;
     class ScriptInterpreter;
@@ -54,7 +56,7 @@ public:
     bool haveInterpreter() const { return m_script; }
 
 private:
-    KJS::ScriptInterpreter* m_script;
+    RefPtr<KJS::ScriptInterpreter> m_script;
     Frame *m_frame;
     int m_handlerLineno;
 };