JavaScriptCore:
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Oct 2008 23:33:07 +0000 (23:33 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Oct 2008 23:33:07 +0000 (23:33 +0000)
2008-10-15  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
        Start the debugger without reloading the inspected page

        * JavaScriptCore.exp: New symbols.
        * JavaScriptCore.xcodeproj/project.pbxproj: New files.

        * VM/CodeBlock.h:
        (JSC::EvalCodeCache::get): Updated for tweak to parsing API.

        * kjs/CollectorHeapIterator.h: Added. An iterator for the object heap,
        which we use to find all the live functions and recompile them.

        * kjs/DebuggerCallFrame.cpp:
        (JSC::DebuggerCallFrame::evaluate): Updated for tweak to parsing API.

        * kjs/FunctionConstructor.cpp:
        (JSC::constructFunction): Updated for tweak to parsing API.

        * kjs/JSFunction.cpp:
        (JSC::JSFunction::JSFunction): Try to validate our SourceCode in debug
        builds by ASSERTing that it's syntactically valid. This doesn't catch
        all SourceCode bugs, but it catches a lot of them.

        * kjs/JSGlobalObjectFunctions.cpp:
        (JSC::globalFuncEval): Updated for tweak to parsing API.

        * kjs/Parser.cpp:
        (JSC::Parser::parse):
        * kjs/Parser.h:
        (JSC::Parser::parse): Tweaked the parser to make it possible to parse
        without an ExecState, and to allow the client to specify a debugger to
        notify (or not) about the source we parse. This allows the inspector
        to recompile even though no JavaScript is executing, then notify the
        debugger about all source code when it's done.

        * kjs/Shell.cpp:
        (prettyPrintScript): Updated for tweak to parsing API.

        * kjs/SourceRange.h:
        (JSC::SourceCode::isNull): Added to help with ASSERTs.

        * kjs/collector.cpp:
        (JSC::Heap::heapAllocate):
        (JSC::Heap::sweep):
        (JSC::Heap::primaryHeapBegin):
        (JSC::Heap::primaryHeapEnd):
        * kjs/collector.h:
        (JSC::): Moved a bunch of declarations around to enable compilation of
        CollectorHeapIterator.

        * kjs/interpreter.cpp:
        (JSC::Interpreter::checkSyntax):
        (JSC::Interpreter::evaluate): Updated for tweak to parsing API.

        * kjs/lexer.h:
        (JSC::Lexer::sourceCode): BUG FIX: Calculate SourceCode ranges relative
        to the SourceCode range in which we're lexing, otherwise nested functions
        that are compiled individually get SourceCode ranges that don't reflect
        their nesting.

        * kjs/nodes.cpp:
        (JSC::FunctionBodyNode::FunctionBodyNode):
        (JSC::FunctionBodyNode::finishParsing):
        (JSC::FunctionBodyNode::create):
        (JSC::FunctionBodyNode::copyParameters):
        * kjs/nodes.h:
        (JSC::ScopeNode::setSource):
        (JSC::FunctionBodyNode::parameterCount): Added some helper functions for
        copying one FunctionBodyNode's parameters to another. The recompiler uses
        these when calling "finishParsing".

WebCore:

2008-10-15  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
        Start the debugger without reloading the inspected page

        * WebCore.base.exp: New symbols.

        * ForwardingHeaders/kjs/CollectorHeapIterator.h: Copied from ForwardingHeaders/kjs/ustring.h.
        * ForwardingHeaders/kjs/Parser.h: Copied from ForwardingHeaders/kjs/ustring.h.
        * WebCore.xcodeproj/project.pbxproj: New forwarding headers.

        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::setWindowVisible):
        (WebCore::InspectorController::windowScriptObjectAvailable):
        (WebCore::InspectorController::startDebugging):
        * inspector/InspectorController.h: Renamed startDebuggingAndReloadInspectedPage
        to startDebugging, and changed its behavior to match.

        * inspector/JavaScriptDebugListener.h:
        * inspector/JavaScriptDebugServer.cpp:
        (WebCore::JavaScriptDebugServer::JavaScriptDebugServer):
        (WebCore::JavaScriptDebugServer::addListener):
        (WebCore::JavaScriptDebugServer::removeListener):
        (WebCore::JavaScriptDebugServer::recompileAllJSFunctions):
        (WebCore::JavaScriptDebugServer::willAddFirstListener):
        (WebCore::JavaScriptDebugServer::didRemoveLastListener):
        * inspector/JavaScriptDebugServer.h: Refactored the
        JavaScriptDebugServer to centralize handling of adding the first listener
        and removing the last. Then, added a feature to recompile all JS functions
        in these cases. This allows us to dynamically add and remove hooks like
        the debugger hooks without reloading the page.

        * inspector/front-end/ScriptsPanel.js:
        * English.lproj/localizedStrings.js: Updated for startDebuggingAndReloadInspectedPage =>
        startDebugging rename. Removed all UI that claimed that starting the
        debugger would reload the page.

WebKit/mac:

2008-10-15  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
        Start the debugger without reloading the inspected page

        * WebInspector/WebInspector.mm:
        (-[WebInspector startDebuggingJavaScript:]): Updated for rename.

WebKit/win:

2008-10-15  Geoffrey Garen  <ggaren@apple.com>

        Reviewed by Cameron Zwarich.

        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
        Start the debugger without reloading the inspected page

        * WebInspector.cpp:
        (WebInspector::toggleDebuggingJavaScript): Updated for rename.

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

35 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/VM/CodeBlock.h
JavaScriptCore/kjs/CollectorHeapIterator.h [new file with mode: 0644]
JavaScriptCore/kjs/DebuggerCallFrame.cpp
JavaScriptCore/kjs/FunctionConstructor.cpp
JavaScriptCore/kjs/JSFunction.cpp
JavaScriptCore/kjs/JSGlobalObjectFunctions.cpp
JavaScriptCore/kjs/Parser.cpp
JavaScriptCore/kjs/Parser.h
JavaScriptCore/kjs/Shell.cpp
JavaScriptCore/kjs/SourceRange.h
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/kjs/collector.h
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/lexer.h
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
WebCore/ChangeLog
WebCore/English.lproj/localizedStrings.js
WebCore/ForwardingHeaders/kjs/CollectorHeapIterator.h [new file with mode: 0644]
WebCore/ForwardingHeaders/kjs/Parser.h [new file with mode: 0644]
WebCore/WebCore.base.exp
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/inspector/JavaScriptDebugListener.h
WebCore/inspector/JavaScriptDebugServer.cpp
WebCore/inspector/JavaScriptDebugServer.h
WebCore/inspector/front-end/ScriptsPanel.js
WebKit/mac/ChangeLog
WebKit/mac/WebInspector/WebInspector.mm
WebKit/win/ChangeLog
WebKit/win/WebInspector.cpp

