]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - debugger/Debugger.cpp
JavaScriptCore-1218.0.1.tar.gz
[apple/javascriptcore.git] / debugger / Debugger.cpp
index 1d2e4fb62bda317b6e7f36e02b42102946ef118b..0f0b31d283572b5d45d51eb10d8c3c61b9856cf5 100644 (file)
 #include "config.h"
 #include "Debugger.h"
 
-#include "CollectorHeapIterator.h"
 #include "Error.h"
 #include "Interpreter.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
+#include "Operations.h"
 #include "Parser.h"
 #include "Protect.h"
 
+namespace {
+
+using namespace JSC;
+
+class Recompiler : public MarkedBlock::VoidFunctor {
+public:
+#if PLATFORM(IOS)
+    Recompiler(JSC::Debugger*);
+#else
+    Recompiler(Debugger*);
+#endif
+    ~Recompiler();
+    void operator()(JSCell*);
+
+private:
+    typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
+    typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
+    
+#if PLATFORM(IOS)
+    JSC::Debugger* m_debugger;
+#else
+    Debugger* m_debugger;
+#endif
+    FunctionExecutableSet m_functionExecutables;
+    SourceProviderMap m_sourceProviders;
+};
+
+#if PLATFORM(IOS)
+inline Recompiler::Recompiler(JSC::Debugger* debugger)
+#else
+inline Recompiler::Recompiler(Debugger* debugger)
+#endif
+    : m_debugger(debugger)
+{
+}
+
+inline Recompiler::~Recompiler()
+{
+    // Call sourceParsed() after reparsing all functions because it will execute
+    // JavaScript in the inspector.
+    SourceProviderMap::const_iterator end = m_sourceProviders.end();
+    for (SourceProviderMap::const_iterator iter = m_sourceProviders.begin(); iter != end; ++iter)
+        m_debugger->sourceParsed(iter->value, iter->key, -1, String());
+}
+
+inline void Recompiler::operator()(JSCell* cell)
+{
+    if (!cell->inherits(&JSFunction::s_info))
+        return;
+
+    JSFunction* function = jsCast<JSFunction*>(cell);
+    if (function->executable()->isHostFunction())
+        return;
+
+    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 (!m_functionExecutables.add(executable).isNewEntry)
+        return;
+
+    ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
+    executable->clearCodeIfNotCompiling();
+    executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
+    if (m_debugger == function->scope()->globalObject()->debugger())
+        m_sourceProviders.add(executable->source().provider(), exec);
+}
+
+} // namespace
+
 namespace JSC {
 
 Debugger::~Debugger()
@@ -53,60 +123,37 @@ void Debugger::detach(JSGlobalObject* globalObject)
     globalObject->setDebugger(0);
 }
 
-void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
+void Debugger::recompileAllJSFunctions(VM* vm)
 {
     // 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)
+    ASSERT(!vm->dynamicGlobalObject);
+    if (vm->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);
+    Recompiler recompiler(this);
+    vm->heap.objectSpace().forEachLiveCell(recompiler);
 }
 
-JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
+JSValue evaluateInGlobalCallFrame(const String& script, JSValue& exception, JSGlobalObject* globalObject)
 {
     CallFrame* globalCallFrame = globalObject->globalExec();
+    VM& vm = globalObject->vm();
 
-    RefPtr<EvalExecutable> eval = EvalExecutable::create(globalCallFrame, makeSource(script));
-    JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain());
-    if (error)
-        return error;
+    EvalExecutable* eval = EvalExecutable::create(globalCallFrame, vm.codeCache(), makeSource(script), false);
+    if (!eval) {
+        exception = vm.exception;
+        vm.exception = JSValue();
+        return exception;
+    }
 
-    return globalObject->globalData()->interpreter->execute(eval.get(), globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
+    JSValue result = vm.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
+    if (vm.exception) {
+        exception = vm.exception;
+        vm.exception = JSValue();
+    }
+    ASSERT(result);
+    return result;
 }
 
 } // namespace JSC