Remove AST nodes from use within the Runtime (outside of parsing), stage 1
[WebKit-https.git] / JavaScriptCore / debugger / Debugger.cpp
1 /*
2  *  Copyright (C) 2008 Apple Inc. All rights reserved.
3  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
4  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #include "config.h"
23 #include "Debugger.h"
24
25 #include "CollectorHeapIterator.h"
26 #include "Error.h"
27 #include "Interpreter.h"
28 #include "JSFunction.h"
29 #include "JSGlobalObject.h"
30 #include "Parser.h"
31 #include "Protect.h"
32
33 namespace JSC {
34
35 Debugger::~Debugger()
36 {
37     HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
38     for (HashSet<JSGlobalObject*>::iterator it = m_globalObjects.begin(); it != end; ++it)
39         (*it)->setDebugger(0);
40 }
41
42 void Debugger::attach(JSGlobalObject* globalObject)
43 {
44     ASSERT(!globalObject->debugger());
45     globalObject->setDebugger(this);
46     m_globalObjects.add(globalObject);
47 }
48
49 void Debugger::detach(JSGlobalObject* globalObject)
50 {
51     ASSERT(m_globalObjects.contains(globalObject));
52     m_globalObjects.remove(globalObject);
53     globalObject->setDebugger(0);
54 }
55
56 void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
57 {
58     // If JavaScript is running, it's not safe to recompile, since we'll end
59     // up throwing away code that is live on the stack.
60     ASSERT(!globalData->dynamicGlobalObject);
61     if (globalData->dynamicGlobalObject)
62         return;
63
64     Vector<ProtectedPtr<JSFunction> > functions;
65     Heap::iterator heapEnd = globalData->heap.primaryHeapEnd();
66     for (Heap::iterator it = globalData->heap.primaryHeapBegin(); it != heapEnd; ++it) {
67         if ((*it)->inherits(&JSFunction::info)) {
68             JSFunction* function = asFunction(*it);
69             if (!function->body()->isHostFunction())
70                 functions.append(function);
71         }
72     }
73
74     typedef HashMap<RefPtr<FunctionBodyNode>, RefPtr<FunctionBodyNode> > FunctionBodyMap;
75     typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
76
77     FunctionBodyMap functionBodies;
78     SourceProviderMap sourceProviders;
79
80     size_t size = functions.size();
81     for (size_t i = 0; i < size; ++i) {
82         JSFunction* function = functions[i];
83
84         FunctionBodyNode* oldBody = function->body();
85         pair<FunctionBodyMap::iterator, bool> result = functionBodies.add(oldBody, 0);
86         if (!result.second) {
87             function->setBody(result.first->second);
88             continue;
89         }
90
91         ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec();
92         const SourceCode& sourceCode = oldBody->source();
93
94         RefPtr<FunctionBodyNode> newBody = globalData->parser->parse<FunctionBodyNode>(exec, 0, sourceCode);
95         ASSERT(newBody);
96         newBody->finishParsing(oldBody->copyParameters(), oldBody->parameterCount(), oldBody->ident());
97
98         result.first->second = newBody;
99         function->setBody(newBody.release());
100
101         if (function->scope().globalObject()->debugger() == this)
102             sourceProviders.add(sourceCode.provider(), exec);
103     }
104
105     // Call sourceParsed() after reparsing all functions because it will execute
106     // JavaScript in the inspector.
107     SourceProviderMap::const_iterator end = sourceProviders.end();
108     for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
109         sourceParsed(iter->second, SourceCode(iter->first), -1, 0);
110 }
111
112 JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
113 {
114     CallFrame* globalCallFrame = globalObject->globalExec();
115
116     EvalExecutable eval(makeSource(script));
117     JSObject* error = eval.parse(globalCallFrame);
118     if (error)
119         return error;
120
121     return globalObject->globalData()->interpreter->execute(&eval, globalCallFrame, globalObject, globalCallFrame->scopeChain(), &exception);
122 }
123
124 } // namespace JSC