~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/JavaScriptCore/debugger/Debugger.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 "Error.h"
 
26
#include "Interpreter.h"
 
27
#include "JSFunction.h"
 
28
#include "JSGlobalObject.h"
 
29
#include "Parser.h"
 
30
#include "Protect.h"
 
31
 
 
32
namespace {
 
33
 
 
34
using namespace JSC;
 
35
 
 
36
class Recompiler : public MarkedBlock::VoidFunctor {
 
37
public:
 
38
    Recompiler(Debugger*);
 
39
    ~Recompiler();
 
40
    void operator()(JSCell*);
 
41
 
 
42
private:
 
43
    typedef HashSet<FunctionExecutable*> FunctionExecutableSet;
 
44
    typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap;
 
45
    
 
46
    Debugger* m_debugger;
 
47
    FunctionExecutableSet m_functionExecutables;
 
48
    SourceProviderMap m_sourceProviders;
 
49
};
 
50
 
 
51
inline Recompiler::Recompiler(Debugger* debugger)
 
52
    : m_debugger(debugger)
 
53
{
 
54
}
 
55
 
 
56
inline Recompiler::~Recompiler()
 
57
{
 
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());
 
63
}
 
64
 
 
65
inline void Recompiler::operator()(JSCell* cell)
 
66
{
 
67
    if (!cell->inherits(&JSFunction::s_info))
 
68
        return;
 
69
 
 
70
    JSFunction* function = jsCast<JSFunction*>(cell);
 
71
    if (function->executable()->isHostFunction())
 
72
        return;
 
73
 
 
74
    FunctionExecutable* executable = function->jsExecutable();
 
75
 
 
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)
 
79
        return;
 
80
 
 
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);
 
86
}
 
87
 
 
88
} // namespace
 
89
 
 
90
namespace JSC {
 
91
 
 
92
Debugger::~Debugger()
 
93
{
 
94
    HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
 
95
    for (HashSet<JSGlobalObject*>::iterator it = m_globalObjects.begin(); it != end; ++it)
 
96
        (*it)->setDebugger(0);
 
97
}
 
98
 
 
99
void Debugger::attach(JSGlobalObject* globalObject)
 
100
{
 
101
    ASSERT(!globalObject->debugger());
 
102
    globalObject->setDebugger(this);
 
103
    m_globalObjects.add(globalObject);
 
104
}
 
105
 
 
106
void Debugger::detach(JSGlobalObject* globalObject)
 
107
{
 
108
    ASSERT(m_globalObjects.contains(globalObject));
 
109
    m_globalObjects.remove(globalObject);
 
110
    globalObject->setDebugger(0);
 
111
}
 
112
 
 
113
void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
 
114
{
 
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)
 
119
        return;
 
120
 
 
121
    Recompiler recompiler(this);
 
122
    globalData->heap.objectSpace().forEachLiveCell(recompiler);
 
123
}
 
124
 
 
125
JSValue evaluateInGlobalCallFrame(const String& script, JSValue& exception, JSGlobalObject* globalObject)
 
126
{
 
127
    CallFrame* globalCallFrame = globalObject->globalExec();
 
128
    JSGlobalData& globalData = globalObject->globalData();
 
129
 
 
130
    EvalExecutable* eval = EvalExecutable::create(globalCallFrame, makeSource(script), false);
 
131
    if (!eval) {
 
132
        exception = globalData.exception;
 
133
        globalData.exception = JSValue();
 
134
        return exception;
 
135
    }
 
136
 
 
137
    JSValue result = globalData.interpreter->execute(eval, globalCallFrame, globalObject, globalCallFrame->scope());
 
138
    if (globalData.exception) {
 
139
        exception = globalData.exception;
 
140
        globalData.exception = JSValue();
 
141
    }
 
142
    ASSERT(result);
 
143
    return result;
 
144
}
 
145
 
 
146
} // namespace JSC