<!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>[243278] trunk</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/243278">243278</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2019-03-20 22:43:08 -0700 (Wed, 20 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>DFG::AbstractValue::validateOSREntry is wrong when isHeapTop and the incoming value is Empty
https://bugs.webkit.org/show_bug.cgi?id=195721

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

There was a check in AbstractValue::validateOSREntry where it checked
if isHeapTop(), and if so, just returned true. However, this is wrong
if the value we're checking against is the empty value, since HeapTop
does not include the Empty value. Instead, this check should be
isBytecodeTop(), which does account for the empty value.

This patch also does a couple of other things:
- For our OSR entry AbstractValues, we were using HeapTop to mark
 a dead value. That is now changed to BytecodeTop. (The idea here
 is just to have validateOSREntry return early.)
- It wasn't obvious to me how I could make this fail in JS code.
 The symptom we'd end up seeing is something like a nullptr derefernece
 from forgetting to do a TDZ check. Instead, I've added a unit test.
 This unit test lives in a new test file: testdfg. testdfg is similar
 to testb3/testair/testapi.

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/SpeculatedType.h:
* dfg/DFGAbstractValue.h:
(JSC::DFG::AbstractValue::isBytecodeTop const):
(JSC::DFG::AbstractValue::validateOSREntryValue const):
* dfg/testdfg.cpp: Added.
(hiddenTruthBecauseNoReturnIsStupid):
(usage):
(JSC::DFG::testEmptyValueDoesNotValidateWithHeapTop):
(JSC::DFG::run):
(run):
(main):
* shell/CMakeLists.txt:

Tools:

