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)
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.
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.
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
26
#include "Interpreter.h"
27
#include "JSFunction.h"
28
#include "JSGlobalObject.h"
36
class Recompiler : public MarkedBlock::VoidFunctor {
38
Recompiler(Debugger*);
40
void operator()(JSCell*);
43
typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
44
typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
47
FunctionExecutableSet m_functionExecutables;
48
SourceProviderMap m_sourceProviders;
51
inline Recompiler::Recompiler(Debugger* debugger)
52
: m_debugger(debugger)
56
inline Recompiler::~Recompiler()
58
// Call sourceParsed() after reparsing all functions because it will execute
59
// JavaScript in the inspector.
60
SourceProviderMap::const_iterator end = m_sourceProviders.end();
61
for (SourceProviderMap::const_iterator iter = m_sourceProviders.begin(); iter != end; ++iter)
62
m_debugger->sourceParsed(iter->value, iter->key, -1, String());
65
inline void Recompiler::operator()(JSCell* cell)
67
if (!cell->inherits(&JSFunction::s_info))
70
JSFunction* function = jsCast<JSFunction*>(cell);
71
if (function->executable()->isHostFunction())
74
FunctionExecutable* executable = function->jsExecutable();
76
// Check if the function is already in the set - if so,
77
// we've already retranslated it, nothing to do here.
78
if (!m_functionExecutables.add(executable).isNewEntry)
81
ExecState* exec = function->scope()->globalObject()->JSGlobalObject::globalExec();
82
executable->clearCodeIfNotCompiling();
83
executable->clearUnlinkedCodeForRecompilationIfNotCompiling();
84
if (m_debugger == function->scope()->globalObject()->debugger())
85
m_sourceProviders.add(executable->source().provider(), exec);
94
HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
95
for (HashSet<JSGlobalObject*>::iterator it = m_globalObjects.begin(); it != end; ++it)
96
(*it)->setDebugger(0);
99
void Debugger::attach(JSGlobalObject* globalObject)
101
ASSERT(!globalObject->debugger());
102
globalObject->setDebugger(this);
103
m_globalObjects.add(globalObject);
106
void Debugger::detach(JSGlobalObject* globalObject)
108
ASSERT(m_globalObjects.contains(globalObject));
109
m_globalObjects.remove(globalObject);
110
globalObject->setDebugger(0);
113
void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
115
// If JavaScript is running, it's not safe to recompile, since we'll end
116
// up throwing away code that is live on the stack.
117
ASSERT(!globalData->dynamicGlobalObject);
118
if (globalData->dynamicGlobalObject)
121
Recompiler recompiler(this);
122
globalData->heap.objectSpace().forEachLiveCell(recompiler);
125
JSValue evaluateInGlobalCallFrame(const String& script, JSValue& exception, JSGlobalObject* globalObject)
127
CallFrame* globalCallFrame = globalObject->globalExec();
128
JSGlobalData& globalData = globalObject->globalData();
130
EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
132
exception = globalData.exception;
133
globalData.exception = JSValue();
137
JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
138
if (globalData.exception) {
139
exception = globalData.exception;
140
globalData.exception = JSValue();