Web Inspector: Move InjectedScript classes into JavaScriptCore
https://bugs.webkit.org/show_bug.cgi?id=126598
Source/JavaScriptCore:
Reviewed by Timothy Hatcher.
Part 1: Extract InspectorInstrumentationCookie class from InspectorInstrumentation.
Part 2: Move InjectedScriptSource and generation into JavaScriptCore.
Part 3: Update CodeGeneratorInspector to avoid inlining virtual destructors.
Part 4: Move all inspector scripts into JavaScriptCore and update generators.
Part 5: Move InjectedScript classes into JavaScriptCore
Part 6: Put it all together. Make WebCore use the JavaScriptCore InjectedScript files.
There are pieces of logic that WebCore wants to hook into in the InjectedScript
execution (e.g. for CommandLineAPIModule and InspectorInstrumentation). Create
hooks for those in a base class called InspectorEnvironment. For now, the
InspectorControllers (Page, JSGlobalObject, Worker) will be the InspectorEnvironments
and provide answers to its hooks.
* inspector/InspectorEnvironment.h: Added.
New hooks needed by WebCore in various places. Mostly stubbed in JavaScriptCore.
* inspector/InjectedScript.cpp: Renamed from Source/WebCore/inspector/InjectedScript.cpp.
* inspector/InjectedScript.h: Added.
* inspector/InjectedScriptBase.cpp: Renamed from Source/WebCore/inspector/InjectedScriptBase.cpp.
* inspector/InjectedScriptBase.h: Renamed from Source/WebCore/inspector/InjectedScriptBase.h.
* inspector/InjectedScriptModule.cpp: Renamed from Source/WebCore/inspector/InjectedScriptModule.cpp.
* inspector/InjectedScriptModule.h: Renamed from Source/WebCore/inspector/InjectedScriptModule.h.
Cleanup the style of these files (nullptr, formatting, whitespace, etc).
Use the InspectorEnvironments call/evaluate function for ScriptFunctionCalls and checking access
* inspector/InjectedScriptManager.cpp: Renamed from Source/WebCore/inspector/InjectedScriptManager.cpp.
* inspector/InjectedScriptManager.h: Renamed from Source/WebCore/inspector/InjectedScriptManager.h.
Take an InspectorEnvironment with multiple hooks, instead of a single hook function.
* inspector/InjectedScriptHost.cpp: Added.
* inspector/InjectedScriptHost.h: Added.
* inspector/JSInjectedScriptHost.cpp: Renamed from Source/WebCore/bindings/js/JSInjectedScriptHostCustom.cpp.
* inspector/JSInjectedScriptHost.h: Added.
* inspector/JSInjectedScriptHostPrototype.cpp: Added.
* inspector/JSInjectedScriptHostPrototype.h: Added.
Implementation of InjectedScriptHost which is passed into the script (InjectedScriptSource.js)
that we inject into the page. This is mostly copied from the original autogenerated code,
then simplified and cleaned up. InjectedScriptHost can be subclasses to provide specialized
implementations of isHTMLAllCollection and type for Web/DOM types unknown to a pure JS context.
For OS X be sure to export the scripts as if they are private headers.
* GNUmakefile.am:
* JavaScriptCore.xcodeproj/project.pbxproj:
* inspector/scripts/cssmin.py: Renamed from Source/WebCore/inspector/Scripts/cssmin.py.
* inspector/scripts/inline-and-minify-stylesheets-and-scripts.py: Renamed from Source/WebCore/inspector/Scripts/inline-and-minify-stylesheets-and-scripts.py.
* inspector/scripts/jsmin.py: Renamed from Source/WebCore/inspector/Scripts/jsmin.py.
* inspector/scripts/xxd.pl: Renamed from Source/WebCore/inspector/xxd.pl.
This avoids build errors about duplicate exported virtual inlined methods
are included from multiple places. Just put empty destructors in the
implementation file instead of inlined.
* inspector/scripts/CodeGeneratorInspector.py:
(Generator):
(Generator.go):
* inspector/scripts/CodeGeneratorInspectorStrings.py:
Move InjectedScriptSource.js and derived sources generation.
* CMakeLists.txt:
* DerivedSources.make:
* GNUmakefile.am:
* GNUmakefile.list.am:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.xcodeproj/project.pbxproj:
* inspector/InjectedScriptSource.js: Renamed from Source/WebCore/inspector/InjectedScriptSource.js.
Source/WebCore:
Reviewed by Timothy Hatcher.
* CMakeLists.txt:
* DerivedSources.cpp:
* DerivedSources.make:
* GNUmakefile.list.am:
* UseJSC.cmake:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
Remove old InjectedScript files.
* ForwardingHeaders/inspector/InjectedScript.h: Added.
* ForwardingHeaders/inspector/InjectedScriptBase.h: Added.
* ForwardingHeaders/inspector/InjectedScriptHost.h: Added.
* ForwardingHeaders/inspector/InjectedScriptManager.h: Added.
* ForwardingHeaders/inspector/InjectedScriptModule.h: Added.
* ForwardingHeaders/inspector/InspectorEnvironment.h: Added.
Expose headers to WebCore.
* inspector/InspectorController.h:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
(WebCore::InspectorController::developerExtrasEnabled):
(WebCore::InspectorController::canAccessInspectedScriptState):
(WebCore::InspectorController::functionCallHandler):
(WebCore::InspectorController::evaluateHandler):
(WebCore::InspectorController::willCallInjectedScriptFunction):
(WebCore::InspectorController::didCallInjectedScriptFunction):
* inspector/WorkerInspectorController.h:
* inspector/WorkerInspectorController.cpp:
(WebCore::WorkerInspectorController::WorkerInspectorController):
(WebCore::WorkerInspectorController::functionCallHandler):
(WebCore::WorkerInspectorController::evaluateHandler):
(WebCore::WorkerInspectorController::willCallInjectedScriptFunction):
(WebCore::WorkerInspectorController::didCallInjectedScriptFunction):
Make both InspectorControllers in WebCore be InspectorEnvironments.
* bindings/js/JSMainThreadExecState.h:
* bindings/js/JSMainThreadExecState.cpp:
(WebCore::evaluateHandlerFromAnyThread):
Make JSC::evaluate wrapper like the existing JSC::call wrapper.
These will be the ScriptFunctionCall implementations when debugging
a WebCore::Page or worker, instead of the pure JSC versions.
* inspector/PageInjectedScriptHost.h: Copied from Source/WebCore/inspector/CommandLineAPIModule.h.
* inspector/PageInjectedScriptHost.cpp: Copied from Source/WebCore/inspector/PageInjectedScriptManager.cpp.
(WebCore::PageInjectedScriptHost::type):
(WebCore::PageInjectedScriptHost::isHTMLAllCollection):
WebCore InjectedScriptHost implementation for DOM type handling.
* inspector/PageInjectedScriptManager.h:
* inspector/PageInjectedScriptManager.cpp:
(WebCore::PageInjectedScriptManager::PageInjectedScriptManager):
(WebCore::PageInjectedScriptManager::discardInjectedScriptsFor):
WebCore InjectedScriptManager implementation for CommandLineAPI and
specialized DOMWindow injected script management.
* bindings/js/JSBindingsAllInOne.cpp:
* inspector/CommandLineAPIHost.cpp:
* inspector/CommandLineAPIHost.h:
* inspector/CommandLineAPIModule.cpp:
(WebCore::CommandLineAPIModule::host):
* inspector/CommandLineAPIModule.h:
* inspector/ConsoleMessage.cpp:
(WebCore::ConsoleMessage::addToFrontend):
* inspector/ConsoleMessage.h:
* inspector/InjectedScriptCanvasModule.cpp:
(WebCore::InjectedScriptCanvasModule::InjectedScriptCanvasModule):
* inspector/InjectedScriptCanvasModule.h:
* inspector/InspectorAllInOne.cpp:
* inspector/InspectorCanvasAgent.cpp:
* inspector/InspectorCanvasAgent.h:
(WebCore::InspectorCanvasAgent::create):
* inspector/InspectorConsoleAgent.cpp:
(WebCore::InspectorConsoleAgent::InspectorConsoleAgent):
* inspector/InspectorConsoleAgent.h:
* inspector/InspectorDOMAgent.cpp:
* inspector/InspectorDOMAgent.h:
(WebCore::InspectorDOMAgent::create):
* inspector/InspectorDebuggerAgent.cpp:
* inspector/InspectorDebuggerAgent.h:
(WebCore::InspectorDebuggerAgent::injectedScriptManager):
* inspector/InspectorHeapProfilerAgent.cpp:
(WebCore::InspectorHeapProfilerAgent::create):
(WebCore::InspectorHeapProfilerAgent::InspectorHeapProfilerAgent):
* inspector/InspectorHeapProfilerAgent.h:
* inspector/InspectorIndexedDBAgent.cpp:
* inspector/InspectorIndexedDBAgent.h:
(WebCore::InspectorIndexedDBAgent::create):
* inspector/InspectorPageAgent.cpp:
* inspector/InspectorPageAgent.h:
* inspector/InspectorProfilerAgent.cpp:
(WebCore::PageProfilerAgent::PageProfilerAgent):
(WebCore::InspectorProfilerAgent::create):
(WebCore::WorkerProfilerAgent::WorkerProfilerAgent):
(WebCore::InspectorProfilerAgent::InspectorProfilerAgent):
* inspector/InspectorProfilerAgent.h:
* inspector/InspectorRuntimeAgent.cpp:
* inspector/InspectorRuntimeAgent.h:
(WebCore::InspectorRuntimeAgent::injectedScriptManager):
* inspector/PageConsoleAgent.cpp:
(WebCore::PageConsoleAgent::PageConsoleAgent):
* inspector/PageConsoleAgent.h:
(WebCore::PageConsoleAgent::create):
* inspector/PageDebuggerAgent.cpp:
* inspector/PageDebuggerAgent.h:
* inspector/PageRuntimeAgent.cpp:
* inspector/PageRuntimeAgent.h:
(WebCore::PageRuntimeAgent::create):
* inspector/WorkerConsoleAgent.cpp:
(WebCore::WorkerConsoleAgent::WorkerConsoleAgent):
* inspector/WorkerConsoleAgent.h:
(WebCore::WorkerConsoleAgent::create):
* inspector/WorkerDebuggerAgent.cpp:
* inspector/WorkerDebuggerAgent.h:
* inspector/WorkerRuntimeAgent.cpp:
* inspector/WorkerRuntimeAgent.h:
(WebCore::WorkerRuntimeAgent::create):
Switch to using the Inspector namespace and JSC InjectedScript files.
* bindings/js/JSInjectedScriptManager.cpp: Removed.
* inspector/InjectedScript.h: Removed.
* inspector/InjectedScriptHost.cpp: Removed.
* inspector/InjectedScriptHost.h: Removed.
* inspector/InjectedScriptHost.idl: Removed.
With the updated location switch to using the appropriate INSPECTOR_SCRIPTS_DIR
variable which defines where the scripts are.
* CMakeLists.txt:
* DerivedSources.make:
* GNUmakefile.am:
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
Currently InjectedScriptBase uses InspectorInstrumentation directly
to track calling into JavaScript for timeline purposes. We will remove
the direct call from InjectedScriptBase and extracting the Cookie class
will make that easier.
* CMakeLists.txt:
* GNUmakefile.list.am:
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* inspector/InspectorAllInOne.cpp:
* inspector/InspectorInstrumentation.cpp:
* inspector/InspectorInstrumentation.h:
* inspector/InspectorInstrumentationCookie.cpp: Added.
(WebCore::InspectorInstrumentationCookie::InspectorInstrumentationCookie):
(WebCore::InspectorInstrumentationCookie::operator=):
(WebCore::InspectorInstrumentationCookie::~InspectorInstrumentationCookie):
* inspector/InspectorInstrumentationCookie.h: Added.
(WebCore::InspectorInstrumentationCookie::isValid):
(WebCore::InspectorInstrumentationCookie::instrumentingAgents):
(WebCore::InspectorInstrumentationCookie::hasMatchingTimelineAgentId):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@161563 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp b/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp
new file mode 100644
index 0000000..3f2f1ed
--- /dev/null
+++ b/Source/JavaScriptCore/inspector/JSInjectedScriptHost.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2013 Apple 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 INC. OR
+ * 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 "JSInjectedScriptHost.h"
+
+#if ENABLE(INSPECTOR)
+
+#include "DateInstance.h"
+#include "Error.h"
+#include "InjectedScriptHost.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSInjectedScriptHostPrototype.h"
+#include "JSTypedArrays.h"
+#include "ObjectConstructor.h"
+#include "Operations.h"
+#include "RegExpObject.h"
+#include "SourceCode.h"
+#include "TypedArrayInlines.h"
+
+using namespace JSC;
+
+namespace Inspector {
+
+const ClassInfo JSInjectedScriptHost::s_info = { "InjectedScriptHost", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSInjectedScriptHost) };
+
+JSInjectedScriptHost::JSInjectedScriptHost(VM& vm, Structure* structure, PassRefPtr<InjectedScriptHost> impl)
+ : JSDestructibleObject(vm, structure)
+ , m_impl(impl.leakRef())
+{
+}
+
+void JSInjectedScriptHost::finishCreation(VM& vm)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+}
+
+JSObject* JSInjectedScriptHost::createPrototype(VM& vm, JSGlobalObject* globalObject)
+{
+ return JSInjectedScriptHostPrototype::create(vm, globalObject, JSInjectedScriptHostPrototype::createStructure(vm, globalObject, globalObject->objectPrototype()));
+}
+
+void JSInjectedScriptHost::destroy(JSC::JSCell* cell)
+{
+ JSInjectedScriptHost* thisObject = static_cast<JSInjectedScriptHost*>(cell);
+ thisObject->JSInjectedScriptHost::~JSInjectedScriptHost();
+}
+
+void JSInjectedScriptHost::releaseImpl()
+{
+ if (m_impl) {
+ m_impl->deref();
+ m_impl = nullptr;
+ }
+}
+
+JSInjectedScriptHost::~JSInjectedScriptHost()
+{
+ releaseImpl();
+}
+
+JSValue JSInjectedScriptHost::evaluate(ExecState* exec) const
+{
+ JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+ return globalObject->evalFunction();
+}
+
+JSValue JSInjectedScriptHost::internalConstructorName(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSObject* thisObject = jsCast<JSObject*>(exec->uncheckedArgument(0).toThis(exec, NotStrictMode));
+ String result = thisObject->methodTable()->className(thisObject);
+ return jsString(exec, result);
+}
+
+JSValue JSInjectedScriptHost::isHTMLAllCollection(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSValue value = exec->uncheckedArgument(0);
+ return jsBoolean(impl().isHTMLAllCollection(value));
+}
+
+JSValue JSInjectedScriptHost::type(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSValue value = exec->uncheckedArgument(0);
+ if (value.isString())
+ return exec->vm().smallStrings.stringString();
+ if (value.isBoolean())
+ return exec->vm().smallStrings.booleanString();
+ if (value.isNumber())
+ return exec->vm().smallStrings.numberString();
+
+ if (value.inherits(JSArray::info()))
+ return jsNontrivialString(exec, ASCIILiteral("array"));
+ if (value.inherits(DateInstance::info()))
+ return jsNontrivialString(exec, ASCIILiteral("date"));
+ if (value.inherits(RegExpObject::info()))
+ return jsNontrivialString(exec, ASCIILiteral("regexp"));
+ if (value.inherits(JSInt8Array::info()) || value.inherits(JSInt16Array::info()) || value.inherits(JSInt32Array::info()))
+ return jsNontrivialString(exec, ASCIILiteral("array"));
+ if (value.inherits(JSUint8Array::info()) || value.inherits(JSUint16Array::info()) || value.inherits(JSUint32Array::info()))
+ return jsNontrivialString(exec, ASCIILiteral("array"));
+ if (value.inherits(JSFloat32Array::info()) || value.inherits(JSFloat64Array::info()))
+ return jsNontrivialString(exec, ASCIILiteral("array"));
+
+ return impl().type(exec, value);
+}
+
+JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
+{
+ if (exec->argumentCount() < 1)
+ return jsUndefined();
+
+ JSValue value = exec->uncheckedArgument(0);
+ if (!value.asCell()->inherits(JSFunction::info()))
+ return jsUndefined();
+
+ JSFunction* function = jsCast<JSFunction*>(value);
+ const SourceCode* sourceCode = function->sourceCode();
+ if (!sourceCode)
+ return jsUndefined();
+
+ int lineNumber = sourceCode->firstLine();
+ if (lineNumber)
+ lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
+
+ String scriptID = String::number(sourceCode->provider()->asID());
+ JSObject* location = constructEmptyObject(exec);
+ location->putDirect(exec->vm(), Identifier(exec, "lineNumber"), jsNumber(lineNumber));
+ location->putDirect(exec->vm(), Identifier(exec, "scriptId"), jsString(exec, scriptID));
+
+ JSObject* result = constructEmptyObject(exec);
+ result->putDirect(exec->vm(), Identifier(exec, "location"), location);
+
+ String name = function->name(exec);
+ if (!name.isEmpty())
+ result->putDirect(exec->vm(), Identifier(exec, "name"), jsString(exec, name));
+
+ String displayName = function->displayName(exec);
+ if (!displayName.isEmpty())
+ result->putDirect(exec->vm(), Identifier(exec, "displayName"), jsString(exec, displayName));
+
+ // FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
+ // <https://webkit.org/b/87192> [JSC] expose function (closure) inner context to debugger
+
+ return result;
+}
+
+JSValue JSInjectedScriptHost::getInternalProperties(ExecState*)
+{
+ // FIXME: <https://webkit.org/b/94533> [JSC] expose object inner properties to debugger
+ return jsUndefined();
+}
+
+JSValue toJS(ExecState* exec, JSGlobalObject* globalObject, InjectedScriptHost* impl)
+{
+ if (!impl)
+ return jsNull();
+
+ JSObject* prototype = JSInjectedScriptHost::createPrototype(exec->vm(), globalObject);
+ Structure* structure = JSInjectedScriptHost::createStructure(exec->vm(), globalObject, prototype);
+ JSInjectedScriptHost* injectedScriptHost = JSInjectedScriptHost::create(exec->vm(), structure, impl);
+
+ return injectedScriptHost;
+}
+
+JSInjectedScriptHost* toJSInjectedScriptHost(JSValue value)
+{
+ return value.inherits(JSInjectedScriptHost::info()) ? jsCast<JSInjectedScriptHost*>(value) : nullptr;
+}
+
+} // namespace Inspector
+
+#endif // ENABLE(INSPECTOR)