]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - inspector/InjectedScriptManager.cpp
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / inspector / InjectedScriptManager.cpp
diff --git a/inspector/InjectedScriptManager.cpp b/inspector/InjectedScriptManager.cpp
new file mode 100644 (file)
index 0000000..ef0d9a3
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InjectedScriptManager.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "Completion.h"
+#include "InjectedScriptHost.h"
+#include "InjectedScriptSource.h"
+#include "InspectorValues.h"
+#include "JSInjectedScriptHost.h"
+#include "JSLock.h"
+#include "ScriptObject.h"
+#include "SourceCode.h"
+
+using namespace JSC;
+
+namespace Inspector {
+
+InjectedScriptManager::InjectedScriptManager(InspectorEnvironment& environment, PassRefPtr<InjectedScriptHost> injectedScriptHost)
+    : m_environment(environment)
+    , m_injectedScriptHost(injectedScriptHost)
+    , m_nextInjectedScriptId(1)
+{
+}
+
+InjectedScriptManager::~InjectedScriptManager()
+{
+}
+
+void InjectedScriptManager::disconnect()
+{
+    discardInjectedScripts();
+}
+
+InjectedScriptHost* InjectedScriptManager::injectedScriptHost()
+{
+    return m_injectedScriptHost.get();
+}
+
+InjectedScript InjectedScriptManager::injectedScriptForId(int id)
+{
+    auto it = m_idToInjectedScript.find(id);
+    if (it != m_idToInjectedScript.end())
+        return it->value;
+
+    for (auto it = m_scriptStateToId.begin(); it != m_scriptStateToId.end(); ++it) {
+        if (it->value == id)
+            return injectedScriptFor(it->key);
+    }
+
+    return InjectedScript();
+}
+
+int InjectedScriptManager::injectedScriptIdFor(ExecState* scriptState)
+{
+    auto it = m_scriptStateToId.find(scriptState);
+    if (it != m_scriptStateToId.end())
+        return it->value;
+
+    int id = m_nextInjectedScriptId++;
+    m_scriptStateToId.set(scriptState, id);
+    return id;
+}
+
+InjectedScript InjectedScriptManager::injectedScriptForObjectId(const String& objectId)
+{
+    RefPtr<InspectorValue> parsedObjectId = InspectorValue::parseJSON(objectId);
+    if (parsedObjectId && parsedObjectId->type() == InspectorValue::TypeObject) {
+        long injectedScriptId = 0;
+        bool success = parsedObjectId->asObject()->getNumber(ASCIILiteral("injectedScriptId"), &injectedScriptId);
+        if (success)
+            return m_idToInjectedScript.get(injectedScriptId);
+    }
+
+    return InjectedScript();
+}
+
+void InjectedScriptManager::discardInjectedScripts()
+{
+    m_injectedScriptHost->clearAllWrappers();
+    m_idToInjectedScript.clear();
+    m_scriptStateToId.clear();
+}
+
+void InjectedScriptManager::releaseObjectGroup(const String& objectGroup)
+{
+    for (auto it = m_idToInjectedScript.begin(); it != m_idToInjectedScript.end(); ++it)
+        it->value.releaseObjectGroup(objectGroup);
+}
+
+String InjectedScriptManager::injectedScriptSource()
+{
+    return String(reinterpret_cast<const char*>(InjectedScriptSource_js), sizeof(InjectedScriptSource_js));
+}
+
+Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ExecState* scriptState, int id)
+{
+    JSLockHolder lock(scriptState);
+
+    SourceCode sourceCode = makeSource(source);
+    JSGlobalObject* globalObject = scriptState->lexicalGlobalObject();
+    JSValue globalThisValue = scriptState->globalThisValue();
+
+    JSValue evaluationException;
+    InspectorEvaluateHandler evaluateHandler = m_environment.evaluateHandler();
+    JSValue functionValue = evaluateHandler(scriptState, sourceCode, globalThisValue, &evaluationException);
+    if (evaluationException)
+        return Deprecated::ScriptObject();
+
+    CallData callData;
+    CallType callType = getCallData(functionValue, callData);
+    if (callType == CallTypeNone)
+        return Deprecated::ScriptObject();
+
+    MarkedArgumentBuffer args;
+    args.append(m_injectedScriptHost->jsWrapper(scriptState, globalObject));
+    args.append(globalThisValue);
+    args.append(jsNumber(id));
+
+    JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
+    if (result.isObject())
+        return Deprecated::ScriptObject(scriptState, result.getObject());
+
+    return Deprecated::ScriptObject();
+}
+
+InjectedScript InjectedScriptManager::injectedScriptFor(ExecState* inspectedExecState)
+{
+    auto it = m_scriptStateToId.find(inspectedExecState);
+    if (it != m_scriptStateToId.end()) {
+        auto it1 = m_idToInjectedScript.find(it->value);
+        if (it1 != m_idToInjectedScript.end())
+            return it1->value;
+    }
+
+    if (!m_environment.canAccessInspectedScriptState(inspectedExecState))
+        return InjectedScript();
+
+    int id = injectedScriptIdFor(inspectedExecState);
+    Deprecated::ScriptObject injectedScriptObject = createInjectedScript(injectedScriptSource(), inspectedExecState, id);
+    InjectedScript result(injectedScriptObject, &m_environment);
+    m_idToInjectedScript.set(id, result);
+    didCreateInjectedScript(result);
+    return result;
+}
+
+void InjectedScriptManager::didCreateInjectedScript(InjectedScript)
+{
+    // Intentionally empty. This allows for subclasses to inject additional scripts.
+}
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR)