Diff
Modified: trunk/LayoutTests/ChangeLog (199938 => 199939)
--- trunk/LayoutTests/ChangeLog 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/LayoutTests/ChangeLog 2016-04-23 00:40:43 UTC (rev 199939)
@@ -1,3 +1,14 @@
+2016-04-22 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Source directives lost when using Function constructor repeatedly
+ https://bugs.webkit.org/show_bug.cgi?id=156863
+ <rdar://problem/25861064>
+
+ Reviewed by Geoffrey Garen.
+
+ * inspector/debugger/sourceURL-repeated-identical-executions-expected.txt: Added.
+ * inspector/debugger/sourceURL-repeated-identical-executions.html: Added.
+
2016-04-22 Mark Lam <mark....@apple.com>
_javascript_ jit bug affecting Google Maps.
Added: trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions-expected.txt (0 => 199939)
--- trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions-expected.txt 2016-04-23 00:40:43 UTC (rev 199939)
@@ -0,0 +1,13 @@
+Tests for the Debugger.scriptParsed messages for identical content should have source directives each time.
+
+
+== Running test suite: Debugger.scriptParsed.sourceURLRepeatedIdenticalExecutions
+-- Running test case: CheckFunctionConstructorMultipleTimes
+PASS: Should see 3 Scripts with sourceURL
+
+-- Running test case: CheckProgramMultipleTimes
+PASS: Should see 3 Scripts with sourceURL
+
+-- Running test case: CheckEvalMultipleTimes
+PASS: Should see 3 Scripts with sourceURL
+
Added: trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions.html (0 => 199939)
--- trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions.html (rev 0)
+++ trunk/LayoutTests/inspector/debugger/sourceURL-repeated-identical-executions.html 2016-04-23 00:40:43 UTC (rev 199939)
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+function triggerFunctionConstructorMultipleTimes() {
+ let sum = 0;
+ sum += Function("\n//# sourceURL=test-Function-constructor.js\nreturn 1+1")();
+ sum += Function("\n//# sourceURL=test-Function-constructor.js\nreturn 1+1")();
+ sum += Function("\n//# sourceURL=test-Function-constructor.js\nreturn 1+1")();
+ return sum;
+}
+
+function triggerProgramMultipleTimes() {
+ for (let i = 0; i < 3; ++i) {
+ let script = document.createElement("script");
+ script.text = "\n//# sourceURL=test-program.js\n1+1";
+ document.head.appendChild(script);
+ }
+}
+
+function triggerEvalMultipleTimes() {
+ let sum = 0;
+ sum += eval("\n//# sourceURL=test-eval.js\n1+1");
+ sum += eval("\n//# sourceURL=test-eval.js\n1+1");
+ sum += eval("\n//# sourceURL=test-eval.js\n1+1");
+ return sum;
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("Debugger.scriptParsed.sourceURLRepeatedIdenticalExecutions");
+
+ // Disable breakpoints to ensure we do not avoid the CodeCache.
+ DebuggerAgent.setBreakpointsActive(false);
+
+ suite.addTestCase({
+ name: "CheckFunctionConstructorMultipleTimes",
+ description: "Trigger multiple Function constructor calls with the same source and expect multiple Scripts added with sourceURLs.",
+ test: (resolve, reject) => {
+ let seen = 0;
+ WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, (event) => {
+ if (event.data.script.sourceURL === "test-Function-constructor.js")
+ seen++;
+ });
+ InspectorTest.evaluateInPage("triggerFunctionConstructorMultipleTimes()", () => {
+ InspectorTest.expectThat(seen === 3, "Should see 3 Scripts with sourceURL");
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "CheckProgramMultipleTimes",
+ description: "Trigger multiple program executions with the same source and expect multiple Scripts added with sourceURLs.",
+ test: (resolve, reject) => {
+ let seen = 0;
+ WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, (event) => {
+ if (event.data.script.sourceURL === "test-program.js")
+ seen++;
+ });
+ InspectorTest.evaluateInPage("triggerProgramMultipleTimes()", () => {
+ InspectorTest.expectThat(seen === 3, "Should see 3 Scripts with sourceURL");
+ resolve();
+ });
+ }
+ });
+
+ suite.addTestCase({
+ name: "CheckEvalMultipleTimes",
+ description: "Trigger eval with the same source and expect multiple Scripts added with sourceURLs.",
+ test: (resolve, reject) => {
+ let seen = 0;
+ WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, (event) => {
+ if (event.data.script.sourceURL === "test-eval.js")
+ seen++;
+ });
+ InspectorTest.evaluateInPage("triggerEvalMultipleTimes()", () => {
+ InspectorTest.expectThat(seen === 3, "Should see 3 Scripts with sourceURL");
+ resolve();
+ });
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+<p>Tests for the Debugger.scriptParsed messages for identical content should have source directives each time.</p>
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (199938 => 199939)
--- trunk/Source/_javascript_Core/ChangeLog 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-04-23 00:40:43 UTC (rev 199939)
@@ -1,3 +1,36 @@
+2016-04-22 Joseph Pecoraro <pecor...@apple.com>
+
+ Web Inspector: Source directives lost when using Function constructor repeatedly
+ https://bugs.webkit.org/show_bug.cgi?id=156863
+ <rdar://problem/25861064>
+
+ Reviewed by Geoffrey Garen.
+
+ Source directives (sourceURL and sourceMappingURL) are normally accessed through
+ the SourceProvider and normally set when the script is parsed. However, when a
+ CodeCache lookup skips parsing, the new SourceProvider never gets the directives
+ (sourceURL/sourceMappingURL). This patch stores the directives on the UnlinkedCodeBlock
+ and UnlinkedFunctionExecutable when entering the cache, and copies to the new providers
+ when the cache is used.
+
+ * bytecode/UnlinkedCodeBlock.h:
+ (JSC::UnlinkedCodeBlock::sourceURLDirective):
+ (JSC::UnlinkedCodeBlock::sourceMappingURLDirective):
+ (JSC::UnlinkedCodeBlock::setSourceURLDirective):
+ (JSC::UnlinkedCodeBlock::setSourceMappingURLDirective):
+ * bytecode/UnlinkedFunctionExecutable.h:
+ * parser/SourceProvider.h:
+ * runtime/CodeCache.cpp:
+ (JSC::CodeCache::getGlobalCodeBlock):
+ (JSC::CodeCache::getFunctionExecutableFromGlobalCode):
+ * runtime/CodeCache.h:
+ Store directives on the unlinked code block / executable when adding
+ to the cache, so they can be used to update new providers when the
+ cache gets used.
+
+ * runtime/JSGlobalObject.cpp:
+ Add needed header after CodeCache header cleanup.
+
2016-04-22 Mark Lam <mark....@apple.com>
_javascript_ jit bug affecting Google Maps.
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h (199938 => 199939)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedCodeBlock.h 2016-04-23 00:40:43 UTC (rev 199939)
@@ -339,6 +339,11 @@
m_endColumn = endColumn;
}
+ const String& sourceURLDirective() const { return m_sourceURLDirective; }
+ const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; }
+ void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; }
+ void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; }
+
CodeFeatures codeFeatures() const { return m_features; }
bool hasCapturedVariables() const { return m_hasCapturedVariables; }
unsigned firstLine() const { return m_firstLine; }
@@ -390,6 +395,9 @@
VirtualRegister m_scopeRegister;
VirtualRegister m_globalObjectRegister;
+ String m_sourceURLDirective;
+ String m_sourceMappingURLDirective;
+
unsigned m_usesEval : 1;
unsigned m_isStrictMode : 1;
unsigned m_isConstructor : 1;
Modified: trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h (199938 => 199939)
--- trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/bytecode/UnlinkedFunctionExecutable.h 2016-04-23 00:40:43 UTC (rev 199939)
@@ -136,7 +136,12 @@
bool isArrowFunction() const { return parseMode() == SourceParseMode::ArrowFunctionMode; }
JSC::DerivedContextType derivedContextType() const {return static_cast<JSC::DerivedContextType>(m_derivedContextType); }
-
+
+ const String& sourceURLDirective() const { return m_sourceURLDirective; }
+ const String& sourceMappingURLDirective() const { return m_sourceMappingURLDirective; }
+ void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; }
+ void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; }
+
private:
UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&, JSC::DerivedContextType);
@@ -171,6 +176,9 @@
RefPtr<SourceProvider> m_sourceOverride;
SourceCode m_classSource;
+ String m_sourceURLDirective;
+ String m_sourceMappingURLDirective;
+
VariableEnvironment m_parentScopeTDZVariables;
protected:
Modified: trunk/Source/_javascript_Core/parser/SourceProvider.h (199938 => 199939)
--- trunk/Source/_javascript_Core/parser/SourceProvider.h 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/parser/SourceProvider.h 2016-04-23 00:40:43 UTC (rev 199939)
@@ -65,12 +65,10 @@
bool isValid() const { return m_validated; }
void setValid() { m_validated = true; }
- private:
- template <typename T> friend class Parser;
-
void setSourceURLDirective(const String& sourceURL) { m_sourceURLDirective = sourceURL; }
void setSourceMappingURLDirective(const String& sourceMappingURL) { m_sourceMappingURLDirective = sourceMappingURL; }
+ private:
JS_EXPORT_PRIVATE void getID();
String m_url;
Modified: trunk/Source/_javascript_Core/runtime/CodeCache.cpp (199938 => 199939)
--- trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.cpp 2016-04-23 00:40:43 UTC (rev 199939)
@@ -24,12 +24,9 @@
*/
#include "config.h"
-
#include "CodeCache.h"
#include "BytecodeGenerator.h"
-#include "CodeSpecializationKind.h"
-#include "ExecutableInfo.h"
#include "JSCInlines.h"
#include "Parser.h"
#include "StrongInlines.h"
@@ -99,6 +96,8 @@
bool endColumnIsOnStartLine = !lineCount;
unsigned endColumn = unlinkedCodeBlock->endColumn() + (endColumnIsOnStartLine ? startColumn : 1);
executable->recordParse(unlinkedCodeBlock->codeFeatures(), unlinkedCodeBlock->hasCapturedVariables(), firstLine, firstLine + lineCount, startColumn, endColumn);
+ source.provider()->setSourceURLDirective(unlinkedCodeBlock->sourceURLDirective());
+ source.provider()->setSourceMappingURLDirective(unlinkedCodeBlock->sourceMappingURLDirective());
return unlinkedCodeBlock;
}
typedef typename CacheTypes<UnlinkedCodeBlockType>::RootNode RootNode;
@@ -118,6 +117,8 @@
UnlinkedCodeBlockType* unlinkedCodeBlock = UnlinkedCodeBlockType::create(&vm, executable->executableInfo());
unlinkedCodeBlock->recordParse(rootNode->features(), rootNode->hasCapturedVariables(), rootNode->firstLine() - source.firstLine(), lineCount, unlinkedEndColumn);
+ unlinkedCodeBlock->setSourceURLDirective(source.provider()->sourceURL());
+ unlinkedCodeBlock->setSourceMappingURLDirective(source.provider()->sourceMappingURL());
error = BytecodeGenerator::generate(vm, rootNode.get(), unlinkedCodeBlock, debuggerMode, profilerMode, variablesUnderTDZ);
@@ -156,8 +157,12 @@
JSParserBuiltinMode::NotBuiltin,
JSParserStrictMode::NotStrict);
SourceCodeValue* cache = m_sourceCode.findCacheAndUpdateAge(key);
- if (cache)
- return jsCast<UnlinkedFunctionExecutable*>(cache->cell.get());
+ if (cache) {
+ UnlinkedFunctionExecutable* executable = jsCast<UnlinkedFunctionExecutable*>(cache->cell.get());
+ source.provider()->setSourceURLDirective(executable->sourceURLDirective());
+ source.provider()->setSourceMappingURLDirective(executable->sourceMappingURLDirective());
+ return executable;
+ }
JSTextPosition positionBeforeLastNewline;
std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
@@ -193,6 +198,9 @@
VariableEnvironment emptyTDZVariables;
UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, UnlinkedNormalFunction, ConstructAbility::CanConstruct, emptyTDZVariables, DerivedContextType::None);
+ functionExecutable->setSourceURLDirective(source.provider()->sourceURL());
+ functionExecutable->setSourceMappingURLDirective(source.provider()->sourceMappingURL());
+
m_sourceCode.addCache(key, SourceCodeValue(vm, functionExecutable, m_sourceCode.age()));
return functionExecutable;
}
Modified: trunk/Source/_javascript_Core/runtime/CodeCache.h (199938 => 199939)
--- trunk/Source/_javascript_Core/runtime/CodeCache.h 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/runtime/CodeCache.h 2016-04-23 00:40:43 UTC (rev 199939)
@@ -26,7 +26,6 @@
#ifndef CodeCache_h
#define CodeCache_h
-#include "CodeSpecializationKind.h"
#include "ExecutableInfo.h"
#include "ParserModes.h"
#include "SourceCode.h"
@@ -34,28 +33,22 @@
#include "Strong.h"
#include <wtf/CurrentTime.h>
#include <wtf/Forward.h>
-#include <wtf/RandomNumber.h>
-#include <wtf/WeakRandom.h>
#include <wtf/text/WTFString.h>
namespace JSC {
class EvalExecutable;
-class FunctionMetadataNode;
class Identifier;
-class JSScope;
+class ModuleProgramExecutable;
class ParserError;
class ProgramExecutable;
-class ModuleProgramExecutable;
+class SourceCode;
class UnlinkedCodeBlock;
class UnlinkedEvalCodeBlock;
-class UnlinkedModuleProgramCodeBlock;
-class UnlinkedFunctionCodeBlock;
class UnlinkedFunctionExecutable;
+class UnlinkedModuleProgramCodeBlock;
class UnlinkedProgramCodeBlock;
class VM;
-class SourceCode;
-class SourceProvider;
class VariableEnvironment;
struct SourceCodeValue {
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (199938 => 199939)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-04-23 00:07:44 UTC (rev 199938)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2016-04-23 00:40:43 UTC (rev 199939)
@@ -154,6 +154,7 @@
#include "WeakMapPrototype.h"
#include "WeakSetConstructor.h"
#include "WeakSetPrototype.h"
+#include <wtf/RandomNumber.h>
#if ENABLE(INTL)
#include "IntlObject.h"