<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164007] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164007">164007</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2014-02-12 19:34:33 -0800 (Wed, 12 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Replay: capture and replay nondeterminism of Date.now() and Math.random()
https://bugs.webkit.org/show_bug.cgi?id=128633

Reviewed by Filip Pizlo.

Upstream the only two sources of script-visible nondeterminism in JavaScriptCore.

The random seed for WeakRandom is memoized when the owning JSGlobalObject is
constructed. It is deterministically initialized during replay before any
scripts execute with the global object.

The implementations of `Date.now()` and `new Date()` eventually obtain the
current time from jsCurrentTime(). When capturing, we save return values of
jsCurrentTime() into the recording. When replaying, we use memoized values from
the recording instead of obtaining values from the platform-specific currentTime()
implementation. No other code calls jsCurrentTime().

* DerivedSources.make: Add rules to make JSReplayInputs.h from JSInputs.json.
* JavaScriptCore.xcodeproj/project.pbxproj:
* replay/JSInputs.json: Added. Includes specifications for replay inputs
&quot;GetCurrentTime&quot; and &quot;SetRandomSeed&quot;. Tests will be added for both input
cases once sufficient replay machinery has been added.

* replay/NondeterministicInput.h: NondeterministicInput should not have
been marked 'final'.

* runtime/DateConstructor.cpp:
(JSC::deterministicCurrentTime): Added. Load or store the current time depending
on what kind of InputCursor is attached to the JSGlobalObject.

(JSC::constructDate): Use deterministicCurrentTime().
(JSC::dateNow): Use deterministicCurrentTime().
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::setInputCursor): When setting a non-empty input cursor,
immediately store or load the &quot;SetRandomSeed&quot; input and initialize WeakRandom's
random seed with it. The input cursor (and thus random seed) must be set before
any scripts are evaluated with this JSGlobalObject.

