Title: [199939] trunk
Revision
199939
Author
commit-qu...@webkit.org
Date
2016-04-22 17:40:43 -0700 (Fri, 22 Apr 2016)

Log Message

Web Inspector: Source directives lost when using Function constructor repeatedly
https://bugs.webkit.org/show_bug.cgi?id=156863
<rdar://problem/25861064>

Patch by Joseph Pecoraro <pecor...@apple.com> on 2016-04-22
Reviewed by Geoffrey Garen.

Source/_javascript_Core:

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.

LayoutTests:

* inspector/debugger/sourceURL-repeated-identical-executions-expected.txt: Added.
* inspector/debugger/sourceURL-repeated-identical-executions.html: Added.

Modified Paths

Added Paths

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"
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to