* Scripts/run-javascriptcore-tests:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeArrayProfileh">trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSpeculatedTypeh">trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGJITCompilercpp">trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh">trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreshellCMakeListstxt">trunk/Source/JavaScriptCore/shell/CMakeLists.txt</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsScriptsrunjavascriptcoretests">trunk/Tools/Scripts/run-javascriptcore-tests</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoredfgtestdfgcpp">trunk/Source/JavaScriptCore/dfg/testdfg.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/ChangeLog       2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -1,5 +1,42 @@
</span><span class="cx"> 2019-03-20  Saam Barati  <sbarati@apple.com>
</span><span class="cx"> 
</span><ins>+        DFG::AbstractValue::validateOSREntry is wrong when isHeapTop and the incoming value is Empty
+        https://bugs.webkit.org/show_bug.cgi?id=195721
+
+        Reviewed by Filip Pizlo.
+
+        There was a check in AbstractValue::validateOSREntry where it checked
+        if isHeapTop(), and if so, just returned true. However, this is wrong
+        if the value we're checking against is the empty value, since HeapTop
+        does not include the Empty value. Instead, this check should be
+        isBytecodeTop(), which does account for the empty value.
+        
+        This patch also does a couple of other things:
+        - For our OSR entry AbstractValues, we were using HeapTop to mark
+         a dead value. That is now changed to BytecodeTop. (The idea here
+         is just to have validateOSREntry return early.)
+        - It wasn't obvious to me how I could make this fail in JS code.
+         The symptom we'd end up seeing is something like a nullptr derefernece
+         from forgetting to do a TDZ check. Instead, I've added a unit test.
+         This unit test lives in a new test file: testdfg. testdfg is similar
+         to testb3/testair/testapi.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/SpeculatedType.h:
+        * dfg/DFGAbstractValue.h:
+        (JSC::DFG::AbstractValue::isBytecodeTop const):
+        (JSC::DFG::AbstractValue::validateOSREntryValue const):
+        * dfg/testdfg.cpp: Added.
+        (hiddenTruthBecauseNoReturnIsStupid):
+        (usage):
+        (JSC::DFG::testEmptyValueDoesNotValidateWithHeapTop):
+        (JSC::DFG::run):
+        (run):
+        (main):
+        * shell/CMakeLists.txt:
+
+2019-03-20  Saam Barati  <sbarati@apple.com>
+
</ins><span class="cx">         typeOfDoubleSum is wrong for when NaN can be produced
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=196030
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj     2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -59,6 +59,7 @@
</span><span class="cx">                  buildPhases = (
</span><span class="cx">                  );
</span><span class="cx">                  dependencies = (
</span><ins>+                               52CD0F662242F5A3004A18A5 /* PBXTargetDependency */,
</ins><span class="cx">                           7954BE0D20B63348009BC83A /* PBXTargetDependency */,
</span><span class="cx">                          FE533CAF1F217EC60016A1FE /* PBXTargetDependency */,
</span><span class="cx">                          0F6183471C45F67A0072450B /* PBXTargetDependency */,
</span><span class="lines">@@ -884,6 +885,9 @@
</span><span class="cx">          52B311011975B4670080857C /* TypeLocationCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B311001975B4670080857C /* TypeLocationCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               52CD0F5D2242F569004A18A5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
+               52CD0F5E2242F569004A18A5 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
+               52CD0F682242F71C004A18A5 /* testdfg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52CD0F672242F71C004A18A5 /* testdfg.cpp */; };
</ins><span class="cx">           52D13091221CE176009C836C /* foo.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 52D1308F221CE03A009C836C /* foo.js */; };
</span><span class="cx">          52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */; };
</span><span class="cx">          530A66B91FA3E78B0026A545 /* UnifiedSource3-mm.mm in Sources */ = {isa = PBXBuildFile; fileRef = 530A66B11FA3E77A0026A545 /* UnifiedSource3-mm.mm */; };
</span><span class="lines">@@ -1925,6 +1929,13 @@
</span><span class="cx">                  remoteGlobalIDString = 65FB3F6609D11E9100F49DEB;
</span><span class="cx">                  remoteInfo = "Derived Sources";
</span><span class="cx">          };
</span><ins>+               52CD0F652242F5A3004A18A5 /* PBXContainerItemProxy */ = {
+                       isa = PBXContainerItemProxy;
+                       containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
+                       proxyType = 1;
+                       remoteGlobalIDString = 52CD0F592242F569004A18A5;
+                       remoteInfo = testdfg;
+               };
</ins><span class="cx">           53B4BD131F68C2AA00D2BEA3 /* PBXContainerItemProxy */ = {
</span><span class="cx">                  isa = PBXContainerItemProxy;
</span><span class="cx">                  containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
</span><span class="lines">@@ -3381,6 +3392,8 @@
</span><span class="cx">          52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = "<group>"; };
</span><span class="cx">          52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; };
</span><span class="cx">          52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
</span><ins>+               52CD0F642242F569004A18A5 /* testdfg */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testdfg; sourceTree = BUILT_PRODUCTS_DIR; };
+               52CD0F672242F71C004A18A5 /* testdfg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = testdfg.cpp; path = dfg/testdfg.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           52D1308F221CE03A009C836C /* foo.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = foo.js; sourceTree = "<group>"; };
</span><span class="cx">          52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyWrapperFunction.cpp; path = js/WebAssemblyWrapperFunction.cpp; sourceTree = "<group>"; };
</span><span class="cx">          52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyWrapperFunction.h; path = js/WebAssemblyWrapperFunction.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -5000,6 +5013,15 @@
</span><span class="cx">                  );
</span><span class="cx">                  runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">          };
</span><ins>+               52CD0F5C2242F569004A18A5 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               52CD0F5D2242F569004A18A5 /* Foundation.framework in Frameworks */,
+                               52CD0F5E2242F569004A18A5 /* JavaScriptCore.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
</ins><span class="cx">           651122FC14046A4C002B101D /* Frameworks */ = {
</span><span class="cx">                  isa = PBXFrameworksBuildPhase;
</span><span class="cx">                  buildActionMask = 2147483647;
</span><span class="lines">@@ -5068,6 +5090,7 @@
</span><span class="cx">                          79281BDC20B62B3E002E2A60 /* testmem */,
</span><span class="cx">                          6511230514046A4C002B101D /* testRegExp */,
</span><span class="cx">                          932F5BD90822A1C700736975 /* JavaScriptCore.framework */,
</span><ins>+                               52CD0F642242F569004A18A5 /* testdfg */,
</ins><span class="cx">                   );
</span><span class="cx">                  name = Products;
</span><span class="cx">                  sourceTree = "<group>";
</span><span class="lines">@@ -7646,6 +7669,7 @@
</span><span class="cx">                          0FDB2CE5174830A2007B3C1B /* DFGWorklist.cpp */,
</span><span class="cx">                          0FDB2CE6174830A2007B3C1B /* DFGWorklist.h */,
</span><span class="cx">                          0F1FB3951E1AF7DF00A9BE50 /* DFGWorklistInlines.h */,
</span><ins>+                               52CD0F672242F71C004A18A5 /* testdfg.cpp */,
</ins><span class="cx">                   );
</span><span class="cx">                  name = dfg;
</span><span class="cx">                  sourceTree = "<group>";
</span><span class="lines">@@ -10038,6 +10062,22 @@
</span><span class="cx">                  productReference = 14BD688E215191310050DAFF /* JSCLLIntSettingsExtractor */;
</span><span class="cx">                  productType = "com.apple.product-type.tool";
</span><span class="cx">          };
</span><ins>+               52CD0F592242F569004A18A5 /* testdfg */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 52CD0F5F2242F569004A18A5 /* Build configuration list for PBXNativeTarget "testdfg" */;
+                       buildPhases = (
+                               52CD0F5A2242F569004A18A5 /* Sources */,
+                               52CD0F5C2242F569004A18A5 /* Frameworks */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = testdfg;
+                       productName = testapi;
+                       productReference = 52CD0F642242F569004A18A5 /* testdfg */;
+                       productType = "com.apple.product-type.tool";
+               };
</ins><span class="cx">           651122F714046A4C002B101D /* testRegExp */ = {
</span><span class="cx">                  isa = PBXNativeTarget;
</span><span class="cx">                  buildConfigurationList = 6511230014046A4C002B101D /* Build configuration list for PBXNativeTarget "testRegExp" */;
</span><span class="lines">@@ -10184,6 +10224,7 @@
</span><span class="cx">                          FE533CA11F217DB30016A1FE /* testmasm */,
</span><span class="cx">                          79281BBD20B62B3E002E2A60 /* testmem */,
</span><span class="cx">                          5325BDBF21DFF2B100A0DEE1 /* Apply Configuration to XCFileLists */,
</span><ins>+                               52CD0F592242F569004A18A5 /* testdfg */,
</ins><span class="cx">                   );
</span><span class="cx">          };
</span><span class="cx"> /* End PBXProject section */
</span><span class="lines">@@ -10552,6 +10593,14 @@
</span><span class="cx">                  );
</span><span class="cx">                  runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">          };
</span><ins>+               52CD0F5A2242F569004A18A5 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               52CD0F682242F71C004A18A5 /* testdfg.cpp in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
</ins><span class="cx">           651122FA14046A4C002B101D /* Sources */ = {
</span><span class="cx">                  isa = PBXSourcesBuildPhase;
</span><span class="cx">                  buildActionMask = 2147483647;
</span><span class="lines">@@ -10802,6 +10851,11 @@
</span><span class="cx">                  target = 65FB3F6609D11E9100F49DEB /* Derived Sources */;
</span><span class="cx">                  targetProxy = 14D9D9D9218462B5009126C2 /* PBXContainerItemProxy */;
</span><span class="cx">          };
</span><ins>+               52CD0F662242F5A3004A18A5 /* PBXTargetDependency */ = {
+                       isa = PBXTargetDependency;
+                       target = 52CD0F592242F569004A18A5 /* testdfg */;
+                       targetProxy = 52CD0F652242F5A3004A18A5 /* PBXContainerItemProxy */;
+               };
</ins><span class="cx">           53B4BD141F68C2AA00D2BEA3 /* PBXTargetDependency */ = {
</span><span class="cx">                  isa = PBXTargetDependency;
</span><span class="cx">                  target = 53B4BD041F68AF8900D2BEA3 /* Generate Unified Sources */;
</span><span class="lines">@@ -11207,6 +11261,38 @@
</span><span class="cx">                  };
</span><span class="cx">                  name = Production;
</span><span class="cx">          };
</span><ins>+               52CD0F602242F569004A18A5 /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Debug;
+               };
+               52CD0F612242F569004A18A5 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Release;
+               };
+               52CD0F622242F569004A18A5 /* Profiling */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Profiling;
+               };
+               52CD0F632242F569004A18A5 /* Production */ = {
+                       isa = XCBuildConfiguration;
+                       baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
+                       buildSettings = {
+                               PRODUCT_NAME = "$(TARGET_NAME)";
+                       };
+                       name = Production;
+               };
</ins><span class="cx">           5325BDC021DFF2B200A0DEE1 /* Debug */ = {
</span><span class="cx">                  isa = XCBuildConfiguration;
</span><span class="cx">                  baseConfigurationReference = 1C9051430BA9E8A70081E9D0 /* JavaScriptCore.xcconfig */;
</span><span class="lines">@@ -11648,6 +11734,17 @@
</span><span class="cx">                  defaultConfigurationIsVisible = 0;
</span><span class="cx">                  defaultConfigurationName = Production;
</span><span class="cx">          };
</span><ins>+               52CD0F5F2242F569004A18A5 /* Build configuration list for PBXNativeTarget "testdfg" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               52CD0F602242F569004A18A5 /* Debug */,
+                               52CD0F612242F569004A18A5 /* Release */,
+                               52CD0F622242F569004A18A5 /* Profiling */,
+                               52CD0F632242F569004A18A5 /* Production */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Production;
+               };
</ins><span class="cx">           5325BDC421DFF2B200A0DEE1 /* Build configuration list for PBXAggregateTarget "Apply Configuration to XCFileLists" */ = {
</span><span class="cx">                  isa = XCConfigurationList;
</span><span class="cx">                  buildConfigurations = (
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeArrayProfileh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h      2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/bytecode/ArrayProfile.h 2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> const ArrayModes Float32ArrayMode = 1 << 28;
</span><span class="cx"> const ArrayModes Float64ArrayMode = 1 << 29;
</span><span class="cx"> 
</span><del>-extern const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView];
</del><ins>+JS_EXPORT_PRIVATE extern const ArrayModes typedArrayModes[NumberOfTypedArrayTypesExcludingDataView];
</ins><span class="cx"> 
</span><span class="cx"> constexpr ArrayModes asArrayModesIgnoringTypedArrays(IndexingType indexingMode)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSpeculatedTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h    2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/bytecode/SpeculatedType.h       2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -482,7 +482,7 @@
</span><span class="cx"> SpeculatedType speculationFromClassInfo(const ClassInfo*);
</span><span class="cx"> SpeculatedType speculationFromStructure(Structure*);
</span><span class="cx"> SpeculatedType speculationFromCell(JSCell*);
</span><del>-SpeculatedType speculationFromValue(JSValue);
</del><ins>+JS_EXPORT_PRIVATE SpeculatedType speculationFromValue(JSValue);
</ins><span class="cx"> SpeculatedType speculationFromJSType(JSType);
</span><span class="cx"> 
</span><span class="cx"> SpeculatedType speculationFromTypedArrayType(TypedArrayType); // only valid for typed views.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h       2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractValue.h  2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -188,6 +188,14 @@
</span><span class="cx">             && m_arrayModes == ALL_ARRAY_MODES
</span><span class="cx">             && !m_value;
</span><span class="cx">     }
</span><ins>+
+    bool isBytecodeTop() const
+    {
+        return (m_type | SpecBytecodeTop) == m_type
+            && m_structure.isTop()
+            && m_arrayModes == ALL_ARRAY_MODES
+            && !m_value;
+    }
</ins><span class="cx">     
</span><span class="cx">     bool valueIsTop() const
</span><span class="cx">     {
</span><span class="lines">@@ -372,7 +380,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool validateOSREntryValue(JSValue value, FlushFormat format) const
</span><span class="cx">     {
</span><del>-        if (isHeapTop())
</del><ins>+        if (isBytecodeTop())
</ins><span class="cx">             return true;
</span><span class="cx">         
</span><span class="cx">         if (!!m_value && m_value != value)
</span><span class="lines">@@ -411,7 +419,7 @@
</span><span class="cx">     void checkConsistency() const { }
</span><span class="cx">     void assertIsRegistered(Graph&) const { }
</span><span class="cx"> #else
</span><del>-    void checkConsistency() const;
</del><ins>+    JS_EXPORT_PRIVATE void checkConsistency() const;
</ins><span class="cx">     void assertIsRegistered(Graph&) const;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -536,7 +544,7 @@
</span><span class="cx">     void filterArrayModesByType();
</span><span class="cx"> 
</span><span class="cx"> #if USE(JSVALUE64) && !defined(NDEBUG)
</span><del>-    void ensureCanInitializeWithZeros();
</del><ins>+    JS_EXPORT_PRIVATE void ensureCanInitializeWithZeros();
</ins><span class="cx"> #endif
</span><span class="cx">     
</span><span class="cx">     bool shouldBeClear() const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGJITCompilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp       2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/dfg/DFGJITCompiler.cpp  2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -584,12 +584,12 @@
</span><span class="cx">     for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) {
</span><span class="cx">         Node* node = basicBlock.variablesAtHead.argument(argument);
</span><span class="cx">         if (!node || !node->shouldGenerate())
</span><del>-            entry->m_expectedValues.argument(argument).makeHeapTop();
</del><ins>+            entry->m_expectedValues.argument(argument).makeBytecodeTop();
</ins><span class="cx">     }
</span><span class="cx">     for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) {
</span><span class="cx">         Node* node = basicBlock.variablesAtHead.local(local);
</span><span class="cx">         if (!node || !node->shouldGenerate())
</span><del>-            entry->m_expectedValues.local(local).makeHeapTop();
</del><ins>+            entry->m_expectedValues.local(local).makeBytecodeTop();
</ins><span class="cx">         else {
</span><span class="cx">             VariableAccessData* variable = node->variableAccessData();
</span><span class="cx">             entry->m_machineStackUsed.set(variable->machineLocal().toLocal());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGStructureAbstractValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h      2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h 2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -232,7 +232,7 @@
</span><span class="cx">     // contains(), true for isSubsetOf(), false for isSupersetOf(), and false for overlaps().
</span><span class="cx"> 
</span><span class="cx">     bool contains(RegisteredStructure) const;
</span><del>-    bool contains(Structure* structure) const;
</del><ins>+    JS_EXPORT_PRIVATE bool contains(Structure* structure) const;
</ins><span class="cx">     
</span><span class="cx">     bool isSubsetOf(const RegisteredStructureSet& other) const;
</span><span class="cx">     bool isSubsetOf(const StructureAbstractValue& other) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgtestdfgcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/dfg/testdfg.cpp (0 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/testdfg.cpp                              (rev 0)
+++ trunk/Source/JavaScriptCore/dfg/testdfg.cpp 2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -0,0 +1,119 @@
</span><ins>+/*
+ * Copyright (C) 2019 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 "HeapCellInlines.h"
+#include "JSCJSValueInlines.h"
+// The above are needed before DFGAbstractValue.h
+#include "DFGAbstractValue.h"
+#include "InitializeThreading.h"
+#include <wtf/DataLog.h>
+
+// We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
+static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
+
+static void usage()
+{
+    dataLog("Usage: testdfg [<filter>]\n");
+    if (hiddenTruthBecauseNoReturnIsStupid())
+        exit(1);
+}
+
+#if ENABLE(DFG_JIT)
+
+using namespace JSC;
+using namespace JSC::DFG;
+
+namespace {
+
+// Nothing fancy for now; we just use the existing WTF assertion machinery.
+#define CHECK(x) do {                                                           \
+        if (!!(x))                                                              \
+            break;                                                              \
+        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
+        CRASH();                                                                \
+    } while (false)
+
+
+#define RUN_NOW(test) do {                      \
+        if (!shouldRun(#test))                  \
+            break;                              \
+        dataLog(#test "...\n");          \
+        test;                                   \
+        dataLog(#test ": OK!\n");        \
+    } while (false)
+
+static void testEmptyValueDoesNotValidateWithHeapTop()
+{
+    AbstractValue value;
+
+    value.makeHeapTop();
+    CHECK(!value.validateOSREntryValue(JSValue(), FlushedJSValue));
+
+    value.makeBytecodeTop();
+    CHECK(value.validateOSREntryValue(JSValue(), FlushedJSValue));
+}
+
+void run(const char* filter)
+{
+    auto shouldRun = [&] (const char* testName) -> bool {
+        return !filter || !!strcasestr(testName, filter);
+    };
+
+    RUN_NOW(testEmptyValueDoesNotValidateWithHeapTop());
+}
+
+} // anonymous namespace
+
+#else // ENABLE(DFG_JIT)
+
+static void run(const char*)
+{
+    dataLog("DFG JIT is not enabled.\n");
+}
+
+#endif // ENABLE(DFG_JIT)
+
+int main(int argc, char** argv)
+{
+    const char* filter = nullptr;
+    switch (argc) {
+    case 1:
+        break;
+    case 2:
+        filter = argv[1];
+        break;
+    default:
+        usage();
+        break;
+    }
+
+    JSC::initializeThreading();
+    
+    run(filter);
+
+    return 0;
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreshellCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/shell/CMakeLists.txt (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/shell/CMakeLists.txt 2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Source/JavaScriptCore/shell/CMakeLists.txt    2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -68,6 +68,10 @@
</span><span class="cx">     ../b3/air/testair.cpp
</span><span class="cx"> )
</span><span class="cx"> 
</span><ins>+set(TESTDFG_SOURCES
+    ../dfg/testdfg.cpp
+)
+
</ins><span class="cx"> if (DEVELOPER_MODE AND NOT WIN32)
</span><span class="cx">     add_executable(testmasm ${TESTMASM_SOURCES})
</span><span class="cx">     target_link_libraries(testmasm ${JSC_LIBRARIES})
</span><span class="lines">@@ -78,6 +82,9 @@
</span><span class="cx">     add_executable(testair ${TESTAIR_SOURCES})
</span><span class="cx">     target_link_libraries(testair ${JSC_LIBRARIES})
</span><span class="cx"> 
</span><ins>+    add_executable(testdfg ${TESTDFG_SOURCES})
+    target_link_libraries(testdfg ${JSC_LIBRARIES})
+
</ins><span class="cx">     add_executable(testapi ${TESTAPI_SOURCES})
</span><span class="cx">     target_link_libraries(testapi ${JSC_LIBRARIES})
</span><span class="cx"> endif ()
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Tools/ChangeLog       2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2019-03-20  Saam Barati  <sbarati@apple.com>
+
+        DFG::AbstractValue::validateOSREntry is wrong when isHeapTop and the incoming value is Empty
+        https://bugs.webkit.org/show_bug.cgi?id=195721
+
+        Reviewed by Filip Pizlo.
+
+        * Scripts/run-javascriptcore-tests:
+
</ins><span class="cx"> 2019-03-20  Simon Fraser  <simon.fraser@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Rename ENABLE_ACCELERATED_OVERFLOW_SCROLLING macro to ENABLE_OVERFLOW_SCROLLING_TOUCH
</span></span></pre></div>
<a id="trunkToolsScriptsrunjavascriptcoretests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-javascriptcore-tests (243277 => 243278)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-javascriptcore-tests     2019-03-21 05:41:21 UTC (rev 243277)
+++ trunk/Tools/Scripts/run-javascriptcore-tests        2019-03-21 05:43:08 UTC (rev 243278)
</span><span class="lines">@@ -71,6 +71,7 @@
</span><span class="cx"> my $runTestMasm = RUN_IF_NO_TESTS_SPECIFIED;
</span><span class="cx"> my $runTestAir = RUN_IF_NO_TESTS_SPECIFIED;
</span><span class="cx"> my $runTestB3 = RUN_IF_NO_TESTS_SPECIFIED;
</span><ins>+my $runTestDFG = RUN_IF_NO_TESTS_SPECIFIED;
</ins><span class="cx"> my $runTestAPI = RUN_IF_NO_TESTS_SPECIFIED;
</span><span class="cx"> my $runJSCStress = RUN_IF_NO_TESTS_SPECIFIED;
</span><span class="cx"> my $runMozillaTests = RUN_IF_NO_TESTS_SPECIFIED;
</span><span class="lines">@@ -128,6 +129,17 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+if ($ENV{RUN_JAVASCRIPTCORE_TESTS_TESTDFG}) {
+    if ($ENV{RUN_JAVASCRIPTCORE_TESTS_TESTDFG} eq "true") {
+        $runTestDFG = ENV_VAR_SAYS_DO_RUN;
+    } elsif ($ENV{RUN_JAVASCRIPTCORE_TESTS_TESTDFG} eq "false") {
+        $runTestDFG = ENV_VAR_SAYS_DONT_RUN;
+    } else {
+        print "Don't recognize value for RUN_JAVASCRIPTCORE_TESTS_TESTDFG environment variable: '"
+            . $ENV{RUN_JAVASCRIPTCORE_TESTS_TESTDFG} . "'. Should be set to 'true' or 'false'.\n";
+    }
+}
+
</ins><span class="cx"> if ($ENV{RUN_JAVASCRIPTCORE_TESTS_TESTAPI}) {
</span><span class="cx">     if ($ENV{RUN_JAVASCRIPTCORE_TESTS_TESTAPI} eq "true") {
</span><span class="cx">         $runTestAPI = ENV_VAR_SAYS_DO_RUN;
</span><span class="lines">@@ -181,6 +193,7 @@
</span><span class="cx"> my $testmasmDefault = defaultStringForTestState($runTestMasm);
</span><span class="cx"> my $testairDefault = defaultStringForTestState($runTestAir);
</span><span class="cx"> my $testb3Default = defaultStringForTestState($runTestB3);
</span><ins>+my $testDFGDefault = defaultStringForTestState($runTestDFG);
</ins><span class="cx"> my $testapiDefault = defaultStringForTestState($runTestAPI);
</span><span class="cx"> my $jscStressDefault = defaultStringForTestState($runJSCStress);
</span><span class="cx"> my $mozillaTestsDefault = defaultStringForTestState($runMozillaTests);
</span><span class="lines">@@ -198,6 +211,7 @@
</span><span class="cx">   --[no-]testmasm               Only run (or don't run) testmasm (default: $testmasmDefault)
</span><span class="cx">   --[no-]testair                Only run (or don't run) testair (default: $testairDefault)
</span><span class="cx">   --[no-]testb3                 Only run (or don't run) testb3 (default: $testb3Default)
</span><ins>+  --[no-]testdfg                Only run (or don't run) testdfg (default: $testDFGDefault)
</ins><span class="cx">   --[no-]testapi                Only run (or don't run) testapi (default: $testapiDefault)
</span><span class="cx">   --[no-]jsc-stress             Only run (or don't run) the JSC stress tests (default: $jscStressDefault)
</span><span class="cx">   --[no-]mozilla-tests          Only run (or don't run) the Mozilla tests (default: $mozillaTestsDefault)
</span><span class="lines">@@ -238,6 +252,7 @@
</span><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_TESTMASM to "true" or "false" (no quotes) to determine if we run testmasm by default.
</span><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_TESTAIR to "true" or "false" (no quotes) to determine if we run testair by default.
</span><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_TESTB3 to "true" or "false" (no quotes) to determine if we run testb3 by default.
</span><ins>+  - set RUN_JAVASCRIPTCORE_TESTS_TESTDFG to "true" or "false" (no quotes) to determine if we run testdfg by default.
</ins><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_TESTAPI to "true" or "false" (no quotes) to determine if we run testapi by default.
</span><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_BUILD to "true" or "false" (no quotes) to set the should-we-build-before-running-tests setting.
</span><span class="cx">   - set RUN_JAVASCRIPTCORE_TESTS_EXTRA_TESTS to the path of a yaml file or a directory of JS files to be run as part of run-javascriptcore-tests.
</span><span class="lines">@@ -257,6 +272,7 @@
</span><span class="cx">     'testmasm!' => \$runTestMasm,
</span><span class="cx">     'testair!' => \$runTestAir,
</span><span class="cx">     'testb3!' => \$runTestB3,
</span><ins>+    'testdfg!' => \$runTestDFG,
</ins><span class="cx">     'testapi!' => \$runTestAPI,
</span><span class="cx">     'jsc-stress!' => \$runJSCStress,
</span><span class="cx">     'mozilla-tests!' => \$runMozillaTests,
</span><span class="lines">@@ -287,6 +303,7 @@
</span><span class="cx"> if ($runTestMasm == DO_RUN
</span><span class="cx">    || $runTestAir == DO_RUN
</span><span class="cx">    || $runTestB3 == DO_RUN
</span><ins>+   || $runTestDFG == DO_RUN
</ins><span class="cx">    || $runTestAPI == DO_RUN
</span><span class="cx">    || $runJSCStress == DO_RUN
</span><span class="cx">    || $runMozillaTests == DO_RUN) {
</span><span class="lines">@@ -306,6 +323,7 @@
</span><span class="cx"> $runTestMasm = enableTestOrNot($runTestMasm);
</span><span class="cx"> $runTestAir = enableTestOrNot($runTestAir);
</span><span class="cx"> $runTestB3 = enableTestOrNot($runTestB3);
</span><ins>+$runTestDFG = enableTestOrNot($runTestDFG);
</ins><span class="cx"> $runTestAPI = enableTestOrNot($runTestAPI);
</span><span class="cx"> $runJSCStress = enableTestOrNot($runJSCStress);
</span><span class="cx"> $runMozillaTests = enableTestOrNot($runMozillaTests);
</span><span class="lines">@@ -394,6 +412,7 @@
</span><span class="cx"> if ($runTestMasm) { runTest("testmasm", "allMasmTestsPassed") }
</span><span class="cx"> if ($runTestAir) { runTest("testair", "allAirTestsPassed") }
</span><span class="cx"> if ($runTestB3) { runTest("testb3", "allB3TestsPassed") }
</span><ins>+if ($runTestDFG) { runTest("testdfg", "allDFGTestsPassed") }
</ins><span class="cx"> if ($runTestAPI) { runTest("testapi", "allApiTestsPassed") }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>