index 8ad6027..a6b157a 100644 (file)
@@ -1,3 +1,78 @@
+2008-10-15  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Cameron Zwarich.
+
+        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
+        Start the debugger without reloading the inspected page
+
+        * JavaScriptCore.exp: New symbols.
+        * JavaScriptCore.xcodeproj/project.pbxproj: New files.
+
+        * VM/CodeBlock.h:
+        (JSC::EvalCodeCache::get): Updated for tweak to parsing API.
+
+        * kjs/CollectorHeapIterator.h: Added. An iterator for the object heap,
+        which we use to find all the live functions and recompile them.
+
+        * kjs/DebuggerCallFrame.cpp:
+        (JSC::DebuggerCallFrame::evaluate): Updated for tweak to parsing API.
+
+        * kjs/FunctionConstructor.cpp:
+        (JSC::constructFunction): Updated for tweak to parsing API.
+
+        * kjs/JSFunction.cpp:
+        (JSC::JSFunction::JSFunction): Try to validate our SourceCode in debug
+        builds by ASSERTing that it's syntactically valid. This doesn't catch
+        all SourceCode bugs, but it catches a lot of them.
+
+        * kjs/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncEval): Updated for tweak to parsing API.
+
+        * kjs/Parser.cpp:
+        (JSC::Parser::parse):
+        * kjs/Parser.h:
+        (JSC::Parser::parse): Tweaked the parser to make it possible to parse
+        without an ExecState, and to allow the client to specify a debugger to
+        notify (or not) about the source we parse. This allows the inspector
+        to recompile even though no JavaScript is executing, then notify the
+        debugger about all source code when it's done.
+
+        * kjs/Shell.cpp:
+        (prettyPrintScript): Updated for tweak to parsing API.
+
+        * kjs/SourceRange.h:
+        (JSC::SourceCode::isNull): Added to help with ASSERTs.
+
+        * kjs/collector.cpp:
+        (JSC::Heap::heapAllocate):
+        (JSC::Heap::sweep):
+        (JSC::Heap::primaryHeapBegin):
+        (JSC::Heap::primaryHeapEnd):
+        * kjs/collector.h:
+        (JSC::): Moved a bunch of declarations around to enable compilation of
+        CollectorHeapIterator.
+
+        * kjs/interpreter.cpp:
+        (JSC::Interpreter::checkSyntax):
+        (JSC::Interpreter::evaluate): Updated for tweak to parsing API.
+
+        * kjs/lexer.h:
+        (JSC::Lexer::sourceCode): BUG FIX: Calculate SourceCode ranges relative
+        to the SourceCode range in which we're lexing, otherwise nested functions
+        that are compiled individually get SourceCode ranges that don't reflect
+        their nesting.
+
+        * kjs/nodes.cpp:
+        (JSC::FunctionBodyNode::FunctionBodyNode):
+        (JSC::FunctionBodyNode::finishParsing):
+        (JSC::FunctionBodyNode::create):
+        (JSC::FunctionBodyNode::copyParameters):
+        * kjs/nodes.h:
+        (JSC::ScopeNode::setSource):
+        (JSC::FunctionBodyNode::parameterCount): Added some helper functions for
+        copying one FunctionBodyNode's parameters to another. The recompiler uses
+        these when calling "finishParsing".
+
 2008-10-15  Joerg Bornemann  <joerg.bornemann@trolltech.com>
 
         Reviewed by Darin Adler.
index 84b8a4d..a6a8449 100644 (file)
@@ -95,6 +95,7 @@ __ZN3JSC10Identifier24checkSameIdentifierTableEPNS_12JSGlobalDataEPNS_7UString3R
 __ZN3JSC10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_7UString3RepE 
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
 __ZN3JSC10Identifier5equalEPKNS_7UString3RepEPKc
+__ZN3JSC10JSFunction4infoE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
@@ -153,6 +154,9 @@ __ZN3JSC14JSGlobalObjectD2Ev
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
 __ZN3JSC14constructArrayEPNS_9ExecStateERKNS_7ArgListE
 __ZN3JSC15JSWrapperObject4markEv
+__ZN3JSC16FunctionBodyNode13finishParsingEPNS_10IdentifierEm
+__ZN3JSC16FunctionBodyNode14copyParametersEv
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm16EEEPNS6_INS5_6RefPtrINS_12FuncDeclNodeEEELm16EEERKNS_10SourceCodeEji
 __ZN3JSC16InternalFunction4infoE
 __ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF10PassRefPtrINS_11StructureIDEEERKNS_10IdentifierE
 __ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
@@ -169,7 +173,9 @@ __ZN3JSC20constructEmptyObjectEPNS_9ExecStateE
 __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectEPNS_7JSValueERKNS_7ArgListE
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC4Heap14allocateNumberEm
+__ZN3JSC4Heap14primaryHeapEndEv
 __ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap17globalObjectCountEv
 __ZN3JSC4Heap20protectedObjectCountEv
 __ZN3JSC4Heap24setGCProtectNeedsLockingEv
@@ -202,7 +208,7 @@ __ZN3JSC6JSLock4lockEb
 __ZN3JSC6JSLock6unlockEb
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
-__ZN3JSC6Parser5parseEPNS_9ExecStateEPiPNS_7UStringE
+__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
 __ZN3JSC6strtodEPKcPPc
 __ZN3JSC7ArgList10slowAppendEPNS_7JSValueE
 __ZN3JSC7CStringD1Ev
index dad3bdb..6b01da7 100644 (file)
@@ -69,6 +69,7 @@
                14BD5A300A3E91F600BAF59C /* JSContextRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A290A3E91F600BAF59C /* JSContextRef.cpp */; };
                14BD5A320A3E91F600BAF59C /* JSValueRef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 14BD5A2B0A3E91F600BAF59C /* JSValueRef.cpp */; };
                14E0FF120DBAAED00007C0AB /* Machine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 149B15E70D81F986009CB8C7 /* Machine.cpp */; settings = {COMPILER_FLAGS = "-fno-tree-pre"; }; };
+               14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */ = {isa = PBXBuildFile; fileRef = 14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5D53726F0E1C54880021E549 /* Tracing.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D53726E0E1C54880021E549 /* Tracing.h */; };
                5D5D8AB60E0D0A7200F9C692 /* jsc in Copy Into Framework */ = {isa = PBXBuildFile; fileRef = 932F5BE10822A1C700736975 /* jsc */; };
                5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
                14DA818F0D99FD2000B0A4FB /* JSActivation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSActivation.cpp; sourceTree = "<group>"; };
                14DE0D680D02431400AACCA2 /* JSGlobalObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObject.cpp; sourceTree = "<group>"; };
                14F252560D08DD8D004ECFFF /* JSVariableObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVariableObject.h; sourceTree = "<group>"; };
+               14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectorHeapIterator.h; sourceTree = "<group>"; };
                1C9051420BA9E8A70081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
                1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = JavaScriptCore.xcconfig; sourceTree = "<group>"; };
                1C9051440BA9E8A70081E9D0 /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
                                F692A8860255597D01FF60F7 /* ustring.h */,
                                147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */,
                                147B84620E6DE6B1004775A4 /* PutPropertySlot.h */,