* runtime/WeakRandom.h:
(JSC::WeakRandom::WeakRandom): Add JSGlobalObject as a friend class.
(JSC::WeakRandom::initializeSeed): Extract the seed initialization into a
separate method so it can be called outside of the JSGlobalObject constructor.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreDerivedSourcesmake">trunk/Source/JavaScriptCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorereplayNondeterministicInputh">trunk/Source/JavaScriptCore/replay/NondeterministicInput.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeDateConstructorcpp">trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeWeakRandomh">trunk/Source/JavaScriptCore/runtime/WeakRandom.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorereplayJSInputsjson">trunk/Source/JavaScriptCore/replay/JSInputs.json</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -1,3 +1,48 @@
</span><ins>+2014-02-12  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Replay: capture and replay nondeterminism of Date.now() and Math.random()
+        https://bugs.webkit.org/show_bug.cgi?id=128633
+
+        Reviewed by Filip Pizlo.
+
+        Upstream the only two sources of script-visible nondeterminism in JavaScriptCore.
+
+        The random seed for WeakRandom is memoized when the owning JSGlobalObject is
+        constructed. It is deterministically initialized during replay before any
+        scripts execute with the global object.
+
+        The implementations of `Date.now()` and `new Date()` eventually obtain the
+        current time from jsCurrentTime(). When capturing, we save return values of
+        jsCurrentTime() into the recording. When replaying, we use memoized values from
+        the recording instead of obtaining values from the platform-specific currentTime()
+        implementation. No other code calls jsCurrentTime().
+
+        * DerivedSources.make: Add rules to make JSReplayInputs.h from JSInputs.json.
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * replay/JSInputs.json: Added. Includes specifications for replay inputs
+        &quot;GetCurrentTime&quot; and &quot;SetRandomSeed&quot;. Tests will be added for both input
+        cases once sufficient replay machinery has been added.
+
+        * replay/NondeterministicInput.h: NondeterministicInput should not have
+        been marked 'final'.
+
+        * runtime/DateConstructor.cpp:
+        (JSC::deterministicCurrentTime): Added. Load or store the current time depending
+        on what kind of InputCursor is attached to the JSGlobalObject.
+
+        (JSC::constructDate): Use deterministicCurrentTime().
+        (JSC::dateNow): Use deterministicCurrentTime().
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::setInputCursor): When setting a non-empty input cursor,
+        immediately store or load the &quot;SetRandomSeed&quot; input and initialize WeakRandom's
+        random seed with it. The input cursor (and thus random seed) must be set before
+        any scripts are evaluated with this JSGlobalObject.
+
+        * runtime/WeakRandom.h:
+        (JSC::WeakRandom::WeakRandom): Add JSGlobalObject as a friend class.
+        (JSC::WeakRandom::initializeSeed): Extract the seed initialization into a
+        separate method so it can be called outside of the JSGlobalObject constructor.
+
</ins><span class="cx"> 2014-02-12  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Cleanup JavaScriptCore/inspector
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/DerivedSources.make (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/DerivedSources.make        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/DerivedSources.make        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -101,15 +101,25 @@
</span><span class="cx">     $(JavaScriptCore)/inspector/protocol/Runtime.json \
</span><span class="cx"> #
</span><span class="cx"> 
</span><ins>+INPUT_GENERATOR_SCRIPTS = \
+    $(JavaScriptCore)/replay/scripts/CodeGeneratorReplayInputs.py \
+    $(JavaScriptCore)/replay/scripts/CodeGeneratorReplayInputsTemplates.py \
+#
+
</ins><span class="cx"> INSPECTOR_GENERATOR_SCRIPTS = \
</span><span class="cx">         $(JavaScriptCore)/inspector/scripts/CodeGeneratorInspector.py \
</span><span class="cx">         $(JavaScriptCore)/inspector/scripts/CodeGeneratorInspectorStrings.py \
</span><span class="cx"> #
</span><span class="cx"> 
</span><ins>+INPUT_GENERATOR_SPECIFICATIONS = \
+    $(JavaScriptCore)/replay/JSInputs.json \
+#
+
</ins><span class="cx"> all : \
</span><span class="cx">     InspectorJS.json \
</span><span class="cx">     InspectorJSFrontendDispatchers.h \
</span><span class="cx">     InjectedScriptSource.h \
</span><ins>+        JSReplayInputs.h \
</ins><span class="cx"> #
</span><span class="cx"> 
</span><span class="cx"> InspectorJS.json : inspector/scripts/generate-combined-inspector-json.py $(INSPECTOR_DOMAINS)
</span><span class="lines">@@ -123,3 +133,9 @@
</span><span class="cx">         python $(JavaScriptCore)/inspector/scripts/jsmin.py &lt; $(JavaScriptCore)/inspector/InjectedScriptSource.js &gt; ./InjectedScriptSource.min.js
</span><span class="cx">         perl $(JavaScriptCore)/inspector/scripts/xxd.pl InjectedScriptSource_js ./InjectedScriptSource.min.js InjectedScriptSource.h
</span><span class="cx">         rm -f ./InjectedScriptSource.min.js
</span><ins>+
+# Web Replay inputs generator
+
+JSReplayInputs.h : $(INPUT_GENERATOR_SPECIFICATIONS) $(INPUT_GENERATOR_SCRIPTS)
+        python $(JavaScriptCore)/replay/scripts/CodeGeneratorReplayInputs.py --outputDir . --framework JavaScriptCore $(INPUT_GENERATOR_SPECIFICATIONS)
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -930,6 +930,8 @@
</span><span class="cx">                 969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 978801401471AD920041B016 /* JSDateMath.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */; };
</span><span class="cx">                 978801411471AD920041B016 /* JSDateMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 9788FC231471AD0C0068CE2D /* JSDateMath.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9928FF3918AC4AEC00B8CF12 /* JSReplayInputs.cpp */; };
+                9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */ = {isa = PBXBuildFile; fileRef = 9928FF3A18AC4AEC00B8CF12 /* JSReplayInputs.h */; };
</ins><span class="cx">                 99E45A2418A1B2590026D88F /* EmptyInputCursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A1F18A1B2590026D88F /* EmptyInputCursor.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 99E45A2518A1B2590026D88F /* EncodedValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 99E45A2018A1B2590026D88F /* EncodedValue.cpp */; };
</span><span class="cx">                 99E45A2618A1B2590026D88F /* EncodedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 99E45A2118A1B2590026D88F /* EncodedValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2409,6 +2411,9 @@
</span><span class="cx">                 969A09220ED1E09C00F1F681 /* Completion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Completion.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9788FC221471AD0C0068CE2D /* JSDateMath.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSDateMath.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 9788FC231471AD0C0068CE2D /* JSDateMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDateMath.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                9928FF3918AC4AEC00B8CF12 /* JSReplayInputs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSReplayInputs.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                9928FF3A18AC4AEC00B8CF12 /* JSReplayInputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSReplayInputs.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                9928FF3D18AC4B1C00B8CF12 /* JSInputs.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = JSInputs.json; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 99E45A1D18A1B1E70026D88F /* CodeGeneratorReplayInputs.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = CodeGeneratorReplayInputs.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 99E45A1E18A1B1E70026D88F /* CodeGeneratorReplayInputsTemplates.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = CodeGeneratorReplayInputsTemplates.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 99E45A1F18A1B2590026D88F /* EmptyInputCursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmptyInputCursor.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3615,6 +3620,8 @@
</span><span class="cx">                 650FDF8D09D0FCA700769E54 /* Derived Sources */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                9928FF3918AC4AEC00B8CF12 /* JSReplayInputs.cpp */,
+                                9928FF3A18AC4AEC00B8CF12 /* JSReplayInputs.h */,
</ins><span class="cx">                                 A7D801A61880D6A80026C39B /* JSCBuiltins.cpp */,
</span><span class="cx">                                 A7D801A71880D6A80026C39B /* JSCBuiltins.h */,
</span><span class="cx">                                 BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */,
</span><span class="lines">@@ -4576,6 +4583,7 @@
</span><span class="cx">                                 99E45A1F18A1B2590026D88F /* EmptyInputCursor.h */,
</span><span class="cx">                                 99E45A2218A1B2590026D88F /* InputCursor.h */,
</span><span class="cx">                                 99E45A2318A1B2590026D88F /* NondeterministicInput.h */,
</span><ins>+                                9928FF3D18AC4B1C00B8CF12 /* JSInputs.json */,
</ins><span class="cx">                         );
</span><span class="cx">                         path = replay;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -4965,6 +4973,7 @@
</span><span class="cx">                                 A78A9779179738B8009DF744 /* DFGJITFinalizer.h in Headers */,
</span><span class="cx">                                 0FC97F4018202119002C9B26 /* DFGJumpReplacement.h in Headers */,
</span><span class="cx">                                 A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */,
</span><ins>+                                9928FF3C18AC4AEC00B8CF12 /* JSReplayInputs.h in Headers */,
</ins><span class="cx">                                 A7D9A29817A0BC7400EE2618 /* DFGLICMPhase.h in Headers */,
</span><span class="cx">                                 A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
</span><span class="cx">                                 0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
</span><span class="lines">@@ -5993,6 +6002,7 @@
</span><span class="cx">                                 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */,
</span><span class="cx">                                 1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
</span><span class="cx">                                 0F0B83B014BCF71600885B4F /* CallLinkInfo.cpp in Sources */,
</span><ins>+                                9928FF3B18AC4AEC00B8CF12 /* JSReplayInputs.cpp in Sources */,
</ins><span class="cx">                                 A513E5B7185B8BD3007E95AD /* InjectedScript.cpp in Sources */,
</span><span class="cx">                                 0F5A6283188C98D40072C9DF /* FTLValueRange.cpp in Sources */,
</span><span class="cx">                                 0F93329D14CA7DC30085F3C6 /* CallLinkStatus.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorereplayJSInputsjson"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/replay/JSInputs.json (0 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/replay/JSInputs.json                                (rev 0)
+++ trunk/Source/JavaScriptCore/replay/JSInputs.json        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+{
+    &quot;types&quot;: {
+        &quot;Global&quot;: [
+            { &quot;name&quot;: &quot;double&quot;, &quot;mode&quot;: &quot;SCALAR&quot; },
+            { &quot;name&quot;: &quot;uint64_t&quot;, &quot;mode&quot;: &quot;SCALAR&quot; }
+        ]
+    },
+
+    &quot;inputs&quot;: [
+        {
+            &quot;name&quot;: &quot;GetCurrentTime&quot;,
+            &quot;description&quot;: &quot;Supplies the system time to Date.now() and new Date().&quot;,
+            &quot;queue&quot;: &quot;SCRIPT_MEMOIZED&quot;,
+            &quot;members&quot;: [
+                { &quot;name&quot;: &quot;currentTime&quot;, &quot;type&quot;: &quot;double&quot; }
+            ]
+        },
+        {
+            &quot;name&quot;: &quot;SetRandomSeed&quot;,
+            &quot;description&quot;: &quot;Sets the PRNG seed used by Math.random().&quot;,
+            &quot;queue&quot;: &quot;SCRIPT_MEMOIZED&quot;,
+            &quot;members&quot;: [
+                { &quot;name&quot;: &quot;randomSeed&quot;, &quot;type&quot;: &quot;uint64_t&quot; }
+            ]
+        }
+    ]
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorereplayNondeterministicInputh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/replay/NondeterministicInput.h (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/replay/NondeterministicInput.h        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/replay/NondeterministicInput.h        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename InputType&gt;
</span><del>-class NondeterministicInput final : public NondeterministicInputBase {
</del><ins>+class NondeterministicInput : public NondeterministicInputBase {
</ins><span class="cx">     virtual const AtomicString&amp; type() const override
</span><span class="cx">     {
</span><span class="cx">         return InputTraits&lt;InputType&gt;::type();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeDateConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/runtime/DateConstructor.cpp        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -36,6 +36,11 @@
</span><span class="cx"> #include &lt;time.h&gt;
</span><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEB_REPLAY)
+#include &quot;InputCursor.h&quot;
+#include &quot;JSReplayInputs.h&quot;
+#endif
+
</ins><span class="cx"> #if OS(WINCE)
</span><span class="cx"> extern &quot;C&quot; time_t time(time_t* timer); // Provided by libce.
</span><span class="cx"> #endif
</span><span class="lines">@@ -72,6 +77,28 @@
</span><span class="cx"> @end
</span><span class="cx"> */
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEB_REPLAY)
+static double deterministicCurrentTime(JSGlobalObject* globalObject)
+{
+    double currentTime = jsCurrentTime();
+    InputCursor&amp; cursor = globalObject-&gt;inputCursor();
+    if (cursor.isCapturing())
+        cursor.appendInput&lt;GetCurrentTime&gt;(currentTime);
+
+    if (cursor.isReplaying()) {
+        if (GetCurrentTime* input = cursor.fetchInput&lt;GetCurrentTime&gt;())
+            currentTime = input-&gt;currentTime();
+    }
+    return currentTime;
+}
+#endif
+
+#if ENABLE(WEB_REPLAY)
+#define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (b)
+#else
+#define NORMAL_OR_DETERMINISTIC_FUNCTION(a, b) (a)
+#endif
+
</ins><span class="cx"> STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(DateConstructor);
</span><span class="cx"> 
</span><span class="cx"> DateConstructor::DateConstructor(VM&amp; vm, Structure* structure)
</span><span class="lines">@@ -100,7 +127,7 @@
</span><span class="cx">     double value;
</span><span class="cx"> 
</span><span class="cx">     if (numArgs == 0) // new Date() ECMA 15.9.3.3
</span><del>-        value = jsCurrentTime();
</del><ins>+        value = NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(globalObject));
</ins><span class="cx">     else if (numArgs == 1) {
</span><span class="cx">         if (args.at(0).inherits(DateInstance::info()))
</span><span class="cx">             value = asDateInstance(args.at(0))-&gt;internalNumber();
</span><span class="lines">@@ -179,9 +206,13 @@
</span><span class="cx">     return JSValue::encode(jsNumber(parseDate(exec-&gt;vm(), exec-&gt;argument(0).toString(exec)-&gt;value(exec))));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static EncodedJSValue JSC_HOST_CALL dateNow(ExecState*)
</del><ins>+static EncodedJSValue JSC_HOST_CALL dateNow(ExecState* exec)
</ins><span class="cx"> {
</span><del>-    return JSValue::encode(jsNumber(jsCurrentTime()));
</del><ins>+#if !ENABLE(WEB_REPLAY)
+    UNUSED_PARAM(exec);
+#endif
+
+    return JSValue::encode(jsNumber(NORMAL_OR_DETERMINISTIC_FUNCTION(jsCurrentTime(), deterministicCurrentTime(exec-&gt;lexicalGlobalObject()))));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL dateUTC(ExecState* exec) 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -129,6 +129,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEB_REPLAY)
</span><span class="cx"> #include &quot;EmptyInputCursor.h&quot;
</span><ins>+#include &quot;JSReplayInputs.h&quot;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSGlobalObject.lut.h&quot;
</span><span class="lines">@@ -786,6 +787,17 @@
</span><span class="cx"> void JSGlobalObject::setInputCursor(PassRefPtr&lt;InputCursor&gt; prpCursor)
</span><span class="cx"> {
</span><span class="cx">     m_inputCursor = prpCursor;
</span><ins>+    ASSERT(m_inputCursor);
+
+    InputCursor&amp; cursor = inputCursor();
+    // Save or set the random seed. This performed here rather than the constructor
+    // to avoid threading the input cursor through all the abstraction layers.
+    if (cursor.isCapturing())
+        cursor.appendInput&lt;SetRandomSeed&gt;(m_weakRandom.seedUnsafe());
+    else if (cursor.isReplaying()) {
+        if (SetRandomSeed* input = cursor.fetchInput&lt;SetRandomSeed&gt;())
+            m_weakRandom.initializeSeed(input-&gt;randomSeed());
+    }
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeWeakRandomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/WeakRandom.h (164006 => 164007)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/WeakRandom.h        2014-02-13 03:02:53 UTC (rev 164006)
+++ trunk/Source/JavaScriptCore/runtime/WeakRandom.h        2014-02-13 03:34:33 UTC (rev 164007)
</span><span class="lines">@@ -56,11 +56,11 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class WeakRandom {
</span><ins>+friend class JSGlobalObject; // For access to initializeSeed() during replay.
</ins><span class="cx"> public:
</span><span class="cx">     WeakRandom(unsigned seed)
</span><del>-        : m_low(seed ^ 0x49616E42)
-        , m_high(seed)
</del><span class="cx">     {
</span><ins>+        initializeSeed(seed);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     // Returns the seed provided that you've never called get() or getUint32().
</span><span class="lines">@@ -85,6 +85,12 @@
</span><span class="cx">         return m_high;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void initializeSeed(unsigned seed)
+    {
+        m_low = seed ^ 0x49616E42;
+        m_high = seed;
+    }
+
</ins><span class="cx">     unsigned m_low;
</span><span class="cx">     unsigned m_high;
</span><span class="cx"> };
</span></span></pre>
</div>
</div>

</body>
</html>