| 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(value: globalObject); |
| 47 | } |
| 48 | |
| 49 | void Debugger::detach(JSGlobalObject* globalObject) |
| 50 | { |
| 51 | ASSERT(m_globalObjects.contains(globalObject)); |
| 52 | m_globalObjects.remove(value: 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 | typedef HashSet<FunctionExecutable*> FunctionExecutableSet; |
| 65 | typedef HashMap<SourceProvider*, ExecState*> SourceProviderMap; |
| 66 | |
| 67 | FunctionExecutableSet functionExecutables; |
| 68 | SourceProviderMap sourceProviders; |
| 69 | |
| 70 | LiveObjectIterator it = globalData->heap.primaryHeapBegin(); |
| 71 | LiveObjectIterator heapEnd = globalData->heap.primaryHeapEnd(); |
| 72 | for ( ; it != heapEnd; ++it) { |
| 73 | if (!(*it)->inherits(info: &JSFunction::info)) |
| 74 | continue; |
| 75 | |
| 76 | JSFunction* function = asFunction(value: *it); |
| 77 | if (function->executable()->isHostFunction()) |
| 78 | continue; |
| 79 | |
| 80 | FunctionExecutable* executable = function->jsExecutable(); |
| 81 | |
| 82 | // Check if the function is already in the set - if so, |
| 83 | // we've already retranslated it, nothing to do here. |
| 84 | if (!functionExecutables.add(value: executable).second) |
| 85 | continue; |
| 86 | |
| 87 | ExecState* exec = function->scope().globalObject()->JSGlobalObject::globalExec(); |
| 88 | executable->recompile(exec); |
| 89 | if (function->scope().globalObject()->debugger() == this) |
| 90 | sourceProviders.add(key: executable->source().provider(), mapped: exec); |
| 91 | } |
| 92 | |
| 93 | // Call sourceParsed() after reparsing all functions because it will execute |
| 94 | // JavaScript in the inspector. |
| 95 | SourceProviderMap::const_iterator end = sourceProviders.end(); |
| 96 | for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter) |
| 97 | sourceParsed(iter->second, SourceCode(iter->first), errorLineNumber: -1, errorMessage: 0); |
| 98 | } |
| 99 | |
| 100 | JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject) |
| 101 | { |
| 102 | CallFrame* globalCallFrame = globalObject->globalExec(); |
| 103 | |
| 104 | RefPtr<EvalExecutable> eval = EvalExecutable::create(exec: globalCallFrame, source: makeSource(source: script)); |
| 105 | JSObject* error = eval->compile(globalCallFrame, globalCallFrame->scopeChain()); |
| 106 | if (error) |
| 107 | return error; |
| 108 | |
| 109 | return globalObject->globalData()->interpreter->execute(evalNode: eval.get(), exec: globalCallFrame, thisObj: globalObject, scopeChain: globalCallFrame->scopeChain(), exception: &exception); |
| 110 | } |
| 111 | |
| 112 | } // namespace JSC |
| 113 | |