+                               14F3488E0E95EF8A003648BC /* CollectorHeapIterator.h */,
                        );
                        path = kjs;
                        sourceTree = "<group>";
                                7E2ADD8E0E79AAD500D50C51 /* CharacterClassConstructor.h in Headers */,
                                140D17D70E8AD4A9000CD17D /* JSBasePrivate.h in Headers */,
                                869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */,
+                               14F3488F0E95EF8A003648BC /* CollectorHeapIterator.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 3313cf9..bf17356 100644 (file)
@@ -161,7 +161,7 @@ namespace JSC {
                 UString errMsg;
                 
                 SourceCode source = makeSource(evalSource);
-                evalNode = exec->globalData().parser->parse<EvalNode>(exec, source, &errLine, &errMsg);
+                evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
                 if (evalNode) {
                     if (evalSource.size() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && cacheMap.size() < maxCacheEntries)
                         cacheMap.set(evalSource.rep(), evalNode);
diff --git a/JavaScriptCore/kjs/CollectorHeapIterator.h b/JavaScriptCore/kjs/CollectorHeapIterator.h
new file mode 100644 (file)
index 0000000..c5e1d78
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "collector.h"
+
+namespace JSC {
+
+    template <HeapType heapType> class CollectorHeapIterator {
+    public:
+        CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock);
+
+        bool operator!=(const CollectorHeapIterator<heapType>& other) { return m_block != other.m_block || m_cell != other.m_cell; }
+        CollectorHeapIterator<heapType>& operator++();
+        JSCell* operator*() const;
+    
+    private:
+        typedef typename HeapConstants<heapType>::Block Block;
+        typedef typename HeapConstants<heapType>::Cell Cell;
+
+        Block** m_block;
+        Block** m_endBlock;
+        Cell* m_cell;
+        Cell* m_endCell;
+    };
+
+    template <HeapType heapType> 
+    CollectorHeapIterator<heapType>::CollectorHeapIterator(CollectorBlock** block, CollectorBlock** endBlock)
+        : m_block(reinterpret_cast<Block**>(block))
+        , m_endBlock(reinterpret_cast<Block**>(endBlock))
+        , m_cell(m_block == m_endBlock ? 0 : (*m_block)->cells)
+        , m_endCell(m_block == m_endBlock ? 0 : (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock)
+    {
+        if (m_cell && m_cell->u.freeCell.zeroIfFree == 0)
+            ++*this;
+    }
+
+    template <HeapType heapType> 
+    CollectorHeapIterator<heapType>& CollectorHeapIterator<heapType>::operator++()
+    {
+        do {
+            for (++m_cell; m_cell != m_endCell; ++m_cell)
+                if (m_cell->u.freeCell.zeroIfFree != 0) {
+                    return *this;
+                }
+
+            if (++m_block != m_endBlock) {
+                m_cell = (*m_block)->cells;
+                m_endCell = (*m_block)->cells + HeapConstants<heapType>::cellsPerBlock;
+            }
+        } while(m_block != m_endBlock);
+
+        m_cell = 0;
+        return *this;
+    }
+
+    template <HeapType heapType> 
+    JSCell* CollectorHeapIterator<heapType>::operator*() const
+    {
+        return reinterpret_cast<JSCell*>(m_cell);
+    }
+
+} // namespace JSC
index 5365ba7..3564b75 100644 (file)
@@ -72,7 +72,7 @@ JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception)
     int errLine;
     UString errMsg;
     SourceCode source = makeSource(script);
-    RefPtr<EvalNode> evalNode = m_callFrame->scopeChain()->globalData->parser->parse<EvalNode>(m_callFrame, source, &errLine, &errMsg);
+    RefPtr<EvalNode> evalNode = m_callFrame->scopeChain()->globalData->parser->parse<EvalNode>(m_callFrame, m_callFrame->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
     if (!evalNode)
         return Error::create(m_callFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
 
index 6ca0231..7cda8b2 100644 (file)
@@ -87,7 +87,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
     int errLine;
     UString errMsg;
     SourceCode source = makeSource(body, sourceURL, lineNumber);
-    RefPtr<FunctionBodyNode> functionBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, source, &errLine, &errMsg);
+    RefPtr<FunctionBodyNode> functionBody = exec->globalData().parser->parse<FunctionBodyNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
 
     // No program node == syntax error - throw a syntax error
     if (!functionBody)
@@ -125,7 +125,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
         return throwError(exec, SyntaxError, "Syntax error in parameter list");
     }
     size_t count = parameters.size();
-    functionBody->finishParsing(source, parameters.releaseBuffer(), count);
+    functionBody->finishParsing(parameters.releaseBuffer(), count);
 
     JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
index a70d293..6f4c51f 100644 (file)
@@ -49,6 +49,7 @@ JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode
     , m_body(body)
     , m_scopeChain(scopeChainNode)
 {
+    ASSERT(exec->globalData().parser->parse<FunctionBodyNode>(exec, 0, body->source()));
 }
 
 void JSFunction::mark()
index 5f706ca..8bb1c6b 100644 (file)
@@ -286,7 +286,7 @@ JSValue* globalFuncEval(ExecState* exec, JSObject* function, JSValue* thisValue,
     UString errMsg;
 
     SourceCode source = makeSource(s);
-    RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(exec, source, &errLine, &errMsg);
+    RefPtr<EvalNode> evalNode = exec->globalData().parser->parse<EvalNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
 
     if (!evalNode)
         return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL);
index d6f2ed4..f0dadba 100644 (file)
@@ -32,7 +32,7 @@ extern int kjsyyparse(void*);
 
 namespace JSC {
 
-void Parser::parse(ExecState* exec, int* errLine, UString* errMsg)
+void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
 {
     ASSERT(!m_sourceElements);
 
@@ -47,23 +47,20 @@ void Parser::parse(ExecState* exec, int* errLine, UString* errMsg)
     *errLine = -1;
     *errMsg = 0;
 
-    Lexer& lexer = *exec->globalData().lexer;
+    Lexer& lexer = *globalData->lexer;
     lexer.setCode(*m_source);
 
-    int parseError = kjsyyparse(&exec->globalData());
+    int parseError = kjsyyparse(globalData);
     bool lexError = lexer.sawError();
     lexer.clear();
 
-    ParserRefCounted::deleteNewObjects(&exec->globalData());
+    ParserRefCounted::deleteNewObjects(globalData);
 
     if (parseError || lexError) {
         *errLine = lexer.lineNo();
         *errMsg = "Parse error";
         m_sourceElements.clear();
     }
-
-    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger())
-        debugger->sourceParsed(exec, *m_source, *errLine, *errMsg);
 }
 
 void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 
index a880262..5539f3d 100644 (file)
@@ -23,6 +23,7 @@
 #ifndef Parser_h
 #define Parser_h
 
+#include "debugger.h"
 #include "SourceProvider.h"
 #include "nodes.h"
 #include <wtf/Forward.h>
@@ -48,16 +49,13 @@ namespace JSC {
 
     class Parser : Noncopyable {
     public:
-        template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, PassRefPtr<SourceProvider>, int* errLine = 0, UString* errMsg = 0);
-        template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
+        template <class ParsedNode> PassRefPtr<ParsedNode> parse(ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
 
         void didFinishParsing(SourceElements*, ParserRefCountedData<DeclarationStacks::VarStack>*, 
                               ParserRefCountedData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
 
     private:
-        friend class JSGlobalData;
-
-        void parse(ExecState*, int* errLine, UString* errMsg);
+        void parse(JSGlobalData*, int* errLine, UString* errMsg);
 
         const SourceCode* m_source;
         RefPtr<SourceElements> m_sourceElements;
@@ -68,10 +66,10 @@ namespace JSC {
         int m_numConstants;
     };
 
-    template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, const SourceCode& source, int* errLine, UString* errMsg)
+    template <class ParsedNode> PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
     {
         m_source = &source;
-        parse(exec, errLine, errMsg);
+        parse(&exec->globalData(), errLine, errMsg);
         RefPtr<ParsedNode> result;
         if (m_sourceElements) {
             result = ParsedNode::create(&exec->globalData(),
@@ -88,6 +86,9 @@ namespace JSC {
         m_sourceElements = 0;
         m_varDeclarations = 0;
         m_funcDeclarations = 0;
+
+        if (debugger)
+            debugger->sourceParsed(exec, source, *errLine, *errMsg);
         return result.release();
     }
 
index 4ddf9ed..ac7c3d6 100644 (file)
@@ -305,7 +305,7 @@ static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Ve
 {
     int errLine = 0;
     UString errMsg;
-    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, makeSource(script.data(), fileName), &errLine, &errMsg);
+    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), makeSource(script.data(), fileName), &errLine, &errMsg);
     if (!programNode) {
         fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
         return false;
index d69f189..9492b00 100644 (file)
@@ -68,6 +68,7 @@ namespace JSC {
             return m_provider->getRange(m_startChar, m_endChar);
         }
         
+        bool isNull() const { return !m_provider; }
         SourceProvider* provider() const { return m_provider.get(); }
         int firstLine() const { return m_firstLine; }
         int startOffset() const { return m_startChar; }
index bafa5c5..52fd370 100644 (file)
@@ -22,6 +22,7 @@
 #include "collector.h"
 
 #include "ArgList.h"
+#include "CollectorHeapIterator.h"
 #include "ExecState.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
@@ -181,7 +182,7 @@ void Heap::destroy()
     m_globalData = 0;
 }
 
-template <Heap::HeapType heapType>
+template <HeapType heapType>
 static NEVER_INLINE CollectorBlock* allocateBlock()
 {
 #if PLATFORM(DARWIN)
@@ -265,25 +266,7 @@ void Heap::recordExtraCost(size_t cost)
     primaryHeap.extraCost += cost;
 }
 
-template <Heap::HeapType heapType> struct HeapConstants;
-
-template <> struct HeapConstants<Heap::PrimaryHeap> {
-    static const size_t cellSize = CELL_SIZE;
-    static const size_t cellsPerBlock = CELLS_PER_BLOCK;
-    static const size_t bitmapShift = 0;
-    typedef CollectorCell Cell;
-    typedef CollectorBlock Block;
-};
-
-template <> struct HeapConstants<Heap::NumberHeap> {
-    static const size_t cellSize = SMALL_CELL_SIZE;
-    static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
-    static const size_t bitmapShift = 1;
-    typedef SmallCollectorCell Cell;
-    typedef SmallCellCollectorBlock Block;
-};
-
-template <Heap::HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
+template <HeapType heapType> ALWAYS_INLINE void* Heap::heapAllocate(size_t s)
 {
     typedef typename HeapConstants<heapType>::Block Block;
     typedef typename HeapConstants<heapType>::Cell Cell;
@@ -859,13 +842,13 @@ void Heap::markProtectedObjects()
         m_protectedValuesMutex->unlock();
 }
 
-template <Heap::HeapType heapType> size_t Heap::sweep()
+template <HeapType heapType> size_t Heap::sweep()
 {
     typedef typename HeapConstants<heapType>::Block Block;
     typedef typename HeapConstants<heapType>::Cell Cell;
 
     // SWEEP: delete everything with a zero refcount (garbage) and unmark everything else
-    CollectorHeap& heap = heapType == Heap::PrimaryHeap ? primaryHeap : numberHeap;
+    CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
     
     size_t emptyBlocks = 0;
     size_t numLiveObjects = heap.numLiveObjects;
@@ -882,7 +865,7 @@ template <Heap::HeapType heapType> size_t Heap::sweep()
                 if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
                     Cell* cell = curBlock->cells + i;
                     
-                    if (heapType != Heap::NumberHeap) {
+                    if (heapType != NumberHeap) {
                         JSCell* imp = reinterpret_cast<JSCell*>(cell);
                         // special case for allocated but uninitialized object
                         // (We don't need this check earlier because nothing prior this point 
@@ -910,7 +893,7 @@ template <Heap::HeapType heapType> size_t Heap::sweep()
                     ++minimumCellsToProcess;
                 } else {
                     if (!curBlock->marked.get(i >> HeapConstants<heapType>::bitmapShift)) {
-                        if (heapType != Heap::NumberHeap) {
+                        if (heapType != NumberHeap) {
                             JSCell* imp = reinterpret_cast<JSCell*>(cell);
                             imp->~JSCell();
                         }
@@ -1086,4 +1069,14 @@ bool Heap::isBusy()
     return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
 }
 
+Heap::iterator Heap::primaryHeapBegin()
+{
+    return iterator(primaryHeap.blocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+}
+
+Heap::iterator Heap::primaryHeapEnd()
+{
+    return iterator(primaryHeap.blocks + primaryHeap.usedBlocks, primaryHeap.blocks + primaryHeap.usedBlocks);
+}
+
 } // namespace JSC
index 4364553..4719465 100644 (file)
@@ -45,6 +45,9 @@ namespace JSC {
     class JSValue;
 
     enum OperationInProgress { NoOperation, Allocation, Collection };
+    enum HeapType { PrimaryHeap, NumberHeap };
+
+    template <HeapType> class CollectorHeapIterator;
 
     struct CollectorHeap {
         CollectorBlock** blocks;
@@ -62,7 +65,7 @@ namespace JSC {
     class Heap : Noncopyable {
     public:
         class Thread;
-        enum HeapType { PrimaryHeap, NumberHeap };
+        typedef CollectorHeapIterator<PrimaryHeap> iterator;
 
         void destroy();
 
@@ -108,10 +111,14 @@ namespace JSC {
 
         JSGlobalData* globalData() const { return m_globalData; }
         static bool isNumber(JSCell*);
+        
+        // Iterators for the object heap.
+        iterator primaryHeapBegin();
+        iterator primaryHeapEnd();
 
     private:
-        template <Heap::HeapType heapType> void* heapAllocate(size_t);
-        template <Heap::HeapType heapType> size_t sweep();
+        template <HeapType heapType> void* heapAllocate(size_t);
+        template <HeapType heapType> size_t sweep();
         static const CollectorBlock* cellBlock(const JSCell*);
         static CollectorBlock* cellBlock(JSCell*);
         static size_t cellOffset(const JSCell*);
@@ -206,7 +213,7 @@ namespace JSC {
         CollectorCell* freeList;
         CollectorBitmap marked;
         Heap* heap;
-        Heap::HeapType type;
+        HeapType type;
     };
 
     class SmallCellCollectorBlock {
@@ -216,9 +223,27 @@ namespace JSC {
         SmallCollectorCell* freeList;
         CollectorBitmap marked;
         Heap* heap;
-        Heap::HeapType type;
+        HeapType type;
     };
     
+    template <HeapType heapType> struct HeapConstants;
+
+    template <> struct HeapConstants<PrimaryHeap> {
+        static const size_t cellSize = CELL_SIZE;
+        static const size_t cellsPerBlock = CELLS_PER_BLOCK;
+        static const size_t bitmapShift = 0;
+        typedef CollectorCell Cell;
+        typedef CollectorBlock Block;
+    };
+
+    template <> struct HeapConstants<NumberHeap> {
+        static const size_t cellSize = SMALL_CELL_SIZE;
+        static const size_t cellsPerBlock = SMALL_CELLS_PER_BLOCK;
+        static const size_t bitmapShift = 1;
+        typedef SmallCollectorCell Cell;
+        typedef SmallCellCollectorBlock Block;
+    };
+
     inline bool Heap::isNumber(JSCell* cell)
     {
         CollectorBlock* block = Heap::cellBlock(cell);
index 4966b52..ec24220 100644 (file)
@@ -46,7 +46,7 @@ Completion Interpreter::checkSyntax(ExecState* exec, const SourceCode& source)
     int errLine;
     UString errMsg;
 
-    RefPtr<ProgramNode> progNode = exec->globalData().parser->parse<ProgramNode>(exec, source, &errLine, &errMsg);
+    RefPtr<ProgramNode> progNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
     if (!progNode)
         return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
     return Completion(Normal);
@@ -58,7 +58,7 @@ Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const
     
     int errLine;
     UString errMsg;
-    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, source, &errLine, &errMsg);
+    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
 
     if (!programNode)
         return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url()));
index e49c400..6495945 100644 (file)
@@ -88,7 +88,7 @@ namespace JSC {
         bool sawError() const { return m_error; }
 
         void clear();
-        SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), openBrace + 1, closeBrace, firstLine); }
+        SourceCode sourceCode(int openBrace, int closeBrace, int firstLine) { return SourceCode(m_source->provider(), m_source->startOffset() + openBrace + 1, m_source->startOffset() + closeBrace, firstLine); }
 
     private:
         friend class JSGlobalData;
index 6d5a2be..8d2f7ce 100644 (file)
@@ -1746,9 +1746,10 @@ EvalNode* EvalNode::create(JSGlobalData* globalData, SourceElements* children, V
 
 // ------------------------------ FunctionBodyNode -----------------------------
 
-FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
-    : ScopeNode(globalData, SourceCode(), children, varStack, funcStack, features, numConstants)
+FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
+    : ScopeNode(globalData, sourceCode, children, varStack, funcStack, features, numConstants)
     , m_parameters(0)
+    , m_parameterCount(0)
     , m_refCount(0)
 {
 }
@@ -1765,12 +1766,14 @@ void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* fi
     for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
         parameters.append(parameter->ident());
     size_t count = parameters.size();
-    finishParsing(source, parameters.releaseBuffer(), count);
+
+    setSource(source);
+    finishParsing(parameters.releaseBuffer(), count);
 }
 
-void FunctionBodyNode::finishParsing(const SourceCode& source, Identifier* parameters, size_t parameterCount)
+void FunctionBodyNode::finishParsing(Identifier* parameters, size_t parameterCount)
 {
-    setSource(source);
+    ASSERT(!source().isNull());
     m_parameters = parameters;
     m_parameterCount = parameterCount;
 }
@@ -1783,12 +1786,12 @@ void FunctionBodyNode::mark()
 
 FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, CodeFeatures features, int numConstants)
 {
-    return new FunctionBodyNode(globalData, children, varStack, funcStack, features, numConstants);
+    return new FunctionBodyNode(globalData, children, varStack, funcStack, SourceCode(), features, numConstants);
 }
 
-FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode&, CodeFeatures features, int numConstants)
+FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
 {
-    return new FunctionBodyNode(globalData, children, varStack, funcStack, features, numConstants);
+    return new FunctionBodyNode(globalData, children, varStack, funcStack, sourceCode, features, numConstants);
 }
 
 void FunctionBodyNode::generateCode(ScopeChainNode* scopeChainNode)
@@ -1850,6 +1853,13 @@ UString FunctionBodyNode::paramString() const
     return s;
 }
 
+Identifier* FunctionBodyNode::copyParameters()
+{
+    Identifier* parameters = static_cast<Identifier*>(fastMalloc(m_parameterCount * sizeof(Identifier)));
+    VectorCopier<false, Identifier>::uninitializedCopy(m_parameters, m_parameters + m_parameterCount, parameters);
+    return parameters;
+}
+
 // ------------------------------ FuncDeclNode ---------------------------------
 
 JSFunction* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
index 6a6caca..61e189e 100644 (file)
@@ -2174,7 +2174,6 @@ namespace JSC {
 
         virtual void streamTo(SourceStream&) const JSC_FAST_CALL;
         
-        void setSource(const SourceCode& source) { m_source = source; }
         const SourceCode& source() const { return m_source; }
         const UString& sourceURL() const JSC_FAST_CALL { return m_source.provider()->url(); }
         intptr_t sourceID() const { return m_source.provider()->asID(); }
@@ -2196,6 +2195,8 @@ namespace JSC {
         }
 
     protected:
+        void setSource(const SourceCode& source) { m_source = source; }
+
         VarStack m_varStack;
         FunctionStack m_functionStack;
 
@@ -2255,8 +2256,9 @@ namespace JSC {
         ~FunctionBodyNode();
 
         const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
-        size_t parameterCount() { return m_parameterCount; }
+        size_t parameterCount() const { return m_parameterCount; }
         UString paramString() const JSC_FAST_CALL;
+        Identifier* copyParameters();
 
         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
         
@@ -2279,7 +2281,7 @@ namespace JSC {
         void mark();
 
         void finishParsing(const SourceCode&, ParameterNode*);
-        void finishParsing(const SourceCode&, Identifier* parameters, size_t parameterCount);
+        void finishParsing(Identifier* parameters, size_t parameterCount);
         
         UString toSourceString() const JSC_FAST_CALL { return UString("{") + source().toString() + UString("}"); }
 
@@ -2298,7 +2300,7 @@ namespace JSC {
         }
 
     protected:
-        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
+        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
 
     private:
         void generateCode(ScopeChainNode*) JSC_FAST_CALL;
index a21c003..935d64f 100644 (file)
@@ -1,3 +1,42 @@
+2008-10-15  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Cameron Zwarich.
+
+        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
+        Start the debugger without reloading the inspected page
+
+        * WebCore.base.exp: New symbols.
+
+        * ForwardingHeaders/kjs/CollectorHeapIterator.h: Copied from ForwardingHeaders/kjs/ustring.h.
+        * ForwardingHeaders/kjs/Parser.h: Copied from ForwardingHeaders/kjs/ustring.h.
+        * WebCore.xcodeproj/project.pbxproj: New forwarding headers.
+
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::setWindowVisible):
+        (WebCore::InspectorController::windowScriptObjectAvailable):
+        (WebCore::InspectorController::startDebugging):
+        * inspector/InspectorController.h: Renamed startDebuggingAndReloadInspectedPage
+        to startDebugging, and changed its behavior to match.
+
+        * inspector/JavaScriptDebugListener.h:
+        * inspector/JavaScriptDebugServer.cpp:
+        (WebCore::JavaScriptDebugServer::JavaScriptDebugServer):
+        (WebCore::JavaScriptDebugServer::addListener):
+        (WebCore::JavaScriptDebugServer::removeListener):
+        (WebCore::JavaScriptDebugServer::recompileAllJSFunctions):
+        (WebCore::JavaScriptDebugServer::willAddFirstListener):
+        (WebCore::JavaScriptDebugServer::didRemoveLastListener):
+        * inspector/JavaScriptDebugServer.h: Refactored the
+        JavaScriptDebugServer to centralize handling of adding the first listener
+        and removing the last. Then, added a feature to recompile all JS functions
+        in these cases. This allows us to dynamically add and remove hooks like
+        the debugger hooks without reloading the page.
+
+        * inspector/front-end/ScriptsPanel.js:
+        * English.lproj/localizedStrings.js: Updated for startDebuggingAndReloadInspectedPage =>
+        startDebugging rename. Removed all UI that claimed that starting the
+        debugger would reload the page.
+
 2008-10-15  Adele Peterson  <adele@apple.com>
 
         Attempt to fix the Tiger build.
index 25a35f2..004240b 100644 (file)
Binary files a/WebCore/English.lproj/localizedStrings.js and b/WebCore/English.lproj/localizedStrings.js differ
diff --git a/WebCore/ForwardingHeaders/kjs/CollectorHeapIterator.h b/WebCore/ForwardingHeaders/kjs/CollectorHeapIterator.h
new file mode 100644 (file)
index 0000000..98166ab
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/CollectorHeapIterator.h>
diff --git a/WebCore/ForwardingHeaders/kjs/Parser.h b/WebCore/ForwardingHeaders/kjs/Parser.h
new file mode 100644 (file)
index 0000000..10a2775
--- /dev/null
@@ -0,0 +1 @@
+#include <JavaScriptCore/Parser.h>
index d9a977c..3735ca5 100644 (file)
@@ -379,10 +379,10 @@ __ZN7WebCore19CSSStyleDeclaration11setPropertyERKNS_6StringES3_Ri
 __ZN7WebCore19InspectorController12attachWindowEv
 __ZN7WebCore19InspectorController12detachWindowEv
 __ZN7WebCore19InspectorController13stopDebuggingEv
+__ZN7WebCore19InspectorController14startDebuggingEv
 __ZN7WebCore19InspectorController16setWindowVisibleEbb
 __ZN7WebCore19InspectorController26stopUserInitiatedProfilingEv
 __ZN7WebCore19InspectorController27startUserInitiatedProfilingEv
-__ZN7WebCore19InspectorController36startDebuggingAndReloadInspectedPageEv
 __ZN7WebCore19InspectorController4showEv
 __ZN7WebCore19InspectorController5closeEv
 __ZN7WebCore19InspectorController7inspectEPNS_4NodeE
@@ -400,6 +400,8 @@ __ZN7WebCore19TextResourceDecoderC1ERKNS_6StringERKNS_12TextEncodingE
 __ZN7WebCore19TextResourceDecoderD1Ev
 __ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx
 __ZN7WebCore21ContextMenuController16clearContextMenuEv
+__ZN7WebCore21JavaScriptDebugServer23recompileAllJSFunctionsEPNS_5TimerIS0_EE
+__ZN7WebCore21JavaScriptDebugServer6sharedEv
 __ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS0_4TypeEb
 __ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
 __ZN7WebCore21WindowsLatin1EncodingEv
index c1b5659..e375af0 100644 (file)
                1C81BA0A0E97348300266E07 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81BA040E97348300266E07 /* JavaScriptCallFrame.h */; };
                1C81BA0C0E97348300266E07 /* JavaScriptDebugListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81BA060E97348300266E07 /* JavaScriptDebugListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1C81BA0D0E97348300266E07 /* JavaScriptDebugServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C81BA070E97348300266E07 /* JavaScriptDebugServer.cpp */; };
