]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - debugger/Debugger.cpp
JavaScriptCore-576.tar.gz
[apple/javascriptcore.git] / debugger / Debugger.cpp
index 7d791e7c8155a962644ed0fbc2c82933005cfca1..1d2e4fb62bda317b6e7f36e02b42102946ef118b 100644 (file)
 #include "config.h"
 #include "Debugger.h"
 
-#include "JSGlobalObject.h"
+#include "CollectorHeapIterator.h"
+#include "Error.h"
 #include "Interpreter.h"
+#include "JSFunction.h"
+#include "JSGlobalObject.h"
 #include "Parser.h"
+#include "Protect.h"
 
 namespace JSC {
 
-Debugger::Debugger()
-{
-}
-
 Debugger::~Debugger()
 {
     HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
@@ -53,18 +53,60 @@ void Debugger::detach(JSGlobalObject* globalObject)
     globalObject->setDebugger(0);
 }
 
+void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
+{
+    // 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;
+
+    typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
+    typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
+
+    FunctionExecutableSet functionExecutables;
+    SourceProviderMap sourceProviders;
+
+    LiveObjectIterator it = globalData->heap.primaryHeapBegin();
+    LiveObjectIterator heapEnd = globalData->heap.primaryHeapEnd();
+    for ( ; it != heapEnd; ++it) {
+        if (!(*it)->inherits(&JSFunction::info))
+            continue;
+
+        JSFunction* function = asFunction(*it);
+        if (function->executable()->isHostFunction())
+            continue;
+
+        FunctionExecutable* executable = function->jsExecutable();
+
+        // Check if the function is already in the set - if so,
+        // we've already retranslated it, nothing to do here.
+        if (!functionExecutables.add(executable).second)
+            continue;
+
+        ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec();
+        executable->recompile(exec);
+        if (function->scope().globalObject()->debugger() == this)
+            sourceProviders.add(executable->source().provider(), exec);
+    }
+
+    // Call sourceParsed() after reparsing all functions because it will execute
+    // JavaScript in the inspector.
+    SourceProviderMap::const_iterator end = sourceProviders.end();
+    for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
+        sourceParsed(iter->second, SourceCode(iter->first), -1, 0);
+}
+
 JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
 {
     CallFrame* globalCallFrame = globalObject->globalExec();
 
-    int errLine;
-    UString errMsg;
-    SourceCode source = makeSource(script);
-    RefPtr<EvalNode> evalNode = globalObject->globalData()->parser->parse<EvalNode>(globalCallFrame, globalObject->debugger(), source, &errLine, &errMsg);
-    if (!evalNode)
-        return Error::create(globalCallFrame, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());
+    RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script));
+    JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain());
+    if (error)
+        return error;
 
-    return globalObject->globalData()->interpreter->execute(evalNode.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
+    return globalObject->globalData()->interpreter->execute(eval.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
 }
 
 } // namespace JSC