-               1C81BA0E0E97348300266E07 /* JavaScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81BA080E97348300266E07 /* JavaScriptDebugServer.h */; };
+               1C81BA0E0E97348300266E07 /* JavaScriptDebugServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81BA080E97348300266E07 /* JavaScriptDebugServer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1CA19E050DC255950065A994 /* EventLoopMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CA19E030DC255950065A994 /* EventLoopMac.mm */; };
                1CA19E160DC255CA0065A994 /* EventLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CA19E150DC255CA0065A994 /* EventLoop.h */; };
                1CAF34810A6C405200ABE06E /* WebScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF347E0A6C405200ABE06E /* WebScriptObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
index 3256690..75898d7 100644 (file)
@@ -73,6 +73,7 @@
 #include <JavaScriptCore/OpaqueJSString.h>
 #include <kjs/JSLock.h>
 #include <kjs/ustring.h>
+#include <kjs/CollectorHeapIterator.h>
 #include <profiler/Profile.h>
 #include <profiler/Profiler.h>
 #include <wtf/RefCounted.h>
@@ -430,7 +431,7 @@ SIMPLE_INSPECTOR_CALLBACK(loaded, scriptObjectReady);
 SIMPLE_INSPECTOR_CALLBACK(unloading, close);
 SIMPLE_INSPECTOR_CALLBACK(attach, attachWindow);
 SIMPLE_INSPECTOR_CALLBACK(detach, detachWindow);
-SIMPLE_INSPECTOR_CALLBACK(startDebuggingAndReloadInspectedPage, startDebuggingAndReloadInspectedPage);
+SIMPLE_INSPECTOR_CALLBACK(startDebugging, startDebugging);
 SIMPLE_INSPECTOR_CALLBACK(stopDebugging, stopDebugging);
 SIMPLE_INSPECTOR_CALLBACK(pauseInDebugger, pauseInDebugger);
 SIMPLE_INSPECTOR_CALLBACK(resumeDebugger, resumeDebugger);
@@ -1114,7 +1115,7 @@ void InspectorController::setWindowVisible(bool visible, bool attached)
         if (m_nodeToFocus)
             focusNode();
         if (m_attachDebuggerWhenShown)
-            startDebuggingAndReloadInspectedPage();
+            startDebugging();
         if (m_showAfterVisible != CurrentPanel)
             showPanel(m_showAfterVisible);
     } else {
@@ -1321,7 +1322,7 @@ void InspectorController::windowScriptObjectAvailable()
         { "windowUnloading", WebCore::unloading, kJSPropertyAttributeNone },
         { "attach", WebCore::attach, kJSPropertyAttributeNone },
         { "detach", WebCore::detach, kJSPropertyAttributeNone },
-        { "startDebuggingAndReloadInspectedPage", WebCore::startDebuggingAndReloadInspectedPage, kJSPropertyAttributeNone },
+        { "startDebugging", WebCore::startDebugging, kJSPropertyAttributeNone },
         { "stopDebugging", WebCore::stopDebugging, kJSPropertyAttributeNone },
         { "pauseInDebugger", WebCore::pauseInDebugger, kJSPropertyAttributeNone },
         { "resumeDebugger", WebCore::resumeDebugger, kJSPropertyAttributeNone },
@@ -2312,7 +2313,7 @@ void InspectorController::moveWindowBy(float x, float y) const
     m_page->chrome()->setWindowRect(frameRect);
 }
 
-void InspectorController::startDebuggingAndReloadInspectedPage()
+void InspectorController::startDebugging()
 {
     if (!enabled())
         return;
@@ -2331,8 +2332,6 @@ void InspectorController::startDebuggingAndReloadInspectedPage()
     m_attachDebuggerWhenShown = false;
 
     callSimpleFunction(m_scriptContext, m_scriptObject, "debuggerAttached");
-
-    m_inspectedPage->mainFrame()->loader()->reload();
 }
 
 void InspectorController::stopDebugging()
index e788ac4..0b53db0 100644 (file)
@@ -160,7 +160,7 @@ public:
     void moveWindowBy(float x, float y) const;
     void closeWindow();
 
-    void startDebuggingAndReloadInspectedPage();
+    void startDebugging();
     void stopDebugging();
     bool debuggerAttached() const { return m_debuggerAttached; }
 
index 8fd2678..f1cd77f 100644 (file)
@@ -30,7 +30,6 @@
 #define JavaScriptDebugListener_h
 
 namespace JSC {
-    class DebuggerCallFrame;
     class ExecState;
     class SourceCode;
     class UString;
index 4743900..3c081d4 100644 (file)
 #include "ScrollView.h"
 #include "Widget.h"
 #include "ScriptController.h"
+#include <kjs/CollectorHeapIterator.h>
 #include <kjs/DebuggerCallFrame.h>
+#include <kjs/JSLock.h>
+#include <kjs/Parser.h>
 #include <wtf/MainThread.h>
 #include <wtf/UnusedParam.h>
 
@@ -67,6 +70,7 @@ JavaScriptDebugServer::JavaScriptDebugServer()
     , m_paused(false)
     , m_doneProcessingDebuggerEvents(true)
     , m_pauseOnCallFrame(0)
+    , m_recompileTimer(this, &JavaScriptDebugServer::recompileAllJSFunctions)
 {
 }
 
@@ -80,7 +84,7 @@ JavaScriptDebugServer::~JavaScriptDebugServer()
 void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener)
 {
     if (!hasListeners())
-        Page::setDebuggerForAllPages(this);
+        willAddFirstListener();
 
     m_listeners.add(listener);
 }
@@ -88,10 +92,8 @@ void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener)
 void JavaScriptDebugServer::removeListener(JavaScriptDebugListener* listener)
 {
     m_listeners.remove(listener);
-    if (!hasListeners()) {
-        Page::setDebuggerForAllPages(0);
-        m_doneProcessingDebuggerEvents = true;
-    }
+    if (!hasListeners())
+        didRemoveLastListener();
 }
 
 void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener, Page* page)
@@ -99,7 +101,7 @@ void JavaScriptDebugServer::addListener(JavaScriptDebugListener* listener, Page*
     ASSERT_ARG(page, page);
 
     if (!hasListeners())
-        Page::setDebuggerForAllPages(this);
+        willAddFirstListener();
 
     pair<PageListenersMap::iterator, bool> result = m_pageListenersMap.add(page, 0);
     if (result.second)
@@ -118,18 +120,14 @@ void JavaScriptDebugServer::removeListener(JavaScriptDebugListener* listener, Pa
         return;
 
     ListenerSet* listeners = it->second;
-
     listeners->remove(listener);
-
     if (listeners->isEmpty()) {
         m_pageListenersMap.remove(it);
         delete listeners;
     }
 
-    if (!hasListeners()) {
-        Page::setDebuggerForAllPages(0);
-        m_doneProcessingDebuggerEvents = true;
-    }
+    if (!hasListeners())
+        didRemoveLastListener();
 }
 
 void JavaScriptDebugServer::pageCreated(Page* page)
@@ -521,4 +519,70 @@ void JavaScriptDebugServer::didReachBreakpoint(const DebuggerCallFrame& debugger
     pauseIfNeeded(toPage(debuggerCallFrame.dynamicGlobalObject()));
 }
 
+void JavaScriptDebugServer::recompileAllJSFunctions(Timer<JavaScriptDebugServer>*)
+{
+    JSLock lock(false);
+    JSGlobalData* globalData = JSDOMWindow::commonJSGlobalData();
+    
+    // If JavaScript is running, it's not safe to recompile, since we'll end
+    // up throwing away code that is live on the stack.
+    ASSERT(!globalData->dynamicGlobalObject);
+    if (globalData->dynamicGlobalObject)
+        return;
+
+    Vector<ProtectedPtr<JSFunction> > functions;
+    Heap::iterator heapEnd = globalData->heap.primaryHeapEnd();
+    for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) {
+        if ((*it)->isObject(&JSFunction::info))
+            functions.append(static_cast<JSFunction*>(*it));
+    }
+
+    typedef HashMap<RefPtr<FunctionBodyNode>, RefPtr<FunctionBodyNode> > FunctionBodyMap;
+    typedef HashSet<SourceProvider*> SourceProviderSet;
+
+    FunctionBodyMap functionBodies;
+    SourceProviderSet sourceProviders;
+    
+    size_t size = functions.size();
+    for (size_t i = 0; i < size; ++i) {
+        JSFunction* function = functions[i];
+        
+        FunctionBodyNode* oldBody = function->m_body.get();
+        pair<FunctionBodyMap::iterator, bool> result = functionBodies.add(oldBody, 0);
+        if (!result.second) {
+            function->m_body = result.first->second;
+            continue;
+        }
+
+        ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec();
+        const SourceCode& sourceCode = oldBody->source();
+
+        RefPtr<FunctionBodyNode> newBody = globalData->parser->parse<FunctionBodyNode>(exec, 0, sourceCode);
+        ASSERT(newBody);
+        newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount());
+        
+        result.first->second = newBody;
+        function->m_body = newBody.release();
+
+        if (hasListeners()) {
+            SourceProvider* provider = sourceCode.provider();
+            if (sourceProviders.add(provider).second)
+                sourceParsed(exec, SourceCode(provider), -1, 0);
+        }
+    }
+}
+
+void JavaScriptDebugServer::willAddFirstListener()
+{
+    Page::setDebuggerForAllPages(this);
+    m_recompileTimer.startOneShot(0);
+}
+
+void JavaScriptDebugServer::didRemoveLastListener()
+{
+    Page::setDebuggerForAllPages(0);
+    m_doneProcessingDebuggerEvents = true;
+    m_recompileTimer.startOneShot(0);
+}
+
 } // namespace WebCore
index 395fc12..d6ccf90 100644 (file)
@@ -29,8 +29,8 @@
 #ifndef JavaScriptDebugServer_h
 #define JavaScriptDebugServer_h
 
+#include "Timer.h"
 #include <kjs/debugger.h>
-
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/RefPtr.h>
@@ -73,6 +73,8 @@ namespace WebCore {
         void stepOverStatement();
         void stepOutOfFunction();
 
+        void recompileAllJSFunctions(Timer<JavaScriptDebugServer>*);
+
         JavaScriptCallFrame* currentCallFrame();
 
         void pageCreated(Page*);
@@ -103,6 +105,9 @@ namespace WebCore {
         virtual void willExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
         virtual void didExecuteProgram(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
         virtual void didReachBreakpoint(const JSC::DebuggerCallFrame&, intptr_t sourceID, int lineno);
+        
+        void willAddFirstListener();
+        void didRemoveLastListener();
 
         typedef HashMap<Page*, ListenerSet*> PageListenersMap;
         PageListenersMap m_pageListenersMap;
@@ -116,6 +121,7 @@ namespace WebCore {
         RefPtr<JavaScriptCallFrame> m_currentCallFrame;
         HashMap<RefPtr<Frame>, PausedTimeouts*> m_pausedTimeouts;
         HashMap<intptr_t, HashSet<unsigned>*> m_breakpoints;
+        Timer<JavaScriptDebugServer> m_recompileTimer;
     };
 
 } // namespace WebCore
index 1ddfbbb..07cb397 100644 (file)
@@ -143,12 +143,6 @@ WebInspector.ScriptsPanel = function()
     this.attachOverlayElement = document.createElement("div");
     this.attachOverlayElement.id = "scripts-attach-overlay";
 
-    var headerElement = document.createElement("h1");
-    headerElement.textContent = WebInspector.UIString("Starting debugging will reload the inspected page.");
-    this.attachOverlayElement.appendChild(headerElement);
-
-    this.attachOverlayElement.appendChild(document.createElement("br"));
-
     var attachButton = document.createElement("button");
     attachButton.textContent = WebInspector.UIString("Start Debugging");
     attachButton.addEventListener("click", this._toggleDebugging.bind(this), false);
@@ -667,7 +661,7 @@ WebInspector.ScriptsPanel.prototype = {
             if (this.attachOverlayElement.parentNode)
                 this.attachOverlayElement.parentNode.removeChild(this.attachOverlayElement);
         } else {
-            this.debuggingButton.title = WebInspector.UIString("Start debugging and reload inspected page.");
+            this.debuggingButton.title = WebInspector.UIString("Start debugging.");
             this.debuggingButton.removeStyleClass("toggled-on");
             this.pauseButton.disabled = true;
 
@@ -748,7 +742,7 @@ WebInspector.ScriptsPanel.prototype = {
         if (InspectorController.debuggerAttached())
             InspectorController.stopDebugging();
         else
-            InspectorController.startDebuggingAndReloadInspectedPage();
+            InspectorController.startDebugging();
 
         this._clearInterface();
     },
index 3b08187..56c52e2 100644 (file)
@@ -1,3 +1,13 @@
+2008-10-15  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Cameron Zwarich.
+
+        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
+        Start the debugger without reloading the inspected page
+
+        * WebInspector/WebInspector.mm:
+        (-[WebInspector startDebuggingJavaScript:]): Updated for rename.
+
 2008-10-14  Maxime Britto  <britto@apple.com>
 
         Reviewed by Darin Adler.
index cb2898d..caee667 100644 (file)
@@ -88,7 +88,7 @@ using namespace WebCore;
     if (!page)
         return;
     page->inspectorController()->showPanel(InspectorController::ScriptsPanel);
-    page->inspectorController()->startDebuggingAndReloadInspectedPage();
+    page->inspectorController()->startDebugging();
 }
 
 - (void)stopDebuggingJavaScript:(id)sender
index 83a9b74..d44879b 100644 (file)
@@ -1,3 +1,13 @@
+2008-10-15  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Cameron Zwarich.
+
+        Fixed https://bugs.webkit.org/show_bug.cgi?id=21345
+        Start the debugger without reloading the inspected page
+
+        * WebInspector.cpp:
+        (WebInspector::toggleDebuggingJavaScript): Updated for rename.
+
 2008-10-15  Adam Roben  <aroben@apple.com>
 
         Export WTF::Mutex::tryLock
index 15bf638..b1cde6d 100644 (file)
@@ -178,7 +178,7 @@ HRESULT STDMETHODCALLTYPE WebInspector::toggleDebuggingJavaScript()
         inspector->stopDebugging();
     else {
         inspector->showPanel(InspectorController::ScriptsPanel);
-        inspector->startDebuggingAndReloadInspectedPage();
+        inspector->startDebugging();
     }
 
     return S_OK;