<!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>[235420] 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/235420">235420</a></dd>
<dt>Author</dt> <dd>yusukesuzuki@slowstart.org</dd>
<dt>Date</dt> <dd>2018-08-27 23:38:29 -0700 (Mon, 27 Aug 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WebAssembly] Parse wasm modules in a streaming fashion
https://bugs.webkit.org/show_bug.cgi?id=188943

Reviewed by Mark Lam.

JSTests:

Wasm parsing error should not report the total byte size since streaming parsing does not
want to load all the bytes.
Add a simple test wasm/stress/streaming-basic.js for initial streaming parsing implementation.

* wasm/function-tests/invalid-duplicate-export.js:
* wasm/function-tests/memory-alignment.js:
(const.op.of.WASM.opcodes):
* wasm/function-tests/memory-section-and-import.js:
* wasm/function-tests/void-argument-type-should-be-a-validation-error.js:
* wasm/js-api/Module-compile.js:
(async.testPromiseAPI):
* wasm/js-api/element.js:
(assert.throws.new.WebAssembly.Module.builder.WebAssembly):
(assert.throws):
* wasm/js-api/global-error.js:
(assert.throws.new.WebAssembly.Module.bin):
(assert.throws):
* wasm/js-api/table.js:
(new.WebAssembly.Module):
(assert.throws):
(assertBadTableImport):
* wasm/js-api/test_Data.js:
(DataSectionWithoutMemory):
* wasm/js-api/test_Start.js:
(InvalidStartFunctionIndex):
* wasm/js-api/test_basic_api.js:
(const.c.in.constructorProperties.switch):
* wasm/js-api/version.js:
* wasm/stress/nameSection.wasm: Added.
* wasm/stress/streaming-basic.js: Added.
(check):

Source/JavaScriptCore:

This patch adds Wasm::StreamingParser, which parses wasm binary in a streaming fashion.
Currently, this StreamingParser is not enabled and integrated. In subsequent patches,
we start integrating it into BBQPlan and dropping the old ModuleParser.

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* tools/JSDollarVM.cpp:
(WTF::WasmStreamingParser::WasmStreamingParser):
(WTF::WasmStreamingParser::create):
(WTF::WasmStreamingParser::createStructure):
(WTF::WasmStreamingParser::streamingParser):
(WTF::WasmStreamingParser::finishCreation):
(WTF::functionWasmStreamingParserAddBytes):
(WTF::functionWasmStreamingParserFinalize):
(JSC::functionCreateWasmStreamingParser):
(JSC::JSDollarVM::finishCreation):
The $vm Wasm::StreamingParser object is introduced for testing purpose. Added new stress test uses
this interface to test streaming parser in the JSC shell.

* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::BBQPlan):
(JSC::Wasm::BBQPlan::parseAndValidateModule):
(JSC::Wasm::BBQPlan::prepare):
(JSC::Wasm::BBQPlan::compileFunctions):
(JSC::Wasm::BBQPlan::complete):
(JSC::Wasm::BBQPlan::work):
* wasm/WasmBBQPlan.h:
BBQPlan has m_source, but once ModuleInformation is parsed, it is no longer necessary.
In subsequent patches, we will remove this, and stream the data into the BBQPlan.

* wasm/WasmFormat.h:
* wasm/WasmModuleInformation.cpp:
(JSC::Wasm::ModuleInformation::ModuleInformation):
* wasm/WasmModuleInformation.h:
One of the largest change in this patch is that ModuleInformation no longer holds source bytes,
since source bytes can be added in a streaming fashion. Instead of holding all the source bytes
in ModuleInformation, each function (ModuleInformation::functions, FunctionData) should have
Vector<uint8_t> for its data. This data is eventually filled by StreamingParser, and compiling
a function with this data can be done concurrently with StreamingParser.

(JSC::Wasm::ModuleInformation::create):
(JSC::Wasm::ModuleInformation::memoryCount const):
(JSC::Wasm::ModuleInformation::tableCount const):
memoryCount and tableCount should be recorded in ModuleInformation.

* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parse):
(JSC::Wasm::makeI32InitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseType): Deleted.
(JSC::Wasm::ModuleParser::parseImport): Deleted.
(JSC::Wasm::ModuleParser::parseFunction): Deleted.
(JSC::Wasm::ModuleParser::parseResizableLimits): Deleted.
(JSC::Wasm::ModuleParser::parseTableHelper): Deleted.
(JSC::Wasm::ModuleParser::parseTable): Deleted.
(JSC::Wasm::ModuleParser::parseMemoryHelper): Deleted.
(JSC::Wasm::ModuleParser::parseMemory): Deleted.
(JSC::Wasm::ModuleParser::parseGlobal): Deleted.
(JSC::Wasm::ModuleParser::parseExport): Deleted.
(JSC::Wasm::ModuleParser::parseStart): Deleted.
(JSC::Wasm::ModuleParser::parseElement): Deleted.
(JSC::Wasm::ModuleParser::parseCode): Deleted.
(JSC::Wasm::ModuleParser::parseInitExpr): Deleted.
(JSC::Wasm::ModuleParser::parseGlobalType): Deleted.
(JSC::Wasm::ModuleParser::parseData): Deleted.
(JSC::Wasm::ModuleParser::parseCustom): Deleted.
Extract section parsing code out from ModuleParser. We create SectionParser and ModuleParser uses it.
SectionParser is also used by StreamingParser.

* wasm/WasmModuleParser.h:
(): Deleted.
* wasm/WasmNameSection.h:
(JSC::Wasm::NameSection::NameSection):
(JSC::Wasm::NameSection::create):
(JSC::Wasm::NameSection::setHash):
Hash calculation is deferred since all the source is not available in streaming parsing.

* wasm/WasmNameSectionParser.cpp:
(JSC::Wasm::NameSectionParser::parse):
* wasm/WasmNameSectionParser.h:
Use Ref<NameSection>.

* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
Wasm::Plan no longer have m_source since data will be eventually filled in a streaming fashion.
OMGPlan can get data of the function by using ModuleInformation::functions.

* wasm/WasmParser.h:
(JSC::Wasm::Parser::source const):
(JSC::Wasm::Parser::length const):
(JSC::Wasm::Parser::offset const):
(JSC::Wasm::Parser::fail const):
(JSC::Wasm::makeI32InitExpr):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
Wasm::Plan should not have all the source apriori. Streamed data will be pumped from the provider.

* wasm/WasmPlan.h:
* wasm/WasmSectionParser.cpp: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.cpp.
SectionParser is extracted from ModuleParser. And it is used by both the old (currently working)
ModuleParser and the new StreamingParser.

(JSC::Wasm::SectionParser::parseType):
(JSC::Wasm::SectionParser::parseImport):
(JSC::Wasm::SectionParser::parseFunction):
(JSC::Wasm::SectionParser::parseResizableLimits):
(JSC::Wasm::SectionParser::parseTableHelper):
(JSC::Wasm::SectionParser::parseTable):
(JSC::Wasm::SectionParser::parseMemoryHelper):
(JSC::Wasm::SectionParser::parseMemory):
(JSC::Wasm::SectionParser::parseGlobal):
(JSC::Wasm::SectionParser::parseExport):
(JSC::Wasm::SectionParser::parseStart):
(JSC::Wasm::SectionParser::parseElement):
(JSC::Wasm::SectionParser::parseCode):
(JSC::Wasm::SectionParser::parseInitExpr):
(JSC::Wasm::SectionParser::parseGlobalType):
(JSC::Wasm::SectionParser::parseData):
(JSC::Wasm::SectionParser::parseCustom):
* wasm/WasmSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.h.
* wasm/WasmStreamingParser.cpp: Added.
(JSC::Wasm::parseUInt7):
(JSC::Wasm::StreamingParser::fail):
(JSC::Wasm::StreamingParser::StreamingParser):
(JSC::Wasm::StreamingParser::parseModuleHeader):
(JSC::Wasm::StreamingParser::parseSectionID):
(JSC::Wasm::StreamingParser::parseSectionSize):
(JSC::Wasm::StreamingParser::parseCodeSectionSize):
Code section in Wasm binary is specially handled compared with the other sections since it includes
a bunch of functions. StreamingParser extracts each function in a streaming fashion and enable
streaming validation / compilation of Wasm functions.

(JSC::Wasm::StreamingParser::parseFunctionSize):
(JSC::Wasm::StreamingParser::parseFunctionPayload):
(JSC::Wasm::StreamingParser::parseSectionPayload):
(JSC::Wasm::StreamingParser::consume):
(JSC::Wasm::StreamingParser::consumeVarUInt32):
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::failOnState):
(JSC::Wasm::StreamingParser::finalize):
* wasm/WasmStreamingParser.h: Added.
(JSC::Wasm::StreamingParser::addBytes):
(JSC::Wasm::StreamingParser::errorMessage const):
This is our new StreamingParser implementation. StreamingParser::consumeXXX functions get data, and
StreamingParser::parseXXX functions parse consumed data. The user of StreamingParser calls
StreamingParser::addBytes() to pump the bytes stream into the parser. And once all the data is pumped,
the user calls StreamingParser::finalize. StreamingParser is a state machine which feeds on the
incoming byte stream.

* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::source const): Deleted.
All the source should not be held.

* wasm/js/JSWebAssemblyModule.h:
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyValidateFunc):

Source/WTF:

Add maxByteLength function to get the maximum size for T.

* wtf/LEBDecoder.h:
(WTF::LEBDecoder::maxByteLength):
(WTF::LEBDecoder::decodeUInt):
(WTF::LEBDecoder::decodeInt):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestswasmfunctiontestsinvalidduplicateexportjs">trunk/JSTests/wasm/function-tests/invalid-duplicate-export.js</a></li>
<li><a href="#trunkJSTestswasmfunctiontestsmemoryalignmentjs">trunk/JSTests/wasm/function-tests/memory-alignment.js</a></li>
<li><a href="#trunkJSTestswasmfunctiontestsmemorysectionandimportjs">trunk/JSTests/wasm/function-tests/memory-section-and-import.js</a></li>
<li><a href="#trunkJSTestswasmfunctiontestsvoidargumenttypeshouldbeavalidationerrorjs">trunk/JSTests/wasm/function-tests/void-argument-type-should-be-a-validation-error.js</a></li>
<li><a href="#trunkJSTestswasmjsapiModulecompilejs">trunk/JSTests/wasm/js-api/Module-compile.js</a></li>
<li><a href="#trunkJSTestswasmjsapielementjs">trunk/JSTests/wasm/js-api/element.js</a></li>
<li><a href="#trunkJSTestswasmjsapiglobalerrorjs">trunk/JSTests/wasm/js-api/global-error.js</a></li>
<li><a href="#trunkJSTestswasmjsapitablejs">trunk/JSTests/wasm/js-api/table.js</a></li>
<li><a href="#trunkJSTestswasmjsapitest_Datajs">trunk/JSTests/wasm/js-api/test_Data.js</a></li>
<li><a href="#trunkJSTestswasmjsapitest_Startjs">trunk/JSTests/wasm/js-api/test_Start.js</a></li>
<li><a href="#trunkJSTestswasmjsapitest_basic_apijs">trunk/JSTests/wasm/js-api/test_basic_api.js</a></li>
<li><a href="#trunkJSTestswasmjsapiversionjs">trunk/JSTests/wasm/js-api/version.js</a></li>
<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="#trunkSourceJavaScriptCoreSourcestxt">trunk/Source/JavaScriptCore/Sources.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoretoolsJSDollarVMcpp">trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmBBQPlancpp">trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmBBQPlanh">trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmFormath">trunk/Source/JavaScriptCore/wasm/WasmFormat.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleInformationcpp">trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleInformationh">trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleParsercpp">trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleParserh">trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmNameSectionh">trunk/Source/JavaScriptCore/wasm/WasmNameSection.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmNameSectionParsercpp">trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmNameSectionParserh">trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmOMGPlancpp">trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmParserh">trunk/Source/JavaScriptCore/wasm/WasmParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmPlancpp">trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmPlanh">trunk/Source/JavaScriptCore/wasm/WasmPlan.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyModulecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyModuleh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyPrototypecpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfLEBDecoderh">trunk/Source/WTF/wtf/LEBDecoder.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestswasmstressnameSectionwasm">trunk/JSTests/wasm/stress/nameSection.wasm</a></li>
<li><a href="#trunkJSTestswasmstressstreamingbasicjs">trunk/JSTests/wasm/stress/streaming-basic.js</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmSectionParsercpp">trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmSectionParserh">trunk/Source/JavaScriptCore/wasm/WasmSectionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmStreamingParsercpp">trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmStreamingParserh">trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog  2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/ChangeLog     2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -1,3 +1,42 @@
</span><ins>+2018-08-27  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
+
+        [WebAssembly] Parse wasm modules in a streaming fashion
+        https://bugs.webkit.org/show_bug.cgi?id=188943
+
+        Reviewed by Mark Lam.
+
+        Wasm parsing error should not report the total byte size since streaming parsing does not
+        want to load all the bytes.
+        Add a simple test wasm/stress/streaming-basic.js for initial streaming parsing implementation.
+
+        * wasm/function-tests/invalid-duplicate-export.js:
+        * wasm/function-tests/memory-alignment.js:
+        (const.op.of.WASM.opcodes):
+        * wasm/function-tests/memory-section-and-import.js:
+        * wasm/function-tests/void-argument-type-should-be-a-validation-error.js:
+        * wasm/js-api/Module-compile.js:
+        (async.testPromiseAPI):
+        * wasm/js-api/element.js:
+        (assert.throws.new.WebAssembly.Module.builder.WebAssembly):
+        (assert.throws):
+        * wasm/js-api/global-error.js:
+        (assert.throws.new.WebAssembly.Module.bin):
+        (assert.throws):
+        * wasm/js-api/table.js:
+        (new.WebAssembly.Module):
+        (assert.throws):
+        (assertBadTableImport):
+        * wasm/js-api/test_Data.js:
+        (DataSectionWithoutMemory):
+        * wasm/js-api/test_Start.js:
+        (InvalidStartFunctionIndex):
+        * wasm/js-api/test_basic_api.js:
+        (const.c.in.constructorProperties.switch):
+        * wasm/js-api/version.js:
+        * wasm/stress/nameSection.wasm: Added.
+        * wasm/stress/streaming-basic.js: Added.
+        (check):
+
</ins><span class="cx"> 2018-08-27  Mark Lam  <mark.lam@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix exception throwing code so that topCallFrame and topEntryFrame stay true to their names.
</span></span></pre></div>
<a id="trunkJSTestswasmfunctiontestsinvalidduplicateexportjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/invalid-duplicate-export.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/invalid-duplicate-export.js    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/function-tests/invalid-duplicate-export.js       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -15,5 +15,5 @@
</span><span class="cx">         .End();
</span><span class="cx"> 
</span><span class="cx">     const bin = builder.WebAssembly().get();
</span><del>-    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 31 / 39: duplicate export: 'foo'");
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 31: duplicate export: 'foo'");
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkJSTestswasmfunctiontestsmemoryalignmentjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/memory-alignment.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/memory-alignment.js    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/function-tests/memory-alignment.js       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx">         if (alignLog2 <= maxAlignLog2)
</span><span class="cx">             instance();
</span><span class="cx">         else
</span><del>-            assert.throws(instance, WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte ${start} / ${end}: byte alignment ${1 << alignLog2} exceeds ${info.type}'s natural alignment ${1 << maxAlignLog2}, in function at index 0`);
</del><ins>+            assert.throws(instance, WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte ${start}: byte alignment ${1 << alignLog2} exceeds ${info.type}'s natural alignment ${1 << maxAlignLog2}, in function at index 0`);
</ins><span class="cx"> 
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkJSTestswasmfunctiontestsmemorysectionandimportjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/memory-section-and-import.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/memory-section-and-import.js   2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/function-tests/memory-section-and-import.js      2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -28,4 +28,4 @@
</span><span class="cx">       .Code().End();
</span><span class="cx"> 
</span><span class="cx"> const i0 = instantiate(builder0);
</span><del>-assert.throws(() => instantiate(builder1, { imp: { memory: i0.exports.memory } }), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 35 / 41: there can at most be one Memory section for now`);
</del><ins>+assert.throws(() => instantiate(builder1, { imp: { memory: i0.exports.memory } }), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 35: there can at most be one Memory section for now`);
</ins></span></pre></div>
<a id="trunkJSTestswasmfunctiontestsvoidargumenttypeshouldbeavalidationerrorjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/void-argument-type-should-be-a-validation-error.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/void-argument-type-should-be-a-validation-error.js     2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/function-tests/void-argument-type-should-be-a-validation-error.js        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -17,6 +17,6 @@
</span><span class="cx">     return builder.WebAssembly().get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15 / 47: can't get 1th argument Type");
-assert.throws(() => new WebAssembly.Module(getBinary(["void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 14 / 46: can't get 0th argument Type");
-assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void", "i32"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15 / 48: can't get 1th argument Type");
</del><ins>+assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15: can't get 1th argument Type");
+assert.throws(() => new WebAssembly.Module(getBinary(["void"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 14: can't get 0th argument Type");
+assert.throws(() => new WebAssembly.Module(getBinary(["i32", "void", "i32"])), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 15: can't get 1th argument Type");
</ins></span></pre></div>
<a id="trunkJSTestswasmjsapiModulecompilejs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/Module-compile.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/Module-compile.js      2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/Module-compile.js 2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -21,7 +21,7 @@
</span><span class="cx">             await WebAssembly.compile(builder.WebAssembly().get());
</span><span class="cx">         } catch(e) {
</span><span class="cx">             assert.truthy(e instanceof WebAssembly.CompileError);
</span><del>-            assert.truthy(e.message === "WebAssembly.Module doesn't parse at byte 34 / 43: there can at most be one Memory section for now");
</del><ins>+            assert.truthy(e.message === "WebAssembly.Module doesn't parse at byte 34: there can at most be one Memory section for now");
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJSTestswasmjsapielementjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/element.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/element.js     2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/element.js        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -18,7 +18,7 @@
</span><span class="cx">             .End()
</span><span class="cx">         .End();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 24 / 41: Element section for Table 0 exceeds available Table 0");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 24: Element section for Table 0 exceeds available Table 0");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx">             .End()
</span><span class="cx">         .End();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30 / 47: Element section for Table 1 exceeds available Table 1");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30: Element section for Table 1 exceeds available Table 1");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx">             .End()
</span><span class="cx">         .End();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 38 / 50: Element section's 0th element's 2th index is 1 which exceeds the function index space size of 1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 38: Element section's 0th element's 2th index is 1 which exceeds the function index space size of 1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -215,5 +215,5 @@
</span><span class="cx">         return new WebAssembly.Module(bin);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    assert.throws(() => badModule(), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 58 / 72: Element init_expr must produce an i32");
</del><ins>+    assert.throws(() => badModule(), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 58: Element init_expr must produce an i32");
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkJSTestswasmjsapiglobalerrorjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/global-error.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/global-error.js        2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/global-error.js   2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -23,7 +23,7 @@
</span><span class="cx">     const bin = builder.WebAssembly();
</span><span class="cx">     bin.trim();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 26 / 59: get_global's index 0 exceeds the number of globals 0 (evaluating 'new WebAssembly.Module(bin.get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 26: get_global's index 0 exceeds the number of globals 0 (evaluating 'new WebAssembly.Module(bin.get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     const bin = builder.WebAssembly();
</span><span class="cx">     bin.trim();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 32 / 76: Mutable Globals aren't supported (evaluating 'new WebAssembly.Module(bin.get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 32: Mutable Globals aren't supported (evaluating 'new WebAssembly.Module(bin.get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     const bin = builder.WebAssembly();
</span><span class="cx">     bin.trim();
</span><span class="cx"> 
</span><del>-    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 51 / 59: 1th Export isn't immutable, named 'global' (evaluating 'new WebAssembly.Module(bin.get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin.get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 51: 1th Export isn't immutable, named 'global' (evaluating 'new WebAssembly.Module(bin.get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkJSTestswasmjsapitablejs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/table.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/table.js       2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/table.js  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -13,7 +13,7 @@
</span><span class="cx">         .End()
</span><span class="cx">         .Code()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 34 / 41: Cannot have more than one Table for now");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 34: Cannot have more than one Table for now");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">         .End()
</span><span class="cx">         .Code()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 17 / 28: Table count of 2 is invalid, at most 1 is allowed for now (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 17: Table count of 2 is invalid, at most 1 is allowed for now (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">                 .CallIndirect(0, 0)
</span><span class="cx">             .End()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 4 / 7: call_indirect is only valid when a table is defined or imported, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 4: call_indirect is only valid when a table is defined or imported, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">                 .CallIndirect(0, 1)
</span><span class="cx">             .End()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 6 / 7: call_indirect's 'reserved' varuint1 must be 0x0, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 6: call_indirect's 'reserved' varuint1 must be 0x0, in function at index 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -86,7 +86,7 @@
</span><span class="cx">         .End()
</span><span class="cx">         .Code()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 23 / 26: can't export Table 0 there are 0 Tables");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 23: can't export Table 0 there are 0 Tables");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> {
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx">         .End()
</span><span class="cx">         .Code()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30 / 33: can't export Table 1 there are 1 Tables");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 30: can't export Table 1 there are 1 Tables");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function assertBadTable(tableDescription, message) {
</span><span class="lines">@@ -132,42 +132,42 @@
</span><span class="cx"> {
</span><span class="cx">     let badDescriptions = [
</span><span class="cx">         [{initial: 10, element: "i32"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 23: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 34: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, element: "f32"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 23: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 34: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, element: "f64"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 23: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 34: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, element: "i64"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 23: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 34: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, maximum: 20, element: "i32"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 24: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 35: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -1 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, maximum: 20, element: "f32"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 24: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 35: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -3 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, maximum: 20, element: "f64"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 24: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 35: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -4 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 10, maximum: 20, element: "i64"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 18 / 24: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 26 / 35: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 18: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 26: Table type should be anyfunc, got -2 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx"> 
</span><span class="cx">         [{initial: 10, maximum: 9, element: "anyfunc"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 21 / 24: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 29 / 35: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 21: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 10 which is greater than its maximum 9 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 1, maximum: 0, element: "anyfunc"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 21 / 24: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 29 / 35: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 21: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 1 which is greater than its maximum 0 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 2**32 - 1, maximum: 2**32 - 2, element: "anyfunc"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 29 / 32: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 37 / 43: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 29: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 37: resizable limits has a initial page count of 4294967295 which is greater than its maximum 4294967294 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">         [{initial: 2**31, element: "anyfunc"},
</span><del>-         "WebAssembly.Module doesn't parse at byte 24 / 27: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
-         "WebAssembly.Module doesn't parse at byte 32 / 38: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</del><ins>+         "WebAssembly.Module doesn't parse at byte 24: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')",
+         "WebAssembly.Module doesn't parse at byte 32: Table's initial page count of 2147483648 is too big, maximum 10000000 (evaluating 'new WebAssembly.Module(builder.WebAssembly().get())')"],
</ins><span class="cx">     ];
</span><span class="cx"> 
</span><span class="cx">     for (const d of badDescriptions) {
</span><span class="lines">@@ -186,7 +186,7 @@
</span><span class="cx">         .Function().End()
</span><span class="cx">         .Code()
</span><span class="cx">         .End();
</span><del>-    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 39 / 48: Cannot have more than one Table for now");
</del><ins>+    assert.throws(() => new WebAssembly.Module(builder.WebAssembly().get()), WebAssembly.CompileError, "WebAssembly.Module doesn't parse at byte 39: Cannot have more than one Table for now");
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkJSTestswasmjsapitest_Datajs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/test_Data.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/test_Data.js   2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/test_Data.js      2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">           .Segment([0xff]).Offset(0).End()
</span><span class="cx">         .End();
</span><span class="cx">     const bin = builder.WebAssembly().get();
</span><del>-    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15 / 20: 0th Data segment has index 0 which exceeds the number of Memories 0`);
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`);
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function EmptyDataSectionWithoutMemory() {
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">           .Segment([]).Offset(0).End()
</span><span class="cx">         .End();
</span><span class="cx">     const bin = builder.WebAssembly().get();
</span><del>-    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15 / 19: 0th Data segment has index 0 which exceeds the number of Memories 0`);
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 15: 0th Data segment has index 0 which exceeds the number of Memories 0`);
</ins><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function DataSectionBiggerThanMemory() {
</span></span></pre></div>
<a id="trunkJSTestswasmjsapitest_Startjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/test_Start.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/test_Start.js  2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/test_Start.js     2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -31,5 +31,5 @@
</span><span class="cx">         .Start(0).End() // Invalid index.
</span><span class="cx">         .Code().End();
</span><span class="cx">     const bin = b.WebAssembly().get();
</span><del>-    assert.throws(() => new WebAssembly.Module(bin), Error, `WebAssembly.Module doesn't parse at byte 17 / 20: Start index 0 exceeds function index space 0 (evaluating 'new WebAssembly.Module(bin)')`);
</del><ins>+    assert.throws(() => new WebAssembly.Module(bin), Error, `WebAssembly.Module doesn't parse at byte 17: Start index 0 exceeds function index space 0 (evaluating 'new WebAssembly.Module(bin)')`);
</ins><span class="cx"> })();
</span></span></pre></div>
<a id="trunkJSTestswasmjsapitest_basic_apijs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/test_basic_api.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/test_basic_api.js      2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/test_basic_api.js 2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">             assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`);
</span><span class="cx">         for (const buffer of [new ArrayBuffer(), new DataView(new ArrayBuffer()), new Int8Array(), new Uint8Array(), new Uint8ClampedArray(), new Int16Array(), new Uint16Array(), new Int32Array(), new Uint32Array(), new Float32Array(), new Float64Array()])
</span><span class="cx">             // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768
</span><del>-            assert.throws(() => new WebAssembly[c](buffer), Error, `WebAssembly.Module doesn't parse at byte 0 / 0: expected a module of at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`);
</del><ins>+            assert.throws(() => new WebAssembly[c](buffer), Error, `WebAssembly.Module doesn't parse at byte 0: expected a module of at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`);
</ins><span class="cx">         assert.instanceof(new WebAssembly[c](emptyModuleArray), WebAssembly.Module);
</span><span class="cx">         break;
</span><span class="cx">     case "Instance":
</span></span></pre></div>
<a id="trunkJSTestswasmjsapiversionjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/version.js (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/version.js     2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/JSTests/wasm/js-api/version.js        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -5,5 +5,5 @@
</span><span class="cx">     if (version === 1)
</span><span class="cx">         continue;
</span><span class="cx">     const emptyModuleArray = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
</span><del>-    assert.throws(() => new WebAssembly.Module(emptyModuleArray), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 8 / 8: unexpected version number ${version} expected 1`);
</del><ins>+    assert.throws(() => new WebAssembly.Module(emptyModuleArray), WebAssembly.CompileError, `WebAssembly.Module doesn't parse at byte 8: unexpected version number ${version} expected 1`);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkJSTestswasmstressnameSectionwasm"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/stress/nameSection.wasm (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/stress/nameSection.wasm                               (rev 0)
+++ trunk/JSTests/wasm/stress/nameSection.wasm  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,151 @@
</span><ins>+asm\xAB\x80\x80\x80````````\x82\x83\x80\x80envDYNAMICTOP_PTRenvSTACKTOPenv        STACK_MAXenvabortenv+enlargeMemoryenvgetTotalMemoryenvabortOnCannotGrowMemoryenv_emscripten_memcpy_bigenv___lockenv_abortenv ___setErrNoenv ___syscall6env+___syscall140env_sillyenv ___syscall54env       ___unlockenv+___syscall146envmemory\x80\x80envtablepenv
+memoryBaseenv     tableBase\xA6\x80\x80\x80%\x9F\x80\x80\x80# # # A A A \x84\x82\x80\x80_malloc) getTempRet0_fflush' runPostSets+ setTempRet0establishStackSpace        stackSave_memset-_sbrk,_emscripten_get_global_libc_memcpy.
+stackAllocsetThrew_parrot_free* stackRestore___errno_location
+dynCall_ii/ dynCall_iiii0  \x8C\x80\x80\x80# 12"
+\xB5܀\x80%\x9E\x80\x80\x80#!# j$#AjApq$  \x84\x80\x80\x80# \x86\x80\x80\x80 $ \x8D\x80\x80\x80@ $ $ \x90\x80\x80\x80#E@ $ $       \x86\x80\x80\x80 $
+ \x84\x80\x80\x80#
+ \x8F\x80\x80\x80 
+!  \x8F\x80\x80\x80 !  \x8F\x80\x80\x80 !  \x8F\x80\x80\x80 !  \x85\x80\x80\x80A\xF4
+ \xB0\x80\x80\x80#!#Aj$ " (<!6A ! $  \xFD\x82\x80\x80 #!#A0j$ Aj! A j" Aj"       ("6  Aj"
+( k"6  6  6  " A<j" (6  6 A6@@  j"A\x92 +"F+A!@ AN@  k! Aj!  ("+K" @ !   AtAu j!  (    +A k"j6 Aj" ( k6   (6  6  6 A\x92 +"F+   A6  A6 
+A6  (A r6 AFA  (k !    (," (0j6     6 
+ 6  $  倀\x80#!#A j$ " (<6 A6  6  Aj"6   6A\x8C         AH A6A ( ! $  \x9A\x80\x80\x80 A\x80`KA k6A  \x88\x80\x80\x80A\xC0j \x84\x80\x80\x80  \x85\x80\x80\x80A\x80 \x84\x80\x80\x80  뀀\x80#!#A j$ ! Aj! A6$ (A\xC0qE@  (<6 A\x93\xA86  6A6  @ A:K    ! $  \x84\x80\x80\x80A \x83\x80\x80\x80 \x8D\x80\x80\x80A\xB4 A\xBC \x87\x80\x80\x80A\xB4  \xA4\x81\x80\x80@ @ (LAL@ (!   #E! (!   $  !A\xF0
+(A\xF0
+('A !%("@@ (LAJ #A ! ( (K@ ( r!  @ $  (8"+ &   \x9C\x81\x80\x80@ Aj"( Aj"(M+ AA ($AqAj (+A   Aj"(" Aj"("I@   kA ((AqAj  A6 A6 A6 A6 A6A " \xA6\xB8\x80\x80#!+#Aj$ +!@ A\xF5I@ A jAxq!A\xC0 (" A IA"  Av"v"Aq@ AqAs j"AtA\xE8 j"Aj"("Aj"(!  F@A\xC0  A tAsq6 A\xD0 (I@  A j"( F@  6  6   At"Ar6  jAj" (Ar6 +$   A\xC8 ("K@ @  tA t"A krq"A kqAj"A vAq!  v"AvAq" r  v"AvAq"r  v"AvAq"r  v"AvAq"r  vj"AtA\xE8 j"Aj"("Aj"
+(!  F@A\xC0  A tAsq"6 A\xD0 (I@  A j" ( F@   6  6 !   Ar6  j" At k"Ar6  j 6 @A\xD4 (! Av"AtA\xE8 j! A t"q@ Aj"("A\xD0 (I@ !  ! A\xC0   r6 Aj!  !    6  6   6  6 A\xC8  6A\xD4  6 +$ 
+ A\xC4 (" @  A  kqAj"A vAq!  v"AvAq" r  v"AvAq"r  v"AvAq"r  v"AvAq"r  vjAtA\xF0+j("(Axq k! Aj (EAtj("@@ (Axq k" I"@ !  @ !  Aj (EAtj("+ !  !  A\xD0 ("I@    j"        O@  (! @ ( " F@ Aj"("E@ Aj"("E@A!  @ Aj"("
+@ 
+! !   Aj"("
+@ 
+! !    I@ A6 !  (" I@  A j"( G@  Aj"
+( F@  6 
+ 6 ! @  @  ("AtA\xF0+j"(F@  6 E@A\xC4   A tAsq6    A\xD0 (I@  Aj  ( GAtj 6 E+  A\xD0 ("I@    6 ("@  I@  6  6  ("@ A\xD0 (I@  6  6  AI@   j"Ar6  jAj" (Ar6  Ar6   Ar6         j 6 @A\xD4 (! Av"AtA\xE8 j! A t"q@ Aj"("A\xD0 (I@ ! ! A\xC0   r6 Aj! !   6  6   6  6 A\xC8  6A\xD4      6  +$ Aj !  !  A\xBFK@A! A j"Axq!A\xC4 ("@ Av" A\xFF\xFF\xFFKA A  A\x80\xFE?jAvAq"t"A\x80\xE0jAvAq" r  t"A\x80\x80jAvAq"rk  tAvj"AjvAq Atr A !A k!@@@ AtA\xF0+j("@A Avk!A!  AFA  t! A!@ (Axq k" I@ @ ! !A! !   ("E  Aj  AvAtj(
 "Fr   !   E"Ast!  + ! ! A!A!
   E Eq A t"A krq"E@ !   A kqAj"A vAq!  v"AvAq" r  v"AvAq"r  v"AvAq"r  v"AvAq"r  vjAtA\xF0+j(!A !  ! @ ! !  ! !  @ (Axq k" I" @ !   @ !  Aj (EAtj("+ ! !  @ A\xC8 ( kI@ A\xD0 ("I@    j"    O@  (! @ ( " F@ Aj"("E@ Aj"("E@A!  @ Aj"
+(" @  ! 
+!   Aj"
+(" @  ! 
+!    I@ A6 !  (" I@  A j"
+( G@  Aj" ( F@ 
+ 6   6 ! @  @  ("AtA\xF0+j"(F@  6 E@A\xC4  A tAsq"6    A\xD0 (I@  Aj  ( GAtj 6 E@ !   A\xD0 ("I@    6 ("@  I@  6  6  ("@ A\xD0 (I@  6  6 !  !  ! @ AI@   j"Ar6  jAj" (Ar6  Ar6    Ar6         j 6 Av! A\x80I@ AtA\xE8 j!A\xC0 ("A t"q@ Aj"("A\xD0 (I@ ! ! A\xC0   r6 Aj! !       6   6       6    6   Av" A\xFF\xFF\xFFKA A  A\x80\xFE?jAvAq"t"A\x80\xE0jAvAq" r  t"A\x80\x80jAvAq"rk  tAvj"AjvAq Atr A "AtA\xF0+j!   6   Aj"A6 A6 A t"qE@A\xC4   r6    6     6          6              6   (!A Avk!  AFA  t!@@@@ (Axq F+ At! Aj AvAtj"("E+ 
 ! !  A\xD0 (I@     6     6          6              6 
    Aj"("A\xD0 ("O  Oq@       6     6     6    6   A6  +$ Aj !  !  ! A\xC8 (" O@A\xD4 (!  k"AK@A\xD4   j"6A\xC8  6  Ar6  j 6  Ar6A\xC8 A6A\xD4 A6  Ar6  jAj" (Ar6  +$ Aj A\xCC (" K@A\xCC   k"6A\xD8 A\xD8 (" j"6  Ar6  Ar6 +$ Aj A\x98(A\xA0(A\xA0A\x80 6A\x9CA\x80 6A\xA4A6A\xA8A6A\xACA6A\xFCA6  ApqAتժs"6A\x98 6A\x80  " A/j"j"A k"q" M@ +$A A\xF8("@A\xF0(" j" M  Kr@ +$A  A0j!@@A\xFC(Aq@A!@@@A\xD8 ("E+A\x80!@@ ("  M@   Aj" (j K+  ("+    k q"A\xFF\xFF\xFF\xFFI@ ," (  (jF@ AG+  A!  A,"AF@A!A\x9C("Aj&qu
 ot; "jA kq k!  q A  j"A\xF0("
 j!  K A\xFF\xFF\xFF\xFFIq@A\xF8("@  M  Kr@A!   ," F+ ! A!    K A\xFF\xFF\xFF\xFFI AGqqE@ AF@A!     kA\xA0("jA kq"A\xFF\xFF\xFF\xFFO+A k! ,AF@ ,A!  j!  A\xFCA\xFC(Ar6  A\xFF\xFF\xFF\xFFI@ ,"A,"I AG AGqq!  k" A(jK"@ !  AF Asr AsrE+  A\xF0A\xF0( j"6 A\xF4(K@A\xF4 6 @A\xD8 ("@A\x80!@@@  (" Aj"("jF+ ("+   ( AqE@  I  Oq@   j6A\xCC (!A Aj"kAq!A\xD8   Aq A" j"6A\xCC    kj"6  Ar6  jA(6A\xDC A\xA8(6   A\xD0 ("I@A\xD0  6 !   j!A\x80!@@@ ( F+ ("+   ( AqE@  6 Aj" ( j6A Aj"kAq!A Aj"kAq!   Aq A j"  j!  Aq  A j"   k k! 
         Ar6@  F@A\xCC A\xCC ( j"6A\xD8  6
   Ar6 A\xD4 (F@A\xC8 A\xC8 ( j"6A\xD4  6  Ar6  j 6   ("AqAF Axq!  Av!@ A\x80I@ ( !@ (" AtA\xE8 j"G@  I@  (  F+   F@A\xC0 A\xC0 (A tAsq6  @  F@ Aj!  I@  Aj"( F@ !     6   6 (!@ ( " F@ Aj"Aj"("@ ! ("E@A!
+  @ Aj"("@ ! !   Aj"("@ ! !    I@ A6 !
+  (" I@  A j"( G@  Aj"( F@  6  6 !
+  E+@  ("AtA\xF0+j"(F@  
+6 
++A\xC4 A\xC4 (A tAsq6  A\xD0 (I@ Aj ( GAtj 
+6 
+E+  
+A\xD0 ("I@  
+ 6 Aj"("@  I@ 
+ 6  
+6  ("E+ A\xD0 (I@ 
+ 6  
+6    j!   j  ! Aj" (A~q6  Ar6  j 6 Av! A\x80I@ AtA\xE8 j!@A\xC0 ("A t"q@ Aj"("A\xD0 (O@ ! !  A\xC0   r6 Aj! !   6   6    6  6   Av"A A\xFF\xFF\xFFK+ A  A\x80\xFE?jAvAq"t"A\x80\xE0jAvAq" r  t"A\x80\x80jAvAq"rk  tAvj"AjvAq AtrA "AtA\xF0+j!  6 Aj"A6 A6A\xC4 ("A t"qE@A\xC4   r6  6  6  6   6   (!A Avk!  AFA  t!@@@@ (Axq F+ At! Aj AvAtj"("E+ ! !  A\xD0 (I@  6  6  6   6    Aj"("A\xD0 ("O  Oq@  6   6  6  6  A6  +$     Aj A\x80!@@ (" M@  (j"
+ K+  (!  A 
+AQj"Aj"kAq!  Aq A j" Aj" I "  Aj! Aj! AXj! A Aj"kAq!A\xD8   Aq A" j"6A\xCC    k"6  Ar6  jA(6A\xDC A\xA8(6 Aj"A6 A\x80)7 A\x88)7A\x80 6A\x84 6A\x8CA6A\x88 6 !@ Aj"A6 Aj 
+I@ !    G@  (A~q6   k"Ar6  6 Av! A\x80I@ AtA\xE8 j!A\xC0 ("A t"q@ Aj"("A\xD0 (I@ ! !  A\xC0   r6 Aj! !      6        6           6  6   Av" A\xFF\xFF\xFFKA A  A\x80\xFE?jAvAq"t"A\x80\xE0jAvAq" r  t"A\x80\x80jAvAq"rk  tAvj"AjvAq Atr A "AtA\xF0+j!  6 A6  A6A\xC4 ("A t"qE@A\xC4   r6  6  6  6   6   (!A Avk!  AFA  t!@@@@ (Axq F+ At! Aj AvAtj"("E+ ! !  A\xD0 (I@  6  6  6   6    Aj"("A\xD0 ("O  Oq@  6   6  6  6  A6 A\xD0 ("E  Ir@A\xD0  6 A\x80 6A\x84 6A\x8CA6A\xE4 A\x98(6A\xE0 A6A!@ AtA\xE8 j" 6   6 Aj"A G+  AXj!A
  Aj"kAq!A\xD8   Aq A" j"6A\xCC
   k"6  Ar6  jA(6A\xDC A\xA8(6 A\xCC (" K@A\xCC   k"6A\xD8 A\xD8 (" j"6  Ar6  Ar6 +$ Aj A 6 +$A ’\x80\x80@ E@  Axj"A\xD0 (" I@  A|j("Aq" AF@   Axq"j!@ Aq@ ! ! ! (!     E@  A    kj"  I@        j! A\xD4 (F@ Aj"("AqAG@ ! ! !  A\xC8  6  A~q6  Ar6  j 6    Av!   A\x80I@ ( ! (" AtA\xE8 j"G@   I@  (  G@   F@A\xC0 A\xC0 (A tAsq6 ! ! !    F@ Aj!   I@  Aj"( F@ !   6   6 ! ! !   (!+@ ( " F@ Aj"Aj"   ("@   ! ("E@A!  @ Aj"       (" @  !       !   Aj"        (" @  !       !     I@ A6 !  ("  I@  A j" ( G@  Aj" ( F@      6   6
  !  +@  ("AtA\xF0+j"(F@  6 E
 @A\xC4 A\xC4 (A tAsq6 ! ! !   +A\xD0 (I@ +Aj +( GAtj 6 E@ ! ! !   A\xD0 ("I@   +6 Aj" ("@  I@  6  6          ("@ A\xD0 (I@  6  6 ! ! !  ! ! !  ! ! !   O@  Aj"("AqE@  Aq@  A~q6  Ar6  j 6A\xD4 (! A\xD8 (F@A\xCC A\xCC ( j"6A\xD8  6  Ar6  G@ A\xD4 A6A\xC8 A6   F@A\xC8 A\xC8 ( j"6A\xD4  6  Ar6  j 6  Axq j! Av!@ A\x80I@ ( ! (" AtA\xE8 j"G@ A\xD0 (I@  (  G@   F@A\xC0 A\xC0 (A tAsq6    F@ Aj! A\xD0 (I@  Aj"( F@ !   6   6 (!@ ( " F@ Aj"Aj"("@ ! ("E@A!
+  @ Aj"("@ ! !   Aj"("@ ! !   A\xD0 (I@ A6 !
+  ("A\xD0 (I@  A j"( G@  Aj"( F@  6  6 !
+  @  ("AtA\xF0+j"(F@  
+6 
+E@A\xC4 A\xC4 (A tAsq6   A\xD0 (I@ Aj ( GAtj 
+6 
+E+  
+A\xD0 ("I@  
+ 6 Aj"("@  I@ 
+ 6  
+6  ("@ A\xD0 (I@ 
+ 6  
+6   Ar6  j 6 A\xD4 (F@A\xC8  6 !  Av! A\x80I@ AtA\xE8 j!A\xC0 ("A t"q@ Aj"("A\xD0 (I@ ! ! A\xC0   r6 Aj! !   6  6   6  6   Av" A\xFF\xFF\xFFKA A  A\x80\xFE?jAvAq"t"A\x80\xE0jAvAq" r  t"A\x80\x80jAvAq"rk  tAvj"AjvAq Atr A "AtA\xF0+j!  6 A6 A6@A\xC4 ("A t"q@ (!A Avk!  AFA  t!@@@@ (Axq F+ At! Aj AvAtj"("E+ ! !  A\xD0 (I@  6  6  6   6    Aj"("A\xD0 ("O  Oq@  6   6  6  6  A6 A\xC4   r6  6  6  6   6 A\xE0 A\xE0 (Aj"6 @A\x88! @ ("Aj! + A\xE0 A6 \x83\x80\x80\x80 ހ\x80\x80#(" AjApq"j! AJ  Hq A
 Hr@A A # 6 J@E@A # 6A   \x9D\x82\x
 80\x80  j! A\xFFq! A\xC3N@@ Aq@  : Aj!   A|q"A\xC0k!  Atr Atr Atr!@  L@  6  6  6  6   6  6  6  6  6   6$  6(  6,  60  64  68  6< A\xC0j!  @  H@  6 Aj!  @  H@  : Aj!    k Ƀ\x80\x80 A\x80\xC0N@     !  j! Aq AqF@@ Aq@ E@    ,: Aj! Aj! Ak!   A|q"A\xC0k!@  L@  (6  (6  (6  ( 6   (6  (6  (6  (6  ( 6   ($6$  ((6(  (,6,  (060  (464  (868  (<6< A\xC0j! A\xC0j!  @  H@  (6 Aj! Aj!   Ak!@  H@  ,:  ,:  ,:  ,: Aj! Aj!  @  H@  ,: Aj! Aj!    \x8C\x80\x80\x80  Aq \x93\x80\x80\x80    AqAj \x8B\x
 80\x80\x80AA \x8B\x80\x80\x80AA ŀ\x80\x80A\xBC        \x9CA\xF4   A\x80
+ A\x98
+ \xB8A\xB0
+ A\xBF
+ 
+\xFF\xFF\xFF\xFFA\xF0
+ \xF4\xA7\x85\x80\x80name\x9C\x85\x80\x803abort+enlargeMemorygetTotalMemoryabortOnCannotGrowMemory_emscripten_memcpy_big___lock_abort ___setErrNo ___syscall6        +___syscall140
+_silly ___syscall54  ___unlock++___syscall146
+stackAlloc    stackSave stackRestoreestablishStackSpacesetThrew setTempRet0 getTempRet0_eggs_bacon_spam_parrot_emscripten_get_global_libc___stdio_close___stdio_write+___stdio_seek___syscall_ret___errno_location___pthread_self_103 +_pthread_self!
+_dummy_570"___stdout_write# ___lockfile$+___unlockfile% ___ofl_lock&+___ofl_unlock'_fflush(___fflush_unlocked)_malloc*_free+ runPostSets,_sbrk-_memset._memcpy/
+dynCall_ii0 dynCall_iiii1b02b1
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmstressstreamingbasicjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/stress/streaming-basic.js (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/stress/streaming-basic.js                             (rev 0)
+++ trunk/JSTests/wasm/stress/streaming-basic.js        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+import * as assert from '../assert.js';
+
+var data = read("./nameSection.wasm", "binary");
+
+function check(step)
+{
+    var parser = $vm.createWasmStreamingParser();
+    for (var i = 0; i < data.byteLength; i += step) {
+        parser.addBytes(data.subarray(i, i + Math.min(step, data.byteLength - i)));
+    }
+    assert.eq(parser.finalize(), 7);
+}
+
+for (var i = 0; i < 10; ++i)
+    check(i + 1);
+check(100);
+check(1000);
+check(2000);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/ChangeLog       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -1,3 +1,166 @@
</span><ins>+2018-08-27  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
+
+        [WebAssembly] Parse wasm modules in a streaming fashion
+        https://bugs.webkit.org/show_bug.cgi?id=188943
+
+        Reviewed by Mark Lam.
+
+        This patch adds Wasm::StreamingParser, which parses wasm binary in a streaming fashion.
+        Currently, this StreamingParser is not enabled and integrated. In subsequent patches,
+        we start integrating it into BBQPlan and dropping the old ModuleParser.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * tools/JSDollarVM.cpp:
+        (WTF::WasmStreamingParser::WasmStreamingParser):
+        (WTF::WasmStreamingParser::create):
+        (WTF::WasmStreamingParser::createStructure):
+        (WTF::WasmStreamingParser::streamingParser):
+        (WTF::WasmStreamingParser::finishCreation):
+        (WTF::functionWasmStreamingParserAddBytes):
+        (WTF::functionWasmStreamingParserFinalize):
+        (JSC::functionCreateWasmStreamingParser):
+        (JSC::JSDollarVM::finishCreation):
+        The $vm Wasm::StreamingParser object is introduced for testing purpose. Added new stress test uses
+        this interface to test streaming parser in the JSC shell.
+
+        * wasm/WasmBBQPlan.cpp:
+        (JSC::Wasm::BBQPlan::BBQPlan):
+        (JSC::Wasm::BBQPlan::parseAndValidateModule):
+        (JSC::Wasm::BBQPlan::prepare):
+        (JSC::Wasm::BBQPlan::compileFunctions):
+        (JSC::Wasm::BBQPlan::complete):
+        (JSC::Wasm::BBQPlan::work):
+        * wasm/WasmBBQPlan.h:
+        BBQPlan has m_source, but once ModuleInformation is parsed, it is no longer necessary.
+        In subsequent patches, we will remove this, and stream the data into the BBQPlan.
+
+        * wasm/WasmFormat.h:
+        * wasm/WasmModuleInformation.cpp:
+        (JSC::Wasm::ModuleInformation::ModuleInformation):
+        * wasm/WasmModuleInformation.h:
+        One of the largest change in this patch is that ModuleInformation no longer holds source bytes,
+        since source bytes can be added in a streaming fashion. Instead of holding all the source bytes
+        in ModuleInformation, each function (ModuleInformation::functions, FunctionData) should have
+        Vector<uint8_t> for its data. This data is eventually filled by StreamingParser, and compiling
+        a function with this data can be done concurrently with StreamingParser.
+
+        (JSC::Wasm::ModuleInformation::create):
+        (JSC::Wasm::ModuleInformation::memoryCount const):
+        (JSC::Wasm::ModuleInformation::tableCount const):
+        memoryCount and tableCount should be recorded in ModuleInformation.
+
+        * wasm/WasmModuleParser.cpp:
+        (JSC::Wasm::ModuleParser::parse):
+        (JSC::Wasm::makeI32InitExpr): Deleted.
+        (JSC::Wasm::ModuleParser::parseType): Deleted.
+        (JSC::Wasm::ModuleParser::parseImport): Deleted.
+        (JSC::Wasm::ModuleParser::parseFunction): Deleted.
+        (JSC::Wasm::ModuleParser::parseResizableLimits): Deleted.
+        (JSC::Wasm::ModuleParser::parseTableHelper): Deleted.
+        (JSC::Wasm::ModuleParser::parseTable): Deleted.
+        (JSC::Wasm::ModuleParser::parseMemoryHelper): Deleted.
+        (JSC::Wasm::ModuleParser::parseMemory): Deleted.
+        (JSC::Wasm::ModuleParser::parseGlobal): Deleted.
+        (JSC::Wasm::ModuleParser::parseExport): Deleted.
+        (JSC::Wasm::ModuleParser::parseStart): Deleted.
+        (JSC::Wasm::ModuleParser::parseElement): Deleted.
+        (JSC::Wasm::ModuleParser::parseCode): Deleted.
+        (JSC::Wasm::ModuleParser::parseInitExpr): Deleted.
+        (JSC::Wasm::ModuleParser::parseGlobalType): Deleted.
+        (JSC::Wasm::ModuleParser::parseData): Deleted.
+        (JSC::Wasm::ModuleParser::parseCustom): Deleted.
+        Extract section parsing code out from ModuleParser. We create SectionParser and ModuleParser uses it.
+        SectionParser is also used by StreamingParser.
+
+        * wasm/WasmModuleParser.h:
+        (): Deleted.
+        * wasm/WasmNameSection.h:
+        (JSC::Wasm::NameSection::NameSection):
+        (JSC::Wasm::NameSection::create):
+        (JSC::Wasm::NameSection::setHash):
+        Hash calculation is deferred since all the source is not available in streaming parsing.
+
+        * wasm/WasmNameSectionParser.cpp:
+        (JSC::Wasm::NameSectionParser::parse):
+        * wasm/WasmNameSectionParser.h:
+        Use Ref<NameSection>.
+
+        * wasm/WasmOMGPlan.cpp:
+        (JSC::Wasm::OMGPlan::work):
+        Wasm::Plan no longer have m_source since data will be eventually filled in a streaming fashion.
+        OMGPlan can get data of the function by using ModuleInformation::functions.
+
+        * wasm/WasmParser.h:
+        (JSC::Wasm::Parser::source const):
+        (JSC::Wasm::Parser::length const):
+        (JSC::Wasm::Parser::offset const):
+        (JSC::Wasm::Parser::fail const):
+        (JSC::Wasm::makeI32InitExpr):
+        * wasm/WasmPlan.cpp:
+        (JSC::Wasm::Plan::Plan):
+        Wasm::Plan should not have all the source apriori. Streamed data will be pumped from the provider.
+
+        * wasm/WasmPlan.h:
+        * wasm/WasmSectionParser.cpp: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.cpp.
+        SectionParser is extracted from ModuleParser. And it is used by both the old (currently working)
+        ModuleParser and the new StreamingParser.
+
+        (JSC::Wasm::SectionParser::parseType):
+        (JSC::Wasm::SectionParser::parseImport):
+        (JSC::Wasm::SectionParser::parseFunction):
+        (JSC::Wasm::SectionParser::parseResizableLimits):
+        (JSC::Wasm::SectionParser::parseTableHelper):
+        (JSC::Wasm::SectionParser::parseTable):
+        (JSC::Wasm::SectionParser::parseMemoryHelper):
+        (JSC::Wasm::SectionParser::parseMemory):
+        (JSC::Wasm::SectionParser::parseGlobal):
+        (JSC::Wasm::SectionParser::parseExport):
+        (JSC::Wasm::SectionParser::parseStart):
+        (JSC::Wasm::SectionParser::parseElement):
+        (JSC::Wasm::SectionParser::parseCode):
+        (JSC::Wasm::SectionParser::parseInitExpr):
+        (JSC::Wasm::SectionParser::parseGlobalType):
+        (JSC::Wasm::SectionParser::parseData):
+        (JSC::Wasm::SectionParser::parseCustom):
+        * wasm/WasmSectionParser.h: Copied from Source/JavaScriptCore/wasm/WasmModuleParser.h.
+        * wasm/WasmStreamingParser.cpp: Added.
+        (JSC::Wasm::parseUInt7):
+        (JSC::Wasm::StreamingParser::fail):
+        (JSC::Wasm::StreamingParser::StreamingParser):
+        (JSC::Wasm::StreamingParser::parseModuleHeader):
+        (JSC::Wasm::StreamingParser::parseSectionID):
+        (JSC::Wasm::StreamingParser::parseSectionSize):
+        (JSC::Wasm::StreamingParser::parseCodeSectionSize):
+        Code section in Wasm binary is specially handled compared with the other sections since it includes
+        a bunch of functions. StreamingParser extracts each function in a streaming fashion and enable
+        streaming validation / compilation of Wasm functions.
+
+        (JSC::Wasm::StreamingParser::parseFunctionSize):
+        (JSC::Wasm::StreamingParser::parseFunctionPayload):
+        (JSC::Wasm::StreamingParser::parseSectionPayload):
+        (JSC::Wasm::StreamingParser::consume):
+        (JSC::Wasm::StreamingParser::consumeVarUInt32):
+        (JSC::Wasm::StreamingParser::addBytes):
+        (JSC::Wasm::StreamingParser::failOnState):
+        (JSC::Wasm::StreamingParser::finalize):
+        * wasm/WasmStreamingParser.h: Added.
+        (JSC::Wasm::StreamingParser::addBytes):
+        (JSC::Wasm::StreamingParser::errorMessage const):
+        This is our new StreamingParser implementation. StreamingParser::consumeXXX functions get data, and
+        StreamingParser::parseXXX functions parse consumed data. The user of StreamingParser calls
+        StreamingParser::addBytes() to pump the bytes stream into the parser. And once all the data is pumped,
+        the user calls StreamingParser::finalize. StreamingParser is a state machine which feeds on the
+        incoming byte stream.
+
+        * wasm/js/JSWebAssemblyModule.cpp:
+        (JSC::JSWebAssemblyModule::source const): Deleted.
+        All the source should not be held.
+
+        * wasm/js/JSWebAssemblyModule.h:
+        * wasm/js/WebAssemblyPrototype.cpp:
+        (JSC::webAssemblyValidateFunc):
+
</ins><span class="cx"> 2018-08-27  Mark Lam  <mark.lam@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix exception throwing code so that topCallFrame and topEntryFrame stay true to their names.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj     2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -1733,6 +1733,8 @@
</span><span class="cx">          E393ADD81FE702D00022D681 /* WeakMapImplInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E393ADD71FE702CC0022D681 /* WeakMapImplInlines.h */; };
</span><span class="cx">          E39D45F51D39005600B3B377 /* InterpreterInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E39D9D841D39000600667282 /* InterpreterInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+               E3A0531A21342B680022EC14 /* WasmStreamingParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531621342B660022EC14 /* WasmStreamingParser.h */; };
+               E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531821342B670022EC14 /* WasmSectionParser.h */; };
</ins><span class="cx">           E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A32BC61FC8312E007D7E76 /* WeakMapImpl.h */; };
</span><span class="cx">          E3A421431D6F58930007C617 /* PreciseJumpTargetsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">          E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFD0BA1DAF807C0065DEA2 /* AccessCaseSnippetParams.h */; };
</span><span class="lines">@@ -4621,6 +4623,10 @@
</span><span class="cx">          E39D9D841D39000600667282 /* InterpreterInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InterpreterInlines.h; sourceTree = "<group>"; };
</span><span class="cx">          E39DA4A41B7E8B7C0084F33A /* JSModuleRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleRecord.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; };
</span><ins>+               E3A0531621342B660022EC14 /* WasmStreamingParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmStreamingParser.h; sourceTree = "<group>"; };
+               E3A0531721342B660022EC14 /* WasmSectionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSectionParser.cpp; sourceTree = "<group>"; };
+               E3A0531821342B670022EC14 /* WasmSectionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSectionParser.h; sourceTree = "<group>"; };
+               E3A0531921342B670022EC14 /* WasmStreamingParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmStreamingParser.cpp; sourceTree = "<group>"; };
</ins><span class="cx">           E3A32BC51FC8312D007D7E76 /* WeakMapImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WeakMapImpl.cpp; sourceTree = "<group>"; };
</span><span class="cx">          E3A32BC61FC8312E007D7E76 /* WeakMapImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakMapImpl.h; sourceTree = "<group>"; };
</span><span class="cx">          E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargetsInlines.h; sourceTree = "<group>"; };
</span><span class="lines">@@ -6351,9 +6357,13 @@
</span><span class="cx">                          53F40E8C1D5901F20099A1B6 /* WasmParser.h */,
</span><span class="cx">                          531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
</span><span class="cx">                          531374BC1D5CE67600AF7A0B /* WasmPlan.h */,
</span><ins>+                               E3A0531721342B660022EC14 /* WasmSectionParser.cpp */,
+                               E3A0531821342B670022EC14 /* WasmSectionParser.h */,
</ins><span class="cx">                           53F40E841D58F9770099A1B6 /* WasmSections.h */,
</span><span class="cx">                          AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
</span><span class="cx">                          AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
</span><ins>+                               E3A0531921342B670022EC14 /* WasmStreamingParser.cpp */,
+                               E3A0531621342B660022EC14 /* WasmStreamingParser.h */,
</ins><span class="cx">                           AD5C36E31F69EC8B000BCAAF /* WasmTable.cpp */,
</span><span class="cx">                          AD5C36E41F69EC8B000BCAAF /* WasmTable.h */,
</span><span class="cx">                          5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */,
</span><span class="lines">@@ -8450,7 +8460,6 @@
</span><span class="cx">                          C2FCAE1317A9C24E0034C735 /* BytecodeLivenessAnalysis.h in Headers */,
</span><span class="cx">                          0F666EC0183566F900D017F1 /* BytecodeLivenessAnalysisInlines.h in Headers */,
</span><span class="cx">                          E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */,
</span><del>-                               FEA3BBAC212C97CB00E93AD1 /* DFGCFG.h in Headers */,
</del><span class="cx">                           6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */,
</span><span class="cx">                          0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
</span><span class="cx">                          0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
</span><span class="lines">@@ -8582,6 +8591,7 @@
</span><span class="cx">                          0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */,
</span><span class="cx">                          0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */,
</span><span class="cx">                          0FFFC95814EF90A200C72532 /* DFGCFAPhase.h in Headers */,
</span><ins>+                               FEA3BBAC212C97CB00E93AD1 /* DFGCFG.h in Headers */,
</ins><span class="cx">                           0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
</span><span class="cx">                          0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
</span><span class="cx">                          A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
</span><span class="lines">@@ -9609,8 +9619,10 @@
</span><span class="cx">                          79B759761DFA4C600052174C /* WasmPageCount.h in Headers */,
</span><span class="cx">                          53F40E8D1D5901F20099A1B6 /* WasmParser.h in Headers */,
</span><span class="cx">                          531374BD1D5CE67600AF7A0B /* WasmPlan.h in Headers */,
</span><ins>+                               E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */,
</ins><span class="cx">                           53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */,
</span><span class="cx">                          AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
</span><ins>+                               E3A0531A21342B680022EC14 /* WasmStreamingParser.h in Headers */,
</ins><span class="cx">                           AD5C36E61F69EC91000BCAAF /* WasmTable.h in Headers */,
</span><span class="cx">                          5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */,
</span><span class="cx">                          53E9E0AF1EAEC45700FEE251 /* WasmTierUpCount.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreSourcestxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/Sources.txt (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/Sources.txt  2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/Sources.txt     2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -991,7 +991,9 @@
</span><span class="cx"> wasm/WasmOpcodeOrigin.cpp
</span><span class="cx"> wasm/WasmPageCount.cpp
</span><span class="cx"> wasm/WasmPlan.cpp
</span><ins>+wasm/WasmSectionParser.cpp
</ins><span class="cx"> wasm/WasmSignature.cpp
</span><ins>+wasm/WasmStreamingParser.cpp
</ins><span class="cx"> wasm/WasmTable.cpp
</span><span class="cx"> wasm/WasmTable.h
</span><span class="cx"> wasm/WasmThunks.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretoolsJSDollarVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp 2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/tools/JSDollarVM.cpp    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -51,6 +51,11 @@
</span><span class="cx"> #include <wtf/ProcessID.h>
</span><span class="cx"> #include <wtf/StringPrintStream.h>
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+#include "JSWebAssemblyHelpers.h"
+#include "WasmStreamingParser.h"
+#endif
+
</ins><span class="cx"> using namespace JSC;
</span><span class="cx"> using namespace WTF;
</span><span class="cx"> 
</span><span class="lines">@@ -1093,6 +1098,80 @@
</span><span class="cx">     m_root->setElement(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+
+static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(ExecState*);
+
+class WasmStreamingParser : public JSDestructibleObject {
+public:
+    WasmStreamingParser(VM& vm, Structure* structure)
+        : Base(vm, structure)
+        , m_info(Wasm::ModuleInformation::create())
+        , m_streamingParser(m_info.get())
+    {
+    }
+
+    using Base = JSDestructibleObject;
+
+    static WasmStreamingParser* create(VM& vm, JSGlobalObject* globalObject)
+    {
+        Structure* structure = createStructure(vm, globalObject, jsNull());
+        WasmStreamingParser* result = new (NotNull, allocateCell<WasmStreamingParser>(vm.heap, sizeof(WasmStreamingParser))) WasmStreamingParser(vm, structure);
+        result->finishCreation(vm);
+        return result;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    Wasm::StreamingParser& streamingParser() { return m_streamingParser; }
+
+    void finishCreation(VM& vm)
+    {
+        Base::finishCreation(vm);
+
+        JSGlobalObject* globalObject = this->globalObject(vm);
+        putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "addBytes"), 0, functionWasmStreamingParserAddBytes, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
+        putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "finalize"), 0, functionWasmStreamingParserFinalize, NoIntrinsic, static_cast<unsigned>(PropertyAttribute::DontEnum));
+    }
+
+    DECLARE_INFO;
+
+    Ref<Wasm::ModuleInformation> m_info;
+    Wasm::StreamingParser m_streamingParser;
+};
+
+const ClassInfo WasmStreamingParser::s_info = { "WasmStreamingParser", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WasmStreamingParser) };
+
+EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserAddBytes(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto scope = DECLARE_THROW_SCOPE(exec->vm());
+    auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, exec->thisValue());
+    if (!thisObject) {
+        scope.release();
+        return JSValue::encode(jsBoolean(false));
+    }
+    auto data = getWasmBufferFromValue(exec, exec->argument(0));
+    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    scope.release();
+    return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().addBytes(bitwise_cast<const uint8_t*>(data.first), data.second))));
+}
+
+EncodedJSValue JSC_HOST_CALL functionWasmStreamingParserFinalize(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    auto* thisObject = jsDynamicCast<WasmStreamingParser*>(vm, exec->thisValue());
+    if (!thisObject)
+        return JSValue::encode(jsBoolean(false));
+    return JSValue::encode(jsNumber(static_cast<int32_t>(thisObject->streamingParser().finalize())));
+}
+
+#endif
+
</ins><span class="cx"> } // namespace
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -1640,6 +1719,15 @@
</span><span class="cx">     return JSValue::encode(result);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+static EncodedJSValue JSC_HOST_CALL functionCreateWasmStreamingParser(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSLockHolder lock(vm);
+    return JSValue::encode(WasmStreamingParser::create(vm, exec->lexicalGlobalObject()));
+}
+#endif
+
</ins><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     VM& vm = exec->vm();
</span><span class="lines">@@ -2040,6 +2128,9 @@
</span><span class="cx">     addFunction(vm, "createDOMJITCheckSubClassObject", functionCreateDOMJITCheckSubClassObject, 0);
</span><span class="cx">     addFunction(vm, "createDOMJITGetterBaseJSObject", functionCreateDOMJITGetterBaseJSObject, 0);
</span><span class="cx">     addFunction(vm, "createBuiltin", functionCreateBuiltin, 2);
</span><ins>+#if ENABLE(WEBASSEMBLY)
+    addFunction(vm, "createWasmStreamingParser", functionCreateWasmStreamingParser, 0);
+#endif
</ins><span class="cx">     addFunction(vm, "getPrivateProperty", functionGetPrivateProperty, 2);
</span><span class="cx">     addFunction(vm, "setImpureGetterDelegate", functionSetImpureGetterDelegate, 2);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmBBQPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp 2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -59,13 +59,15 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> BBQPlan::BBQPlan(Context* context, Vector<uint8_t>&& source, AsyncWork work, CompletionTask&& task, CreateEmbedderWrapper&& createEmbedderWrapper, ThrowWasmException throwWasmException)
</span><del>-    : BBQPlan(context, adoptRef(*new ModuleInformation(WTFMove(source))), work, WTFMove(task), WTFMove(createEmbedderWrapper), throwWasmException)
</del><ins>+    : Base(context, ModuleInformation::create(), WTFMove(task), WTFMove(createEmbedderWrapper), throwWasmException)
+    , m_source(WTFMove(source))
+    , m_state(State::Initial)
+    , m_asyncWork(work)
</ins><span class="cx"> {
</span><del>-    m_state = State::Initial;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-BBQPlan::BBQPlan(Context* context, const uint8_t* source, size_t sourceLength, AsyncWork work, CompletionTask&& task)
-    : Base(context, source, sourceLength, WTFMove(task))
</del><ins>+BBQPlan::BBQPlan(Context* context, AsyncWork work, CompletionTask&& task)
+    : Base(context, WTFMove(task))
</ins><span class="cx">     , m_state(State::Initial)
</span><span class="cx">     , m_asyncWork(work)
</span><span class="cx"> {
</span><span class="lines">@@ -90,7 +92,7 @@
</span><span class="cx">     m_state = state;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool BBQPlan::parseAndValidateModule()
</del><ins>+bool BBQPlan::parseAndValidateModule(const uint8_t* source, size_t sourceLength)
</ins><span class="cx"> {
</span><span class="cx">     if (m_state != State::Initial)
</span><span class="cx">         return true;
</span><span class="lines">@@ -101,7 +103,7 @@
</span><span class="cx">         startTime = MonotonicTime::now();
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        ModuleParser moduleParser(m_source, m_sourceLength, m_moduleInformation);
</del><ins>+        ModuleParser moduleParser(source, sourceLength, m_moduleInformation);
</ins><span class="cx">         auto parseResult = moduleParser.parse();
</span><span class="cx">         if (!parseResult) {
</span><span class="cx">             Base::fail(holdLock(m_lock), WTFMove(parseResult.error()));
</span><span class="lines">@@ -109,20 +111,21 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
-    for (unsigned functionIndex = 0; functionIndex < functionLocations.size(); ++functionIndex) {
-        dataLogLnIf(WasmBBQPlanInternal::verbose, "Processing function starting at: ", functionLocations[functionIndex].start, " and ending at: ", functionLocations[functionIndex].end);
-        const uint8_t* functionStart = m_source + functionLocations[functionIndex].start;
-        size_t functionLength = functionLocations[functionIndex].end - functionLocations[functionIndex].start;
-        ASSERT(functionLength <= m_sourceLength);
</del><ins>+    const auto& functions = m_moduleInformation->functions;
+    for (unsigned functionIndex = 0; functionIndex < functions.size(); ++functionIndex) {
+        const auto& function = functions[functionIndex];
+        dataLogLnIf(WasmBBQPlanInternal::verbose, "Processing function starting at: ", function.start, " and ending at: ", function.end);
+        size_t functionLength = function.end - function.start;
+        ASSERT(functionLength <= sourceLength);
+        ASSERT(functionLength == function.data.size());
</ins><span class="cx">         SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
</span><span class="cx">         const Signature& signature = SignatureInformation::get(signatureIndex);
</span><span class="cx"> 
</span><del>-        auto validationResult = validateFunction(functionStart, functionLength, signature, m_moduleInformation.get());
</del><ins>+        auto validationResult = validateFunction(function.data.data(), function.data.size(), signature, m_moduleInformation.get());
</ins><span class="cx">         if (!validationResult) {
</span><span class="cx">             if (WasmBBQPlanInternal::verbose) {
</span><span class="cx">                 for (unsigned i = 0; i < functionLength; ++i)
</span><del>-                    dataLog(RawPointer(reinterpret_cast<void*>(functionStart[i])), ", ");
</del><ins>+                    dataLog(RawPointer(reinterpret_cast<void*>(function.data[i])), ", ");
</ins><span class="cx">                 dataLogLn();
</span><span class="cx">             }
</span><span class="cx">             Base::fail(holdLock(m_lock), makeString(validationResult.error(), ", in function at index ", String::number(functionIndex))); // FIXME make this an Expected.
</span><span class="lines">@@ -156,18 +159,18 @@
</span><span class="cx">         return true;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
</del><ins>+    const auto& functions = m_moduleInformation->functions;
</ins><span class="cx">     if (!tryReserveCapacity(m_wasmToWasmExitStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")
</span><del>-        || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, functionLocations.size(), " unlinked WebAssembly to WebAssembly calls")
-        || !tryReserveCapacity(m_wasmInternalFunctions, functionLocations.size(), " WebAssembly functions")
-        || !tryReserveCapacity(m_compilationContexts, functionLocations.size(), " compilation contexts")
-        || !tryReserveCapacity(m_tierUpCounts, functionLocations.size(), " tier-up counts"))
</del><ins>+        || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, functions.size(), " unlinked WebAssembly to WebAssembly calls")
+        || !tryReserveCapacity(m_wasmInternalFunctions, functions.size(), " WebAssembly functions")
+        || !tryReserveCapacity(m_compilationContexts, functions.size(), " compilation contexts")
+        || !tryReserveCapacity(m_tierUpCounts, functions.size(), " tier-up counts"))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    m_unlinkedWasmToWasmCalls.resize(functionLocations.size());
-    m_wasmInternalFunctions.resize(functionLocations.size());
-    m_compilationContexts.resize(functionLocations.size());
-    m_tierUpCounts.resize(functionLocations.size());
</del><ins>+    m_unlinkedWasmToWasmCalls.resize(functions.size());
+    m_wasmInternalFunctions.resize(functions.size());
+    m_compilationContexts.resize(functions.size());
+    m_tierUpCounts.resize(functions.size());
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned importIndex = 0; importIndex < m_moduleInformation->imports.size(); ++importIndex) {
</span><span class="cx">         Import* import = &m_moduleInformation->imports[importIndex];
</span><span class="lines">@@ -241,7 +244,7 @@
</span><span class="cx">     ThreadCountHolder holder(*this);
</span><span class="cx"> 
</span><span class="cx">     size_t bytesCompiled = 0;
</span><del>-    const auto& functionLocations = m_moduleInformation->functionLocationInBinary;
</del><ins>+    const auto& functions = m_moduleInformation->functions;
</ins><span class="cx">     while (true) {
</span><span class="cx">         if (effort == Partial && bytesCompiled >= Options::webAssemblyPartialCompileLimit())
</span><span class="cx">             return;
</span><span class="lines">@@ -249,7 +252,7 @@
</span><span class="cx">         uint32_t functionIndex;
</span><span class="cx">         {
</span><span class="cx">             auto locker = holdLock(m_lock);
</span><del>-            if (m_currentIndex >= functionLocations.size()) {
</del><ins>+            if (m_currentIndex >= functions.size()) {
</ins><span class="cx">                 if (hasWork())
</span><span class="cx">                     moveToState(State::Compiled);
</span><span class="cx">                 return;
</span><span class="lines">@@ -258,18 +261,16 @@
</span><span class="cx">             ++m_currentIndex;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        const uint8_t* functionStart = m_source + functionLocations[functionIndex].start;
-        size_t functionLength = functionLocations[functionIndex].end - functionLocations[functionIndex].start;
-        ASSERT(functionLength <= m_sourceLength);
</del><ins>+        const auto& function = functions[functionIndex];
</ins><span class="cx">         SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
</span><span class="cx">         const Signature& signature = SignatureInformation::get(signatureIndex);
</span><span class="cx">         unsigned functionIndexSpace = m_wasmToWasmExitStubs.size() + functionIndex;
</span><span class="cx">         ASSERT_UNUSED(functionIndexSpace, m_moduleInformation->signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex);
</span><del>-        ASSERT(validateFunction(functionStart, functionLength, signature, m_moduleInformation.get()));
</del><ins>+        ASSERT(validateFunction(function.data.data(), function.data.size(), signature, m_moduleInformation.get()));
</ins><span class="cx"> 
</span><span class="cx">         m_unlinkedWasmToWasmCalls[functionIndex] = Vector<UnlinkedWasmToWasmCall>();
</span><span class="cx">         TierUpCount* tierUp = Options::useBBQTierUpChecks() ? &m_tierUpCounts[functionIndex] : nullptr;
</span><del>-        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, tierUp, m_throwWasmException);
</del><ins>+        auto parseAndCompileResult = parseAndCompile(m_compilationContexts[functionIndex], function.data.data(), function.data.size(), signature, m_unlinkedWasmToWasmCalls[functionIndex], m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, tierUp, m_throwWasmException);
</ins><span class="cx"> 
</span><span class="cx">         if (UNLIKELY(!parseAndCompileResult)) {
</span><span class="cx">             auto locker = holdLock(m_lock);
</span><span class="lines">@@ -277,7 +278,7 @@
</span><span class="cx">                 // Multiple compiles could fail simultaneously. We arbitrarily choose the first.
</span><span class="cx">                 fail(locker, makeString(parseAndCompileResult.error(), ", in function at index ", String::number(functionIndex))); // FIXME make this an Expected.
</span><span class="cx">             }
</span><del>-            m_currentIndex = functionLocations.size();
</del><ins>+            m_currentIndex = functions.size();
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -289,17 +290,17 @@
</span><span class="cx">             ASSERT_UNUSED(result, result.isNewEntry);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        bytesCompiled += functionLength;
</del><ins>+        bytesCompiled += function.data.size();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void BBQPlan::complete(const AbstractLocker& locker)
</span><span class="cx"> {
</span><del>-    ASSERT(m_state != State::Compiled || m_currentIndex >= m_moduleInformation->functionLocationInBinary.size());
</del><ins>+    ASSERT(m_state != State::Compiled || m_currentIndex >= m_moduleInformation->functions.size());
</ins><span class="cx">     dataLogLnIf(WasmBBQPlanInternal::verbose, "Starting Completion");
</span><span class="cx"> 
</span><span class="cx">     if (!failed() && m_state == State::Compiled) {
</span><del>-        for (uint32_t functionIndex = 0; functionIndex < m_moduleInformation->functionLocationInBinary.size(); functionIndex++) {
</del><ins>+        for (uint32_t functionIndex = 0; functionIndex < m_moduleInformation->functions.size(); functionIndex++) {
</ins><span class="cx">             CompilationContext& context = m_compilationContexts[functionIndex];
</span><span class="cx">             SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex];
</span><span class="cx">             const Signature& signature = SignatureInformation::get(signatureIndex);
</span><span class="lines">@@ -351,7 +352,7 @@
</span><span class="cx"> {
</span><span class="cx">     switch (m_state) {
</span><span class="cx">     case State::Initial:
</span><del>-        parseAndValidateModule();
</del><ins>+        parseAndValidateModule(m_source.data(), m_source.size());
</ins><span class="cx">         if (!hasWork()) {
</span><span class="cx">             ASSERT(isComplete());
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmBBQPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h   2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h      2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -52,12 +52,15 @@
</span><span class="cx">     // Note: CompletionTask should not hold a reference to the Plan otherwise there will be a reference cycle.
</span><span class="cx">     BBQPlan(Context*, Ref<ModuleInformation>, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
</span><span class="cx">     JS_EXPORT_PRIVATE BBQPlan(Context*, Vector<uint8_t>&&, AsyncWork, CompletionTask&&, CreateEmbedderWrapper&&, ThrowWasmException);
</span><del>-    // Note: This constructor should only be used if you are not actually building a module e.g. validation/function tests
-    // FIXME: When we get rid of function tests we should remove AsyncWork from this constructor.
-    JS_EXPORT_PRIVATE BBQPlan(Context*, const uint8_t*, size_t, AsyncWork, CompletionTask&&);
</del><ins>+    BBQPlan(Context*, AsyncWork, CompletionTask&&);
</ins><span class="cx"> 
</span><del>-    bool parseAndValidateModule();
</del><span class="cx"> 
</span><ins>+    bool parseAndValidateModule()
+    {
+        return parseAndValidateModule(m_source.data(), m_source.size());
+    }
+    bool parseAndValidateModule(const uint8_t*, size_t);
+
</ins><span class="cx">     JS_EXPORT_PRIVATE void prepare();
</span><span class="cx">     void compileFunctions(CompilationEffort);
</span><span class="cx"> 
</span><span class="lines">@@ -136,6 +139,7 @@
</span><span class="cx"> 
</span><span class="cx">     const char* stateString(State);
</span><span class="cx">     
</span><ins>+    Vector<uint8_t> m_source;
</ins><span class="cx">     Bag<CallLinkInfo> m_callLinkInfos;
</span><span class="cx">     Vector<MacroAssemblerCodeRef<WasmEntryPtrTag>> m_wasmToWasmExitStubs;
</span><span class="cx">     Vector<std::unique_ptr<InternalFunction>> m_wasmInternalFunctions;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFormath"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFormat.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFormat.h    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmFormat.h       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -140,9 +140,10 @@
</span><span class="cx">     uint64_t initialBitsOrImportNumber { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-struct FunctionLocationInBinary {
</del><ins>+struct FunctionData {
</ins><span class="cx">     size_t start;
</span><span class="cx">     size_t end;
</span><ins>+    Vector<uint8_t> data;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class I32InitExpr {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleInformationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.cpp       2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.cpp  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -31,21 +31,10 @@
</span><span class="cx"> #include "WasmNameSection.h"
</span><span class="cx"> #include <wtf/SHA1.h>
</span><span class="cx"> 
</span><del>-namespace {
-CString sha1(const Vector<uint8_t>& input)
-{
-    SHA1 hash;
-    hash.addBytes(input);
-    return hash.computeHexDigest();
-}
-}
-
</del><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><del>-ModuleInformation::ModuleInformation(Vector<uint8_t>&& sourceBytes)
-    : source(WTFMove(sourceBytes))
-    , hash(Options::useEagerWebAssemblyModuleHashing() ? std::make_optional(sha1(source)) : std::nullopt)
-    , nameSection(new NameSection(hash))
</del><ins>+ModuleInformation::ModuleInformation()
+    : nameSection(NameSection::create())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> ModuleInformation::~ModuleInformation() { }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleInformationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h 2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -34,11 +34,14 @@
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><span class="cx"> struct ModuleInformation : public ThreadSafeRefCounted<ModuleInformation> {
</span><del>-    ModuleInformation() = delete;
</del><ins>+    ModuleInformation();
</ins><span class="cx">     ModuleInformation(const ModuleInformation&) = delete;
</span><span class="cx">     ModuleInformation(ModuleInformation&&) = delete;
</span><span class="cx"> 
</span><del>-    ModuleInformation(Vector<uint8_t>&& sourceBytes);
</del><ins>+    static Ref<ModuleInformation> create()
+    {
+        return adoptRef(*new ModuleInformation);
+    }
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE ~ModuleInformation();
</span><span class="cx">     
</span><span class="lines">@@ -58,8 +61,10 @@
</span><span class="cx">     uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); }
</span><span class="cx">     uint32_t internalFunctionCount() const { return internalFunctionSignatureIndices.size(); }
</span><span class="cx"> 
</span><del>-    const Vector<uint8_t> source;
-    const std::optional<CString> hash;
</del><ins>+    // Currently, our wasm implementation allows only one memory and table.
+    // If we need to remove this limitation, we would have MemoryInformation and TableInformation in the Vectors.
+    uint32_t memoryCount() const { return memory ? 1 : 0; }
+    uint32_t tableCount() const { return tableInformation ? 1 : 0; }
</ins><span class="cx"> 
</span><span class="cx">     Vector<Import> imports;
</span><span class="cx">     Vector<SignatureIndex> importFunctionSignatureIndices;
</span><span class="lines">@@ -68,7 +73,7 @@
</span><span class="cx"> 
</span><span class="cx">     MemoryInformation memory;
</span><span class="cx"> 
</span><del>-    Vector<FunctionLocationInBinary> functionLocationInBinary;
</del><ins>+    Vector<FunctionData> functions;
</ins><span class="cx"> 
</span><span class="cx">     Vector<Export> exports;
</span><span class="cx">     std::optional<uint32_t> startFunctionIndexSpace;
</span><span class="lines">@@ -78,7 +83,7 @@
</span><span class="cx">     Vector<Global> globals;
</span><span class="cx">     unsigned firstInternalGlobal { 0 };
</span><span class="cx">     Vector<CustomSection> customSections;
</span><del>-    RefPtr<NameSection> nameSection;
</del><ins>+    Ref<NameSection> nameSection;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -32,18 +32,11 @@
</span><span class="cx"> #include "WasmMemoryInformation.h"
</span><span class="cx"> #include "WasmNameSectionParser.h"
</span><span class="cx"> #include "WasmOps.h"
</span><ins>+#include "WasmSectionParser.h"
</ins><span class="cx"> #include "WasmSections.h"
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><del>-ALWAYS_INLINE I32InitExpr makeI32InitExpr(uint8_t opcode, uint32_t bits)
-{
-    RELEASE_ASSERT(opcode == I32Const || opcode == GetGlobal);
-    if (opcode == I32Const)
-        return I32InitExpr::constValue(bits);
-    return I32InitExpr::globalImport(bits);
-}
-
</del><span class="cx"> auto ModuleParser::parse() -> Result
</span><span class="cx"> {
</span><span class="cx">     const size_t minSize = 8;
</span><span class="lines">@@ -71,12 +64,12 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(sectionLength), "can't get ", section, " section's length");
</span><span class="cx">         WASM_PARSER_FAIL_IF(sectionLength > length() - m_offset, section, " section of size ", sectionLength, " would overflow Module's size");
</span><span class="cx"> 
</span><del>-        auto end = m_offset + sectionLength;
</del><ins>+        SectionParser parser(source() + m_offset, sectionLength, m_offset, m_info.get());
</ins><span class="cx"> 
</span><span class="cx">         switch (section) {
</span><span class="cx"> #define WASM_SECTION_PARSE(NAME, ID, DESCRIPTION)                   \
</span><span class="cx">         case Section::NAME: {                                       \
</span><del>-            WASM_FAIL_IF_HELPER_FAILS(parse ## NAME());             \
</del><ins>+            WASM_FAIL_IF_HELPER_FAILS(parser.parse ## NAME());             \
</ins><span class="cx">             break;                                                  \
</span><span class="cx">         }
</span><span class="cx">         FOR_EACH_KNOWN_WASM_SECTION(WASM_SECTION_PARSE)
</span><span class="lines">@@ -83,7 +76,7 @@
</span><span class="cx"> #undef WASM_SECTION_PARSE
</span><span class="cx"> 
</span><span class="cx">         case Section::Custom: {
</span><del>-            WASM_FAIL_IF_HELPER_FAILS(parseCustom(sectionLength));
</del><ins>+            WASM_FAIL_IF_HELPER_FAILS(parser.parseCustom());
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -93,538 +86,24 @@
</span><span class="cx">         }
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        WASM_PARSER_FAIL_IF(end != m_offset, "parsing ended before the end of ", section, " section");
</del><ins>+        WASM_PARSER_FAIL_IF(parser.length() != parser.offset(), "parsing ended before the end of ", section, " section");
</ins><span class="cx"> 
</span><ins>+        m_offset += sectionLength;
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx">         if (isKnownSection(section))
</span><span class="cx">             previousKnownSection = section;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return { };
-}
-
-auto ModuleParser::parseType() -> PartialResult
-{
-    uint32_t count;
-
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count");
-    WASM_PARSER_FAIL_IF(count > maxTypes, "Type section's count is too big ", count, " maximum ", maxTypes);
-    WASM_PARSER_FAIL_IF(!m_info->usedSignatures.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
-
-    for (uint32_t i = 0; i < count; ++i) {
-        int8_t type;
-        uint32_t argumentCount;
-        Vector<Type> argumentTypes;
-
-        WASM_PARSER_FAIL_IF(!parseInt7(type), "can't get ", i, "th Type's type");
-        WASM_PARSER_FAIL_IF(type != Func, i, "th Type is non-Func ", type);
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get ", i, "th Type's argument count");
-        WASM_PARSER_FAIL_IF(argumentCount > maxFunctionParams, i, "th argument count is too big ", argumentCount, " maximum ", maxFunctionParams);
-        RefPtr<Signature> maybeSignature = Signature::tryCreate(argumentCount);
-        WASM_PARSER_FAIL_IF(!maybeSignature, "can't allocate enough memory for Type section's ", i, "th signature");
-        Ref<Signature> signature = maybeSignature.releaseNonNull();
-
-        for (unsigned i = 0; i < argumentCount; ++i) {
-            Type argumentType;
-            WASM_PARSER_FAIL_IF(!parseValueType(argumentType), "can't get ", i, "th argument Type");
-            signature->argument(i) = argumentType;
-        }
-
-        uint8_t returnCount;
-        WASM_PARSER_FAIL_IF(!parseVarUInt1(returnCount), "can't get ", i, "th Type's return count");
-        Type returnType;
-        if (returnCount) {
-            Type value;
-            WASM_PARSER_FAIL_IF(!parseValueType(value), "can't get ", i, "th Type's return value");
-            returnType = static_cast<Type>(value);
-        } else
-            returnType = Type::Void;
-        signature->returnType() = returnType;
-
-        std::pair<SignatureIndex, Ref<Signature>> result = SignatureInformation::adopt(WTFMove(signature));
-        m_info->usedSignatures.uncheckedAppend(WTFMove(result.second));
</del><ins>+    if (UNLIKELY(Options::useEagerWebAssemblyModuleHashing())) {
+        SHA1 hasher;
+        hasher.addBytes(source(), length());
+        m_info->nameSection->setHash(hasher.computeHexDigest());
</ins><span class="cx">     }
</span><del>-    return { };
-}
</del><span class="cx"> 
</span><del>-auto ModuleParser::parseImport() -> PartialResult
-{
-    uint32_t importCount;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(importCount), "can't get Import section's count");
-    WASM_PARSER_FAIL_IF(importCount > maxImports, "Import section's count is too big ", importCount, " maximum ", maxImports);
-    WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below.
-    WASM_PARSER_FAIL_IF(!m_info->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below.
-    WASM_PARSER_FAIL_IF(!m_info->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below.
-
-    for (uint32_t importNumber = 0; importNumber < importCount; ++importNumber) {
-        uint32_t moduleLen;
-        uint32_t fieldLen;
-        Name moduleString;
-        Name fieldString;
-        ExternalKind kind;
-        unsigned kindIndex { 0 };
-
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(moduleLen), "can't get ", importNumber, "th Import's module name length");
-        WASM_PARSER_FAIL_IF(!consumeUTF8String(moduleString, moduleLen), "can't get ", importNumber, "th Import's module name of length ", moduleLen);
-
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", importNumber, "th Import's field name length in module '", moduleString, "'");
-        WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", importNumber, "th Import's field name of length ", moduleLen, " in module '", moduleString, "'");
-
-        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", importNumber, "th Import's kind in module '", moduleString, "' field '", fieldString, "'");
-        switch (kind) {
-        case ExternalKind::Function: {
-            uint32_t functionSignatureIndex;
-            WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSignatureIndex), "can't get ", importNumber, "th Import's function signature in module '", moduleString, "' field '", fieldString, "'");
-            WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_info->usedSignatures.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_info->usedSignatures.size(), " in module '", moduleString, "' field '", fieldString, "'");
-            kindIndex = m_info->importFunctionSignatureIndices.size();
-            SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[functionSignatureIndex]);
-            m_info->importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
-            break;
-        }
-        case ExternalKind::Table: {
-            bool isImport = true;
-            PartialResult result = parseTableHelper(isImport);
-            if (UNLIKELY(!result))
-                return makeUnexpected(WTFMove(result.error()));
-            break;
-        }
-        case ExternalKind::Memory: {
-            bool isImport = true;
-            PartialResult result = parseMemoryHelper(isImport);
-            if (UNLIKELY(!result))
-                return makeUnexpected(WTFMove(result.error()));
-            break;
-        }
-        case ExternalKind::Global: {
-            Global global;
-            WASM_FAIL_IF_HELPER_FAILS(parseGlobalType(global));
-            WASM_PARSER_FAIL_IF(global.mutability == Global::Mutable, "Mutable Globals aren't supported");
-
-            kindIndex = m_info->globals.size();
-            m_info->globals.uncheckedAppend(WTFMove(global));
-            break;
-        }
-        }
-
-        m_info->imports.uncheckedAppend({ WTFMove(moduleString), WTFMove(fieldString), kind, kindIndex });
-    }
-
-    m_info->firstInternalGlobal = m_info->globals.size();
</del><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-auto ModuleParser::parseFunction() -> PartialResult
-{
-    uint32_t count;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count");
-    WASM_PARSER_FAIL_IF(count > maxFunctions, "Function section's count is too big ", count, " maximum ", maxFunctions);
-    WASM_PARSER_FAIL_IF(!m_info->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");
-    WASM_PARSER_FAIL_IF(!m_info->functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
-
-    for (uint32_t i = 0; i < count; ++i) {
-        uint32_t typeNumber;
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", i, "th Function's type number");
-        WASM_PARSER_FAIL_IF(typeNumber >= m_info->usedSignatures.size(), i, "th Function type number is invalid ", typeNumber);
-
-        SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[typeNumber]);
-        // The Code section fixes up start and end.
-        size_t start = 0;
-        size_t end = 0;
-        m_info->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
-        m_info->functionLocationInBinary.uncheckedAppend({ start, end });
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum) -> PartialResult
-{
-    ASSERT(!maximum);
-
-    uint8_t flags;
-    WASM_PARSER_FAIL_IF(!parseVarUInt1(flags), "can't parse resizable limits flags");
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(initial), "can't parse resizable limits initial page count");
-
-    if (flags) {
-        uint32_t maximumInt;
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(maximumInt), "can't parse resizable limits maximum page count");
-        WASM_PARSER_FAIL_IF(initial > maximumInt, "resizable limits has a initial page count of ", initial, " which is greater than its maximum ", maximumInt);
-        maximum = maximumInt;
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseTableHelper(bool isImport) -> PartialResult
-{
-    WASM_PARSER_FAIL_IF(m_tableCount > 0, "Cannot have more than one Table for now");
-
-    ++m_tableCount;
-
-    int8_t type;
-    WASM_PARSER_FAIL_IF(!parseInt7(type), "can't parse Table type");
-    WASM_PARSER_FAIL_IF(type != Wasm::Anyfunc, "Table type should be anyfunc, got ", type);
-
-    uint32_t initial;
-    std::optional<uint32_t> maximum;
-    PartialResult limits = parseResizableLimits(initial, maximum);
-    if (UNLIKELY(!limits))
-        return makeUnexpected(WTFMove(limits.error()));
-    WASM_PARSER_FAIL_IF(initial > maxTableEntries, "Table's initial page count of ", initial, " is too big, maximum ", maxTableEntries);
-
-    ASSERT(!maximum || *maximum >= initial);
-
-    m_info->tableInformation = TableInformation(initial, maximum, isImport);
-
-    return { };
-}
-
-auto ModuleParser::parseTable() -> PartialResult
-{
-    uint32_t count;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Table's count");
-    WASM_PARSER_FAIL_IF(count > 1, "Table count of ", count, " is invalid, at most 1 is allowed for now");
-
-    if (!count)
-        return { };
-
-    bool isImport = false;
-    PartialResult result = parseTableHelper(isImport);
-    if (UNLIKELY(!result))
-        return makeUnexpected(WTFMove(result.error()));
-
-    return { };
-}
-
-auto ModuleParser::parseMemoryHelper(bool isImport) -> PartialResult
-{
-    WASM_PARSER_FAIL_IF(m_memoryCount, "there can at most be one Memory section for now");
-
-    ++m_memoryCount;
-
-    PageCount initialPageCount;
-    PageCount maximumPageCount;
-    {
-        uint32_t initial;
-        std::optional<uint32_t> maximum;
-        PartialResult limits = parseResizableLimits(initial, maximum);
-        if (UNLIKELY(!limits))
-            return makeUnexpected(WTFMove(limits.error()));
-        ASSERT(!maximum || *maximum >= initial);
-        WASM_PARSER_FAIL_IF(!PageCount::isValid(initial), "Memory's initial page count of ", initial, " is invalid");
-
-        initialPageCount = PageCount(initial);
-
-        if (maximum) {
-            WASM_PARSER_FAIL_IF(!PageCount::isValid(*maximum), "Memory's maximum page count of ", *maximum, " is invalid");
-            maximumPageCount = PageCount(*maximum);
-        }
-    }
-    ASSERT(initialPageCount);
-    ASSERT(!maximumPageCount || maximumPageCount >= initialPageCount);
-
-    m_info->memory = MemoryInformation(initialPageCount, maximumPageCount, isImport);
-    return { };
-}
-
-auto ModuleParser::parseMemory() -> PartialResult
-{
-    uint8_t count;
-    WASM_PARSER_FAIL_IF(!parseVarUInt1(count), "can't parse Memory section's count");
-
-    if (!count)
-        return { };
-
-    WASM_PARSER_FAIL_IF(count != 1, "Memory section has more than one memory, WebAssembly currently only allows zero or one");
-
-    bool isImport = false;
-    return parseMemoryHelper(isImport);
-}
-
-auto ModuleParser::parseGlobal() -> PartialResult
-{
-    uint32_t globalCount;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(globalCount), "can't get Global section's count");
-    WASM_PARSER_FAIL_IF(globalCount > maxGlobals, "Global section's count is too big ", globalCount, " maximum ", maxGlobals);
-    size_t totalBytes = globalCount + m_info->firstInternalGlobal;
-    WASM_PARSER_FAIL_IF((static_cast<uint32_t>(totalBytes) < globalCount) || !m_info->globals.tryReserveCapacity(totalBytes), "can't allocate memory for ", totalBytes, " globals");
-
-    for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) {
-        Global global;
-        uint8_t initOpcode;
-
-        WASM_FAIL_IF_HELPER_FAILS(parseGlobalType(global));
-        Type typeForInitOpcode;
-        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, global.initialBitsOrImportNumber, typeForInitOpcode));
-        if (initOpcode == GetGlobal)
-            global.initializationType = Global::FromGlobalImport;
-        else
-            global.initializationType = Global::FromExpression;
-        WASM_PARSER_FAIL_IF(typeForInitOpcode != global.type, "Global init_expr opcode of type ", typeForInitOpcode, " doesn't match global's type ", global.type);
-
-        m_info->globals.uncheckedAppend(WTFMove(global));
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseExport() -> PartialResult
-{
-    uint32_t exportCount;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(exportCount), "can't get Export section's count");
-    WASM_PARSER_FAIL_IF(exportCount > maxExports, "Export section's count is too big ", exportCount, " maximum ", maxExports);
-    WASM_PARSER_FAIL_IF(!m_info->exports.tryReserveCapacity(exportCount), "can't allocate enough memory for ", exportCount, " exports");
-
-    HashSet<String> exportNames;
-    for (uint32_t exportNumber = 0; exportNumber < exportCount; ++exportNumber) {
-        uint32_t fieldLen;
-        Name fieldString;
-        ExternalKind kind;
-        unsigned kindIndex;
-
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", exportNumber, "th Export's field name length");
-        WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", exportNumber, "th Export's field name of length ", fieldLen);
-        String fieldName = String::fromUTF8(fieldString);
-        WASM_PARSER_FAIL_IF(exportNames.contains(fieldName), "duplicate export: '", fieldString, "'");
-        exportNames.add(fieldName);
-
-        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", exportNumber, "th Export's kind, named '", fieldString, "'");
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(kindIndex), "can't get ", exportNumber, "th Export's kind index, named '", fieldString, "'");
-        switch (kind) {
-        case ExternalKind::Function: {
-            WASM_PARSER_FAIL_IF(kindIndex >= m_info->functionIndexSpaceSize(), exportNumber, "th Export has invalid function number ", kindIndex, " it exceeds the function index space ", m_info->functionIndexSpaceSize(), ", named '", fieldString, "'");
-            break;
-        }
-        case ExternalKind::Table: {
-            WASM_PARSER_FAIL_IF(kindIndex >= m_tableCount, "can't export Table ", kindIndex, " there are ", m_tableCount, " Tables");
-            break;
-        }
-        case ExternalKind::Memory: {
-            WASM_PARSER_FAIL_IF(!m_info->memory, "can't export a non-existent Memory");
-            WASM_PARSER_FAIL_IF(kindIndex, "can't export Memory ", kindIndex, " only one Table is currently supported");
-            break;
-        }
-        case ExternalKind::Global: {
-            WASM_PARSER_FAIL_IF(kindIndex >= m_info->globals.size(), exportNumber, "th Export has invalid global number ", kindIndex, " it exceeds the globals count ", m_info->globals.size(), ", named '", fieldString, "'");
-            WASM_PARSER_FAIL_IF(m_info->globals[kindIndex].mutability != Global::Immutable, exportNumber, "th Export isn't immutable, named '", fieldString, "'");
-            break;
-        }
-        }
-
-        m_info->exports.uncheckedAppend({ WTFMove(fieldString), kind, kindIndex });
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseStart() -> PartialResult
-{
-    uint32_t startFunctionIndex;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), "can't get Start index");
-    WASM_PARSER_FAIL_IF(startFunctionIndex >= m_info->functionIndexSpaceSize(), "Start index ", startFunctionIndex, " exceeds function index space ", m_info->functionIndexSpaceSize());
-    SignatureIndex signatureIndex = m_info->signatureIndexFromFunctionIndexSpace(startFunctionIndex);
-    const Signature& signature = SignatureInformation::get(signatureIndex);
-    WASM_PARSER_FAIL_IF(signature.argumentCount(), "Start function can't have arguments");
-    WASM_PARSER_FAIL_IF(signature.returnType() != Void, "Start function can't return a value");
-    m_info->startFunctionIndexSpace = startFunctionIndex;
-    return { };
-}
-
-auto ModuleParser::parseElement() -> PartialResult
-{
-    uint32_t elementCount;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(elementCount), "can't get Element section's count");
-    WASM_PARSER_FAIL_IF(elementCount > maxTableEntries, "Element section's count is too big ", elementCount, " maximum ", maxTableEntries);
-    WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements");
-    for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) {
-        uint32_t tableIndex;
-        uint64_t initExprBits;
-        uint8_t initOpcode;
-        uint32_t indexCount;
-
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(tableIndex), "can't get ", elementNum, "th Element table index");
-        WASM_PARSER_FAIL_IF(tableIndex >= m_tableCount, "Element section for Table ", tableIndex, " exceeds available Table ", m_tableCount);
-        Type initExprType;
-        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType));
-        WASM_PARSER_FAIL_IF(initExprType != I32, "Element init_expr must produce an i32");
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(indexCount), "can't get ", elementNum, "th index count for Element section");
-        WASM_PARSER_FAIL_IF(indexCount == std::numeric_limits<uint32_t>::max(), "Element section's ", elementNum, "th index count is too big ", indexCount);
-
-        ASSERT(!!m_info->tableInformation);
-
-        Element element(makeI32InitExpr(initOpcode, initExprBits));
-        WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices");
-
-        for (unsigned index = 0; index < indexCount; ++index) {
-            uint32_t functionIndex;
-            WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index");
-            WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize());
-
-            element.functionIndices.uncheckedAppend(functionIndex);
-        }
-
-        m_info->elements.uncheckedAppend(WTFMove(element));
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseCode() -> PartialResult
-{
-    uint32_t count;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Code section's count");
-    WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", count);
-    WASM_PARSER_FAIL_IF(count != m_info->functionLocationInBinary.size(), "Code section count ", count, " exceeds the declared number of functions ", m_info->functionLocationInBinary.size());
-
-    for (uint32_t i = 0; i < count; ++i) {
-        uint32_t functionSize;
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSize), "can't get ", i, "th Code function's size");
-        WASM_PARSER_FAIL_IF(functionSize > length(), "Code function's size ", functionSize, " exceeds the module's size ", length());
-        WASM_PARSER_FAIL_IF(functionSize > length() - m_offset, "Code function's size ", functionSize, " exceeds the module's remaining size", length() - m_offset);
-        WASM_PARSER_FAIL_IF(functionSize > maxFunctionSize, "Code function's size ", functionSize, " is too big");
-
-        m_info->functionLocationInBinary[i].start = m_offset;
-        m_info->functionLocationInBinary[i].end = m_offset + functionSize;
-        m_offset = m_info->functionLocationInBinary[i].end;
-    }
-
-    return { };
-}
-
-auto ModuleParser::parseInitExpr(uint8_t& opcode, uint64_t& bitsOrImportNumber, Type& resultType) -> PartialResult
-{
-    WASM_PARSER_FAIL_IF(!parseUInt8(opcode), "can't get init_expr's opcode");
-
-    switch (opcode) {
-    case I32Const: {
-        int32_t constant;
-        WASM_PARSER_FAIL_IF(!parseVarInt32(constant), "can't get constant value for init_expr's i32.const");
-        bitsOrImportNumber = static_cast<uint64_t>(constant);
-        resultType = I32;
-        break;
-    }
-
-    case I64Const: {
-        int64_t constant;
-        WASM_PARSER_FAIL_IF(!parseVarInt64(constant), "can't get constant value for init_expr's i64.const");
-        bitsOrImportNumber = constant;
-        resultType = I64;
-        break;
-    }
-
-    case F32Const: {
-        uint32_t constant;
-        WASM_PARSER_FAIL_IF(!parseUInt32(constant), "can't get constant value for init_expr's f32.const");
-        bitsOrImportNumber = constant;
-        resultType = F32;
-        break;
-    }
-
-    case F64Const: {
-        uint64_t constant;
-        WASM_PARSER_FAIL_IF(!parseUInt64(constant), "can't get constant value for init_expr's f64.const");
-        bitsOrImportNumber = constant;
-        resultType = F64;
-        break;
-    }
-
-    case GetGlobal: {
-        uint32_t index;
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get get_global's index");
-
-        WASM_PARSER_FAIL_IF(index >= m_info->globals.size(), "get_global's index ", index, " exceeds the number of globals ", m_info->globals.size());
-        WASM_PARSER_FAIL_IF(index >= m_info->firstInternalGlobal, "get_global import kind index ", index, " exceeds the first internal global ", m_info->firstInternalGlobal);
-
-        ASSERT(m_info->globals[index].mutability == Global::Immutable);
-        resultType = m_info->globals[index].type;
-        bitsOrImportNumber = index;
-        break;
-    }
-
-    default:
-        WASM_PARSER_FAIL_IF(true, "unknown init_expr opcode ", opcode);
-    }
-
-    uint8_t endOpcode;
-    WASM_PARSER_FAIL_IF(!parseUInt8(endOpcode), "can't get init_expr's end opcode");
-    WASM_PARSER_FAIL_IF(endOpcode != OpType::End, "init_expr should end with end, ended with ", endOpcode);
-
-    return { };
-}
-
-auto ModuleParser::parseGlobalType(Global& global) -> PartialResult
-{
-    uint8_t mutability;
-    WASM_PARSER_FAIL_IF(!parseValueType(global.type), "can't get Global's value type");
-    WASM_PARSER_FAIL_IF(!parseVarUInt1(mutability), "can't get Global type's mutability");
-    global.mutability = static_cast<Global::Mutability>(mutability);
-    return { };
-}
-
-auto ModuleParser::parseData() -> PartialResult
-{
-    uint32_t segmentCount;
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(segmentCount), "can't get Data section's count");
-    WASM_PARSER_FAIL_IF(segmentCount > maxDataSegments, "Data section's count is too big ", segmentCount, " maximum ", maxDataSegments);
-    WASM_PARSER_FAIL_IF(!m_info->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");
-
-    for (uint32_t segmentNumber = 0; segmentNumber < segmentCount; ++segmentNumber) {
-        uint32_t memoryIndex;
-        uint64_t initExprBits;
-        uint8_t initOpcode;
-        uint32_t dataByteLength;
-
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(memoryIndex), "can't get ", segmentNumber, "th Data segment's index");
-        WASM_PARSER_FAIL_IF(memoryIndex >= m_memoryCount, segmentNumber, "th Data segment has index ", memoryIndex, " which exceeds the number of Memories ", m_memoryCount);
-        Type initExprType;
-        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType));
-        WASM_PARSER_FAIL_IF(initExprType != I32, segmentNumber, "th Data segment's init_expr must produce an i32");
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(dataByteLength), "can't get ", segmentNumber, "th Data segment's data byte length");
-        WASM_PARSER_FAIL_IF(dataByteLength > maxModuleSize, segmentNumber, "th Data segment's data byte length is too big ", dataByteLength, " maximum ", maxModuleSize);
-
-        Segment* segment = Segment::create(makeI32InitExpr(initOpcode, initExprBits), dataByteLength);
-        WASM_PARSER_FAIL_IF(!segment, "can't allocate enough memory for ", segmentNumber, "th Data segment of size ", dataByteLength);
-        m_info->data.uncheckedAppend(Segment::adoptPtr(segment));
-        for (uint32_t dataByte = 0; dataByte < dataByteLength; ++dataByte) {
-            uint8_t byte;
-            WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", dataByte, "th data byte from ", segmentNumber, "th Data segment");
-            segment->byte(dataByte) = byte;
-        }
-    }
-    return { };
-}
-    
-auto ModuleParser::parseCustom(uint32_t sectionLength) -> PartialResult
-{
-    const uint32_t customSectionStartOffset = m_offset;
-
-    CustomSection section;
-    uint32_t customSectionNumber = m_info->customSections.size() + 1;
-    uint32_t nameLen;
-    WASM_PARSER_FAIL_IF(!m_info->customSections.tryReserveCapacity(customSectionNumber), "can't allocate enough memory for ", customSectionNumber, "th custom section");
-    WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get ", customSectionNumber, "th custom section's name length");
-    WASM_PARSER_FAIL_IF(!consumeUTF8String(section.name, nameLen), "nameLen get ", customSectionNumber, "th custom section's name of length ", nameLen);
-
-    uint32_t payloadBytes = sectionLength - (m_offset - customSectionStartOffset);
-    WASM_PARSER_FAIL_IF(!section.payload.tryReserveCapacity(payloadBytes), "can't allocate enough memory for ", customSectionNumber, "th custom section's ", payloadBytes, " bytes");
-    for (uint32_t byteNumber = 0; byteNumber < payloadBytes; ++byteNumber) {
-        uint8_t byte;
-        WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", byteNumber, "th data byte from ", customSectionNumber, "th custom section");
-        section.payload.uncheckedAppend(byte);
-    }
-
-    Name nameName = { 'n', 'a', 'm', 'e' };
-    if (section.name == nameName) {
-        NameSectionParser nameSectionParser(section.payload.begin(), section.payload.size(), m_info);
-        if (auto nameSection = nameSectionParser.parse())
-            m_info->nameSection = WTFMove(*nameSection);
-    }
-
-    m_info->customSections.uncheckedAppend(WTFMove(section));
-
-    return { };
-}
-
</del><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h      2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h 2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -46,21 +46,7 @@
</span><span class="cx">     Result WARN_UNUSED_RETURN parse();
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-
-#define WASM_SECTION_DECLARE_PARSER(NAME, ID, DESCRIPTION) PartialResult WARN_UNUSED_RETURN parse ## NAME();
-    FOR_EACH_KNOWN_WASM_SECTION(WASM_SECTION_DECLARE_PARSER)
-#undef WASM_SECTION_DECLARE_PARSER
-
-    PartialResult WARN_UNUSED_RETURN parseCustom(uint32_t);
-    PartialResult WARN_UNUSED_RETURN parseGlobalType(Global&);
-    PartialResult WARN_UNUSED_RETURN parseMemoryHelper(bool isImport);
-    PartialResult WARN_UNUSED_RETURN parseTableHelper(bool isImport);
-    PartialResult WARN_UNUSED_RETURN parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum);
-    PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&, Type& initExprType);
-
</del><span class="cx">     Ref<ModuleInformation> m_info;
</span><del>-    uint32_t m_memoryCount { 0 };
-    uint32_t m_tableCount { 0 };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmNameSectionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmNameSection.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmNameSection.h       2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmNameSection.h  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -36,11 +36,20 @@
</span><span class="cx"> 
</span><span class="cx"> struct NameSection : public ThreadSafeRefCounted<NameSection> {
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(NameSection);
</span><del>-
</del><span class="cx"> public:
</span><del>-    NameSection(const std::optional<CString> &hash)
-        : moduleHash(hash ? hash->length() : 3)
</del><ins>+    NameSection()
</ins><span class="cx">     {
</span><ins>+        setHash(std::nullopt);
+    }
+
+    static Ref<NameSection> create()
+    {
+        return adoptRef(*new NameSection);
+    }
+
+    void setHash(const std::optional<CString> &hash)
+    {
+        moduleHash = Name(hash ? hash->length() : 3);
</ins><span class="cx">         if (hash) {
</span><span class="cx">             for (size_t i = 0; i < hash->length(); ++i)
</span><span class="cx">                 moduleHash[i] = static_cast<uint8_t>(*(hash->data() + i));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmNameSectionParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp       2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.cpp  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> 
</span><span class="cx"> auto NameSectionParser::parse() -> Result
</span><span class="cx"> {
</span><del>-    RefPtr<NameSection> nameSection(adoptRef(*new NameSection(m_info.hash)));
</del><ins>+    Ref<NameSection> nameSection = NameSection::create();
</ins><span class="cx">     WASM_PARSER_FAIL_IF(!nameSection->functionNames.tryReserveCapacity(m_info.functionIndexSpaceSize()), "can't allocate enough memory for function names");
</span><span class="cx">     nameSection->functionNames.resize(m_info.functionIndexSpaceSize());
</span><span class="cx"> 
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx">         }
</span><span class="cx">         WASM_PARSER_FAIL_IF(payloadStart + payloadLength != m_offset);
</span><span class="cx">     }
</span><del>-    return nameSection;
</del><ins>+    return WTFMove(nameSection);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmNameSectionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.h 2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmNameSectionParser.h    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -33,7 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><del>-class NameSectionParser : public Parser<RefPtr<NameSection>> {
</del><ins>+class NameSectionParser : public Parser<Ref<NameSection>> {
</ins><span class="cx"> public:
</span><span class="cx">     NameSectionParser(const uint8_t* sourceBuffer, size_t sourceLength, const ModuleInformation& info)
</span><span class="cx">         : Parser(sourceBuffer, sourceLength)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmOMGPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp 2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -69,10 +69,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_codeBlock->runnable());
</span><span class="cx">     ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode()));
</span><del>-    const FunctionLocationInBinary& location = m_moduleInformation->functionLocationInBinary[m_functionIndex];
-    const uint8_t* functionStart = m_moduleInformation->source.data() + location.start;
-    const size_t functionLength = location.end - location.start;
-    ASSERT(functionStart + functionLength <= m_moduleInformation->source.end());
</del><ins>+    const FunctionData& function = m_moduleInformation->functions[m_functionIndex];
</ins><span class="cx"> 
</span><span class="cx">     const uint32_t functionIndexSpace = m_functionIndex + m_module->moduleInformation().importFunctionCount();
</span><span class="cx">     ASSERT(functionIndexSpace < m_module->moduleInformation().functionIndexSpaceSize());
</span><span class="lines">@@ -79,11 +76,11 @@
</span><span class="cx"> 
</span><span class="cx">     SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[m_functionIndex];
</span><span class="cx">     const Signature& signature = SignatureInformation::get(signatureIndex);
</span><del>-    ASSERT(validateFunction(functionStart, functionLength, signature, m_moduleInformation.get()));
</del><ins>+    ASSERT(validateFunction(function.data.data(), function.data.size(), signature, m_moduleInformation.get()));
</ins><span class="cx"> 
</span><span class="cx">     Vector<UnlinkedWasmToWasmCall> unlinkedCalls;
</span><span class="cx">     CompilationContext context;
</span><del>-    auto parseAndCompileResult = parseAndCompile(context, functionStart, functionLength, signature, unlinkedCalls, m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex);
</del><ins>+    auto parseAndCompileResult = parseAndCompile(context, function.data.data(), function.data.size(), signature, unlinkedCalls, m_moduleInformation.get(), m_mode, CompilationMode::OMGMode, m_functionIndex);
</ins><span class="cx"> 
</span><span class="cx">     if (UNLIKELY(!parseAndCompileResult)) {
</span><span class="cx">         fail(holdLock(m_lock), makeString(parseAndCompileResult.error(), "when trying to tier up ", String::number(m_functionIndex)));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmParser.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmParser.h    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmParser.h       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -58,6 +58,10 @@
</span><span class="cx">     typedef Expected<void, ErrorType> PartialResult;
</span><span class="cx">     typedef Expected<SuccessType, ErrorType> Result;
</span><span class="cx"> 
</span><ins>+    const uint8_t* source() const { return m_source; }
+    size_t length() const { return m_sourceLength; }
+    size_t offset() const { return m_offset; }
+
</ins><span class="cx"> protected:
</span><span class="cx">     Parser(const uint8_t*, size_t);
</span><span class="cx"> 
</span><span class="lines">@@ -81,9 +85,6 @@
</span><span class="cx">     bool WARN_UNUSED_RETURN parseValueType(Type&);
</span><span class="cx">     bool WARN_UNUSED_RETURN parseExternalKind(ExternalKind&);
</span><span class="cx"> 
</span><del>-    const uint8_t* source() const { return m_source; }
-    size_t length() const { return m_sourceLength; }
-
</del><span class="cx">     size_t m_offset = 0;
</span><span class="cx"> 
</span><span class="cx">     template <typename ...Args>
</span><span class="lines">@@ -90,7 +91,7 @@
</span><span class="cx">     NEVER_INLINE UnexpectedResult WARN_UNUSED_RETURN fail(Args... args) const
</span><span class="cx">     {
</span><span class="cx">         using namespace FailureHelper; // See ADL comment in namespace above.
</span><del>-        return UnexpectedResult(makeString("WebAssembly.Module doesn't parse at byte "_s, String::number(m_offset), " / "_s, String::number(m_sourceLength), ": "_s, makeString(args)...));
</del><ins>+        return UnexpectedResult(makeString("WebAssembly.Module doesn't parse at byte "_s, String::number(m_offset), ": "_s, makeString(args)...));
</ins><span class="cx">     }
</span><span class="cx"> #define WASM_PARSER_FAIL_IF(condition, ...) do { \
</span><span class="cx">     if (UNLIKELY(condition))                     \
</span><span class="lines">@@ -285,6 +286,14 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+ALWAYS_INLINE I32InitExpr makeI32InitExpr(uint8_t opcode, uint32_t bits)
+{
+    RELEASE_ASSERT(opcode == I32Const || opcode == GetGlobal);
+    if (opcode == I32Const)
+        return I32InitExpr::constValue(bits);
+    return I32InitExpr::globalImport(bits);
+}
+
</ins><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp    2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp       2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -53,8 +53,6 @@
</span><span class="cx">     : m_moduleInformation(WTFMove(info))
</span><span class="cx">     , m_createEmbedderWrapper(WTFMove(createEmbedderWrapper))
</span><span class="cx">     , m_throwWasmException(throwWasmException)
</span><del>-    , m_source(m_moduleInformation->source.data())
-    , m_sourceLength(m_moduleInformation->source.size())
</del><span class="cx"> {
</span><span class="cx">     m_completionTasks.append(std::make_pair(context, WTFMove(task)));
</span><span class="cx"> }
</span><span class="lines">@@ -64,10 +62,8 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Plan::Plan(Context* context, const uint8_t* source, size_t sourceLength, CompletionTask&& task)
-    : m_moduleInformation(adoptRef(*new ModuleInformation(Vector<uint8_t>())))
-    , m_source(source)
-    , m_sourceLength(sourceLength)
</del><ins>+Plan::Plan(Context* context, CompletionTask&& task)
+    : m_moduleInformation(ModuleInformation::create())
</ins><span class="cx"> {
</span><span class="cx">     m_completionTasks.append(std::make_pair(context, WTFMove(task)));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmPlan.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmPlan.h      2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/WasmPlan.h 2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -54,7 +54,7 @@
</span><span class="cx">     Plan(Context*, Ref<ModuleInformation>, CompletionTask&&);
</span><span class="cx"> 
</span><span class="cx">     // Note: This constructor should only be used if you are not actually building a module e.g. validation/function tests
</span><del>-    JS_EXPORT_PRIVATE Plan(Context*, const uint8_t*, size_t, CompletionTask&&);
</del><ins>+    JS_EXPORT_PRIVATE Plan(Context*, CompletionTask&&);
</ins><span class="cx">     virtual JS_EXPORT_PRIVATE ~Plan();
</span><span class="cx"> 
</span><span class="cx">     // If you guarantee the ordering here, you can rely on FIFO of the
</span><span class="lines">@@ -90,8 +90,6 @@
</span><span class="cx">     CreateEmbedderWrapper m_createEmbedderWrapper;
</span><span class="cx">     ThrowWasmException m_throwWasmException { nullptr };
</span><span class="cx"> 
</span><del>-    const uint8_t* m_source;
-    const size_t m_sourceLength;
</del><span class="cx">     String m_errorMessage;
</span><span class="cx">     MemoryMode m_mode { MemoryMode::BoundsChecking };
</span><span class="cx">     Lock m_lock;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmSectionParsercppfromrev235419trunkSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp (from rev 235419, trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp) (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp                           (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp      2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,562 @@
</span><ins>+/*
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>.
+ *
+ * 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 "WasmSectionParser.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "IdentifierInlines.h"
+#include "WasmMemoryInformation.h"
+#include "WasmNameSectionParser.h"
+#include "WasmOps.h"
+#include "WasmSections.h"
+
+namespace JSC { namespace Wasm {
+
+auto SectionParser::parseType() -> PartialResult
+{
+    uint32_t count;
+
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count");
+    WASM_PARSER_FAIL_IF(count > maxTypes, "Type section's count is too big ", count, " maximum ", maxTypes);
+    WASM_PARSER_FAIL_IF(!m_info->usedSignatures.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");
+
+    for (uint32_t i = 0; i < count; ++i) {
+        int8_t type;
+        uint32_t argumentCount;
+        Vector<Type> argumentTypes;
+
+        WASM_PARSER_FAIL_IF(!parseInt7(type), "can't get ", i, "th Type's type");
+        WASM_PARSER_FAIL_IF(type != Func, i, "th Type is non-Func ", type);
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get ", i, "th Type's argument count");
+        WASM_PARSER_FAIL_IF(argumentCount > maxFunctionParams, i, "th argument count is too big ", argumentCount, " maximum ", maxFunctionParams);
+        RefPtr<Signature> maybeSignature = Signature::tryCreate(argumentCount);
+        WASM_PARSER_FAIL_IF(!maybeSignature, "can't allocate enough memory for Type section's ", i, "th signature");
+        Ref<Signature> signature = maybeSignature.releaseNonNull();
+
+        for (unsigned i = 0; i < argumentCount; ++i) {
+            Type argumentType;
+            WASM_PARSER_FAIL_IF(!parseValueType(argumentType), "can't get ", i, "th argument Type");
+            signature->argument(i) = argumentType;
+        }
+
+        uint8_t returnCount;
+        WASM_PARSER_FAIL_IF(!parseVarUInt1(returnCount), "can't get ", i, "th Type's return count");
+        Type returnType;
+        if (returnCount) {
+            Type value;
+            WASM_PARSER_FAIL_IF(!parseValueType(value), "can't get ", i, "th Type's return value");
+            returnType = static_cast<Type>(value);
+        } else
+            returnType = Type::Void;
+        signature->returnType() = returnType;
+
+        std::pair<SignatureIndex, Ref<Signature>> result = SignatureInformation::adopt(WTFMove(signature));
+        m_info->usedSignatures.uncheckedAppend(WTFMove(result.second));
+    }
+    return { };
+}
+
+auto SectionParser::parseImport() -> PartialResult
+{
+    uint32_t importCount;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(importCount), "can't get Import section's count");
+    WASM_PARSER_FAIL_IF(importCount > maxImports, "Import section's count is too big ", importCount, " maximum ", maxImports);
+    WASM_PARSER_FAIL_IF(!m_info->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below.
+    WASM_PARSER_FAIL_IF(!m_info->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below.
+    WASM_PARSER_FAIL_IF(!m_info->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below.
+
+    for (uint32_t importNumber = 0; importNumber < importCount; ++importNumber) {
+        uint32_t moduleLen;
+        uint32_t fieldLen;
+        Name moduleString;
+        Name fieldString;
+        ExternalKind kind;
+        unsigned kindIndex { 0 };
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(moduleLen), "can't get ", importNumber, "th Import's module name length");
+        WASM_PARSER_FAIL_IF(!consumeUTF8String(moduleString, moduleLen), "can't get ", importNumber, "th Import's module name of length ", moduleLen);
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", importNumber, "th Import's field name length in module '", moduleString, "'");
+        WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", importNumber, "th Import's field name of length ", moduleLen, " in module '", moduleString, "'");
+
+        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", importNumber, "th Import's kind in module '", moduleString, "' field '", fieldString, "'");
+        switch (kind) {
+        case ExternalKind::Function: {
+            uint32_t functionSignatureIndex;
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSignatureIndex), "can't get ", importNumber, "th Import's function signature in module '", moduleString, "' field '", fieldString, "'");
+            WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_info->usedSignatures.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_info->usedSignatures.size(), " in module '", moduleString, "' field '", fieldString, "'");
+            kindIndex = m_info->importFunctionSignatureIndices.size();
+            SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[functionSignatureIndex]);
+            m_info->importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
+            break;
+        }
+        case ExternalKind::Table: {
+            bool isImport = true;
+            PartialResult result = parseTableHelper(isImport);
+            if (UNLIKELY(!result))
+                return makeUnexpected(WTFMove(result.error()));
+            break;
+        }
+        case ExternalKind::Memory: {
+            bool isImport = true;
+            PartialResult result = parseMemoryHelper(isImport);
+            if (UNLIKELY(!result))
+                return makeUnexpected(WTFMove(result.error()));
+            break;
+        }
+        case ExternalKind::Global: {
+            Global global;
+            WASM_FAIL_IF_HELPER_FAILS(parseGlobalType(global));
+            WASM_PARSER_FAIL_IF(global.mutability == Global::Mutable, "Mutable Globals aren't supported");
+
+            kindIndex = m_info->globals.size();
+            m_info->globals.uncheckedAppend(WTFMove(global));
+            break;
+        }
+        }
+
+        m_info->imports.uncheckedAppend({ WTFMove(moduleString), WTFMove(fieldString), kind, kindIndex });
+    }
+
+    m_info->firstInternalGlobal = m_info->globals.size();
+    return { };
+}
+
+auto SectionParser::parseFunction() -> PartialResult
+{
+    uint32_t count;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count");
+    WASM_PARSER_FAIL_IF(count > maxFunctions, "Function section's count is too big ", count, " maximum ", maxFunctions);
+    WASM_PARSER_FAIL_IF(!m_info->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");
+    WASM_PARSER_FAIL_IF(!m_info->functions.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
+
+    for (uint32_t i = 0; i < count; ++i) {
+        uint32_t typeNumber;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", i, "th Function's type number");
+        WASM_PARSER_FAIL_IF(typeNumber >= m_info->usedSignatures.size(), i, "th Function type number is invalid ", typeNumber);
+
+        SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[typeNumber]);
+        // The Code section fixes up start and end.
+        size_t start = 0;
+        size_t end = 0;
+        m_info->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
+        m_info->functions.uncheckedAppend({ start, end, Vector<uint8_t>() });
+    }
+
+    return { };
+}
+
+auto SectionParser::parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum) -> PartialResult
+{
+    ASSERT(!maximum);
+
+    uint8_t flags;
+    WASM_PARSER_FAIL_IF(!parseVarUInt1(flags), "can't parse resizable limits flags");
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(initial), "can't parse resizable limits initial page count");
+
+    if (flags) {
+        uint32_t maximumInt;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(maximumInt), "can't parse resizable limits maximum page count");
+        WASM_PARSER_FAIL_IF(initial > maximumInt, "resizable limits has a initial page count of ", initial, " which is greater than its maximum ", maximumInt);
+        maximum = maximumInt;
+    }
+
+    return { };
+}
+
+auto SectionParser::parseTableHelper(bool isImport) -> PartialResult
+{
+    WASM_PARSER_FAIL_IF(m_info->tableCount() > 0, "Cannot have more than one Table for now");
+
+    int8_t type;
+    WASM_PARSER_FAIL_IF(!parseInt7(type), "can't parse Table type");
+    WASM_PARSER_FAIL_IF(type != Wasm::Anyfunc, "Table type should be anyfunc, got ", type);
+
+    uint32_t initial;
+    std::optional<uint32_t> maximum;
+    PartialResult limits = parseResizableLimits(initial, maximum);
+    if (UNLIKELY(!limits))
+        return makeUnexpected(WTFMove(limits.error()));
+    WASM_PARSER_FAIL_IF(initial > maxTableEntries, "Table's initial page count of ", initial, " is too big, maximum ", maxTableEntries);
+
+    ASSERT(!maximum || *maximum >= initial);
+
+    m_info->tableInformation = TableInformation(initial, maximum, isImport);
+
+    return { };
+}
+
+auto SectionParser::parseTable() -> PartialResult
+{
+    uint32_t count;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Table's count");
+    WASM_PARSER_FAIL_IF(count > 1, "Table count of ", count, " is invalid, at most 1 is allowed for now");
+
+    if (!count)
+        return { };
+
+    bool isImport = false;
+    PartialResult result = parseTableHelper(isImport);
+    if (UNLIKELY(!result))
+        return makeUnexpected(WTFMove(result.error()));
+
+    return { };
+}
+
+auto SectionParser::parseMemoryHelper(bool isImport) -> PartialResult
+{
+    WASM_PARSER_FAIL_IF(m_info->memoryCount(), "there can at most be one Memory section for now");
+
+    PageCount initialPageCount;
+    PageCount maximumPageCount;
+    {
+        uint32_t initial;
+        std::optional<uint32_t> maximum;
+        PartialResult limits = parseResizableLimits(initial, maximum);
+        if (UNLIKELY(!limits))
+            return makeUnexpected(WTFMove(limits.error()));
+        ASSERT(!maximum || *maximum >= initial);
+        WASM_PARSER_FAIL_IF(!PageCount::isValid(initial), "Memory's initial page count of ", initial, " is invalid");
+
+        initialPageCount = PageCount(initial);
+
+        if (maximum) {
+            WASM_PARSER_FAIL_IF(!PageCount::isValid(*maximum), "Memory's maximum page count of ", *maximum, " is invalid");
+            maximumPageCount = PageCount(*maximum);
+        }
+    }
+    ASSERT(initialPageCount);
+    ASSERT(!maximumPageCount || maximumPageCount >= initialPageCount);
+
+    m_info->memory = MemoryInformation(initialPageCount, maximumPageCount, isImport);
+    return { };
+}
+
+auto SectionParser::parseMemory() -> PartialResult
+{
+    uint8_t count;
+    WASM_PARSER_FAIL_IF(!parseVarUInt1(count), "can't parse Memory section's count");
+
+    if (!count)
+        return { };
+
+    WASM_PARSER_FAIL_IF(count != 1, "Memory section has more than one memory, WebAssembly currently only allows zero or one");
+
+    bool isImport = false;
+    return parseMemoryHelper(isImport);
+}
+
+auto SectionParser::parseGlobal() -> PartialResult
+{
+    uint32_t globalCount;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(globalCount), "can't get Global section's count");
+    WASM_PARSER_FAIL_IF(globalCount > maxGlobals, "Global section's count is too big ", globalCount, " maximum ", maxGlobals);
+    size_t totalBytes = globalCount + m_info->firstInternalGlobal;
+    WASM_PARSER_FAIL_IF((static_cast<uint32_t>(totalBytes) < globalCount) || !m_info->globals.tryReserveCapacity(totalBytes), "can't allocate memory for ", totalBytes, " globals");
+
+    for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) {
+        Global global;
+        uint8_t initOpcode;
+
+        WASM_FAIL_IF_HELPER_FAILS(parseGlobalType(global));
+        Type typeForInitOpcode;
+        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, global.initialBitsOrImportNumber, typeForInitOpcode));
+        if (initOpcode == GetGlobal)
+            global.initializationType = Global::FromGlobalImport;
+        else
+            global.initializationType = Global::FromExpression;
+        WASM_PARSER_FAIL_IF(typeForInitOpcode != global.type, "Global init_expr opcode of type ", typeForInitOpcode, " doesn't match global's type ", global.type);
+
+        m_info->globals.uncheckedAppend(WTFMove(global));
+    }
+
+    return { };
+}
+
+auto SectionParser::parseExport() -> PartialResult
+{
+    uint32_t exportCount;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(exportCount), "can't get Export section's count");
+    WASM_PARSER_FAIL_IF(exportCount > maxExports, "Export section's count is too big ", exportCount, " maximum ", maxExports);
+    WASM_PARSER_FAIL_IF(!m_info->exports.tryReserveCapacity(exportCount), "can't allocate enough memory for ", exportCount, " exports");
+
+    HashSet<String> exportNames;
+    for (uint32_t exportNumber = 0; exportNumber < exportCount; ++exportNumber) {
+        uint32_t fieldLen;
+        Name fieldString;
+        ExternalKind kind;
+        unsigned kindIndex;
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(fieldLen), "can't get ", exportNumber, "th Export's field name length");
+        WASM_PARSER_FAIL_IF(!consumeUTF8String(fieldString, fieldLen), "can't get ", exportNumber, "th Export's field name of length ", fieldLen);
+        String fieldName = String::fromUTF8(fieldString);
+        WASM_PARSER_FAIL_IF(exportNames.contains(fieldName), "duplicate export: '", fieldString, "'");
+        exportNames.add(fieldName);
+
+        WASM_PARSER_FAIL_IF(!parseExternalKind(kind), "can't get ", exportNumber, "th Export's kind, named '", fieldString, "'");
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(kindIndex), "can't get ", exportNumber, "th Export's kind index, named '", fieldString, "'");
+        switch (kind) {
+        case ExternalKind::Function: {
+            WASM_PARSER_FAIL_IF(kindIndex >= m_info->functionIndexSpaceSize(), exportNumber, "th Export has invalid function number ", kindIndex, " it exceeds the function index space ", m_info->functionIndexSpaceSize(), ", named '", fieldString, "'");
+            break;
+        }
+        case ExternalKind::Table: {
+            WASM_PARSER_FAIL_IF(kindIndex >= m_info->tableCount(), "can't export Table ", kindIndex, " there are ", m_info->tableCount(), " Tables");
+            break;
+        }
+        case ExternalKind::Memory: {
+            WASM_PARSER_FAIL_IF(!m_info->memory, "can't export a non-existent Memory");
+            WASM_PARSER_FAIL_IF(kindIndex, "can't export Memory ", kindIndex, " only one Table is currently supported");
+            break;
+        }
+        case ExternalKind::Global: {
+            WASM_PARSER_FAIL_IF(kindIndex >= m_info->globals.size(), exportNumber, "th Export has invalid global number ", kindIndex, " it exceeds the globals count ", m_info->globals.size(), ", named '", fieldString, "'");
+            WASM_PARSER_FAIL_IF(m_info->globals[kindIndex].mutability != Global::Immutable, exportNumber, "th Export isn't immutable, named '", fieldString, "'");
+            break;
+        }
+        }
+
+        m_info->exports.uncheckedAppend({ WTFMove(fieldString), kind, kindIndex });
+    }
+
+    return { };
+}
+
+auto SectionParser::parseStart() -> PartialResult
+{
+    uint32_t startFunctionIndex;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), "can't get Start index");
+    WASM_PARSER_FAIL_IF(startFunctionIndex >= m_info->functionIndexSpaceSize(), "Start index ", startFunctionIndex, " exceeds function index space ", m_info->functionIndexSpaceSize());
+    SignatureIndex signatureIndex = m_info->signatureIndexFromFunctionIndexSpace(startFunctionIndex);
+    const Signature& signature = SignatureInformation::get(signatureIndex);
+    WASM_PARSER_FAIL_IF(signature.argumentCount(), "Start function can't have arguments");
+    WASM_PARSER_FAIL_IF(signature.returnType() != Void, "Start function can't return a value");
+    m_info->startFunctionIndexSpace = startFunctionIndex;
+    return { };
+}
+
+auto SectionParser::parseElement() -> PartialResult
+{
+    uint32_t elementCount;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(elementCount), "can't get Element section's count");
+    WASM_PARSER_FAIL_IF(elementCount > maxTableEntries, "Element section's count is too big ", elementCount, " maximum ", maxTableEntries);
+    WASM_PARSER_FAIL_IF(!m_info->elements.tryReserveCapacity(elementCount), "can't allocate memory for ", elementCount, " Elements");
+    for (unsigned elementNum = 0; elementNum < elementCount; ++elementNum) {
+        uint32_t tableIndex;
+        uint64_t initExprBits;
+        uint8_t initOpcode;
+        uint32_t indexCount;
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(tableIndex), "can't get ", elementNum, "th Element table index");
+        WASM_PARSER_FAIL_IF(tableIndex >= m_info->tableCount(), "Element section for Table ", tableIndex, " exceeds available Table ", m_info->tableCount());
+        Type initExprType;
+        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType));
+        WASM_PARSER_FAIL_IF(initExprType != I32, "Element init_expr must produce an i32");
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(indexCount), "can't get ", elementNum, "th index count for Element section");
+        WASM_PARSER_FAIL_IF(indexCount == std::numeric_limits<uint32_t>::max(), "Element section's ", elementNum, "th index count is too big ", indexCount);
+
+        ASSERT(!!m_info->tableInformation);
+
+        Element element(makeI32InitExpr(initOpcode, initExprBits));
+        WASM_PARSER_FAIL_IF(!element.functionIndices.tryReserveCapacity(indexCount), "can't allocate memory for ", indexCount, " Element indices");
+
+        for (unsigned index = 0; index < indexCount; ++index) {
+            uint32_t functionIndex;
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), "can't get Element section's ", elementNum, "th element's ", index, "th index");
+            WASM_PARSER_FAIL_IF(functionIndex >= m_info->functionIndexSpaceSize(), "Element section's ", elementNum, "th element's ", index, "th index is ", functionIndex, " which exceeds the function index space size of ", m_info->functionIndexSpaceSize());
+
+            element.functionIndices.uncheckedAppend(functionIndex);
+        }
+
+        m_info->elements.uncheckedAppend(WTFMove(element));
+    }
+
+    return { };
+}
+
+// This function will be changed to be RELEASE_ASSERT_NOT_REACHED once we switch our parsing infrastructure to the streaming parser.
+auto SectionParser::parseCode() -> PartialResult
+{
+    uint32_t count;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Code section's count");
+    WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", count);
+    WASM_PARSER_FAIL_IF(count != m_info->functions.size(), "Code section count ", count, " exceeds the declared number of functions ", m_info->functions.size());
+
+    for (uint32_t i = 0; i < count; ++i) {
+        uint32_t functionSize;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSize), "can't get ", i, "th Code function's size");
+        WASM_PARSER_FAIL_IF(functionSize > length(), "Code function's size ", functionSize, " exceeds the module's size ", length());
+        WASM_PARSER_FAIL_IF(functionSize > length() - m_offset, "Code function's size ", functionSize, " exceeds the module's remaining size", length() - m_offset);
+        WASM_PARSER_FAIL_IF(functionSize > maxFunctionSize, "Code function's size ", functionSize, " is too big");
+
+        Vector<uint8_t> data(functionSize);
+        std::memcpy(data.data(), source() + m_offset, functionSize);
+        m_info->functions[i].start = m_offsetInSource + m_offset;
+        m_info->functions[i].end = m_offsetInSource + m_offset + functionSize;
+        m_info->functions[i].data = WTFMove(data);
+        m_offset += functionSize;
+    }
+
+    return { };
+}
+
+auto SectionParser::parseInitExpr(uint8_t& opcode, uint64_t& bitsOrImportNumber, Type& resultType) -> PartialResult
+{
+    WASM_PARSER_FAIL_IF(!parseUInt8(opcode), "can't get init_expr's opcode");
+
+    switch (opcode) {
+    case I32Const: {
+        int32_t constant;
+        WASM_PARSER_FAIL_IF(!parseVarInt32(constant), "can't get constant value for init_expr's i32.const");
+        bitsOrImportNumber = static_cast<uint64_t>(constant);
+        resultType = I32;
+        break;
+    }
+
+    case I64Const: {
+        int64_t constant;
+        WASM_PARSER_FAIL_IF(!parseVarInt64(constant), "can't get constant value for init_expr's i64.const");
+        bitsOrImportNumber = constant;
+        resultType = I64;
+        break;
+    }
+
+    case F32Const: {
+        uint32_t constant;
+        WASM_PARSER_FAIL_IF(!parseUInt32(constant), "can't get constant value for init_expr's f32.const");
+        bitsOrImportNumber = constant;
+        resultType = F32;
+        break;
+    }
+
+    case F64Const: {
+        uint64_t constant;
+        WASM_PARSER_FAIL_IF(!parseUInt64(constant), "can't get constant value for init_expr's f64.const");
+        bitsOrImportNumber = constant;
+        resultType = F64;
+        break;
+    }
+
+    case GetGlobal: {
+        uint32_t index;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(index), "can't get get_global's index");
+
+        WASM_PARSER_FAIL_IF(index >= m_info->globals.size(), "get_global's index ", index, " exceeds the number of globals ", m_info->globals.size());
+        WASM_PARSER_FAIL_IF(index >= m_info->firstInternalGlobal, "get_global import kind index ", index, " exceeds the first internal global ", m_info->firstInternalGlobal);
+
+        ASSERT(m_info->globals[index].mutability == Global::Immutable);
+        resultType = m_info->globals[index].type;
+        bitsOrImportNumber = index;
+        break;
+    }
+
+    default:
+        WASM_PARSER_FAIL_IF(true, "unknown init_expr opcode ", opcode);
+    }
+
+    uint8_t endOpcode;
+    WASM_PARSER_FAIL_IF(!parseUInt8(endOpcode), "can't get init_expr's end opcode");
+    WASM_PARSER_FAIL_IF(endOpcode != OpType::End, "init_expr should end with end, ended with ", endOpcode);
+
+    return { };
+}
+
+auto SectionParser::parseGlobalType(Global& global) -> PartialResult
+{
+    uint8_t mutability;
+    WASM_PARSER_FAIL_IF(!parseValueType(global.type), "can't get Global's value type");
+    WASM_PARSER_FAIL_IF(!parseVarUInt1(mutability), "can't get Global type's mutability");
+    global.mutability = static_cast<Global::Mutability>(mutability);
+    return { };
+}
+
+auto SectionParser::parseData() -> PartialResult
+{
+    uint32_t segmentCount;
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(segmentCount), "can't get Data section's count");
+    WASM_PARSER_FAIL_IF(segmentCount > maxDataSegments, "Data section's count is too big ", segmentCount, " maximum ", maxDataSegments);
+    WASM_PARSER_FAIL_IF(!m_info->data.tryReserveCapacity(segmentCount), "can't allocate enough memory for Data section's ", segmentCount, " segments");
+
+    for (uint32_t segmentNumber = 0; segmentNumber < segmentCount; ++segmentNumber) {
+        uint32_t memoryIndex;
+        uint64_t initExprBits;
+        uint8_t initOpcode;
+        uint32_t dataByteLength;
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(memoryIndex), "can't get ", segmentNumber, "th Data segment's index");
+        WASM_PARSER_FAIL_IF(memoryIndex >= m_info->memoryCount(), segmentNumber, "th Data segment has index ", memoryIndex, " which exceeds the number of Memories ", m_info->memoryCount());
+        Type initExprType;
+        WASM_FAIL_IF_HELPER_FAILS(parseInitExpr(initOpcode, initExprBits, initExprType));
+        WASM_PARSER_FAIL_IF(initExprType != I32, segmentNumber, "th Data segment's init_expr must produce an i32");
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(dataByteLength), "can't get ", segmentNumber, "th Data segment's data byte length");
+        WASM_PARSER_FAIL_IF(dataByteLength > maxModuleSize, segmentNumber, "th Data segment's data byte length is too big ", dataByteLength, " maximum ", maxModuleSize);
+
+        Segment* segment = Segment::create(makeI32InitExpr(initOpcode, initExprBits), dataByteLength);
+        WASM_PARSER_FAIL_IF(!segment, "can't allocate enough memory for ", segmentNumber, "th Data segment of size ", dataByteLength);
+        m_info->data.uncheckedAppend(Segment::adoptPtr(segment));
+        for (uint32_t dataByte = 0; dataByte < dataByteLength; ++dataByte) {
+            uint8_t byte;
+            WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", dataByte, "th data byte from ", segmentNumber, "th Data segment");
+            segment->byte(dataByte) = byte;
+        }
+    }
+    return { };
+}
+
+auto SectionParser::parseCustom() -> PartialResult
+{
+    CustomSection section;
+    uint32_t customSectionNumber = m_info->customSections.size() + 1;
+    uint32_t nameLen;
+    WASM_PARSER_FAIL_IF(!m_info->customSections.tryReserveCapacity(customSectionNumber), "can't allocate enough memory for ", customSectionNumber, "th custom section");
+    WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get ", customSectionNumber, "th custom section's name length");
+    WASM_PARSER_FAIL_IF(!consumeUTF8String(section.name, nameLen), "nameLen get ", customSectionNumber, "th custom section's name of length ", nameLen);
+
+    uint32_t payloadBytes = length() - m_offset;
+    WASM_PARSER_FAIL_IF(!section.payload.tryReserveCapacity(payloadBytes), "can't allocate enough memory for ", customSectionNumber, "th custom section's ", payloadBytes, " bytes");
+    for (uint32_t byteNumber = 0; byteNumber < payloadBytes; ++byteNumber) {
+        uint8_t byte;
+        WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", byteNumber, "th data byte from ", customSectionNumber, "th custom section");
+        section.payload.uncheckedAppend(byte);
+    }
+
+    Name nameName = { 'n', 'a', 'm', 'e' };
+    if (section.name == nameName) {
+        NameSectionParser nameSectionParser(section.payload.begin(), section.payload.size(), m_info);
+        if (auto nameSection = nameSectionParser.parse())
+            m_info->nameSection = WTFMove(*nameSection);
+    }
+
+    m_info->customSections.uncheckedAppend(WTFMove(section));
+
+    return { };
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmSectionParserhfromrev235419trunkSourceJavaScriptCorewasmWasmModuleParserh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/wasm/WasmSectionParser.h (from rev 235419, trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h) (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmSectionParser.h                             (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WasmSectionParser.h        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmFormat.h"
+#include "WasmOps.h"
+#include "WasmParser.h"
+#include <wtf/Optional.h>
+#include <wtf/Vector.h>
+
+namespace JSC { namespace Wasm {
+
+class SectionParser final : public Parser<void> {
+public:
+    SectionParser(const uint8_t* data, size_t size, size_t offsetInSource, ModuleInformation& info)
+        : Parser(data, size)
+        , m_offsetInSource(offsetInSource)
+        , m_info(info)
+    {
+    }
+
+#define WASM_SECTION_DECLARE_PARSER(NAME, ID, DESCRIPTION) PartialResult WARN_UNUSED_RETURN parse ## NAME();
+    FOR_EACH_KNOWN_WASM_SECTION(WASM_SECTION_DECLARE_PARSER)
+#undef WASM_SECTION_DECLARE_PARSER
+
+    PartialResult WARN_UNUSED_RETURN parseCustom();
+
+private:
+    template <typename ...Args>
+    NEVER_INLINE UnexpectedResult WARN_UNUSED_RETURN fail(Args... args) const
+    {
+        using namespace FailureHelper; // See ADL comment in namespace above.
+        return UnexpectedResult(makeString("WebAssembly.Module doesn't parse at byte "_s, String::number(m_offset + m_offsetInSource), ": "_s, makeString(args)...));
+    }
+
+    PartialResult WARN_UNUSED_RETURN parseGlobalType(Global&);
+    PartialResult WARN_UNUSED_RETURN parseMemoryHelper(bool isImport);
+    PartialResult WARN_UNUSED_RETURN parseTableHelper(bool isImport);
+    PartialResult WARN_UNUSED_RETURN parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum);
+    PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&, Type& initExprType);
+
+    size_t m_offsetInSource;
+    Ref<ModuleInformation> m_info;
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmStreamingParsercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp                         (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp    2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,392 @@
</span><ins>+/*
+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>.
+ *
+ * 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 "WasmStreamingParser.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmModuleParser.h"
+#include "WasmSectionParser.h"
+#include <wtf/UnalignedAccess.h>
+
+namespace JSC { namespace Wasm {
+
+namespace WasmStreamingParserInternal {
+static constexpr bool verbose = false;
+}
+
+#define WASM_STREAMING_PARSER_FAIL_IF_HELPER_FAILS(helper) \
+    do { \
+        auto helperResult = helper; \
+        if (UNLIKELY(!helperResult)) { \
+            m_errorMessage = helperResult.error(); \
+            return State::FatalError; \
+        } \
+    } while (0)
+
+ALWAYS_INLINE std::optional<uint8_t> parseUInt7(const uint8_t* data, size_t& offset, size_t size)
+{
+    if (offset >= size)
+        return false;
+    uint8_t result = data[offset++];
+    if (result < 0x80)
+        return result;
+    return std::nullopt;
+}
+
+template <typename ...Args>
+NEVER_INLINE auto WARN_UNUSED_RETURN StreamingParser::fail(Args... args) -> State
+{
+    using namespace FailureHelper; // See ADL comment in namespace above.
+    m_errorMessage = makeString("WebAssembly.Module doesn't parse at byte "_s, String::number(m_offset), ": "_s, makeString(args)...);
+    dataLogLnIf(WasmStreamingParserInternal::verbose, m_errorMessage);
+    return State::FatalError;
+}
+
+StreamingParser::StreamingParser(ModuleInformation& info)
+    : m_info(info)
+{
+    dataLogLnIf(WasmStreamingParserInternal::verbose, "starting validation");
+}
+
+auto StreamingParser::parseModuleHeader(Vector<uint8_t>&& data) -> State
+{
+    ASSERT(data.size() == moduleHeaderSize);
+    dataLogLnIf(WasmStreamingParserInternal::verbose, "header validation");
+    WASM_PARSER_FAIL_IF(data[0] != '\0' || data[1] != 'a' || data[2] != 's' || data[3] != 'm', "modules doesn't start with '\\0asm'");
+    uint32_t versionNumber = WTF::unalignedLoad<uint32_t>(data.data() + 4);
+    WASM_PARSER_FAIL_IF(versionNumber != expectedVersionNumber, "unexpected version number ", versionNumber, " expected ", expectedVersionNumber);
+    return State::SectionID;
+}
+
+auto StreamingParser::parseSectionID(Vector<uint8_t>&& data) -> State
+{
+    ASSERT(data.size() == sectionIDSize);
+    size_t offset = 0;
+    auto result = parseUInt7(data.data(), offset, data.size());
+    WASM_PARSER_FAIL_IF(!result, "can't get section byte");
+
+    Section section = Section::Custom;
+    WASM_PARSER_FAIL_IF(!decodeSection(*result, section), "invalid section");
+    ASSERT(section != Section::Begin);
+    WASM_PARSER_FAIL_IF(!validateOrder(m_previousKnownSection, section), "invalid section order, ", m_previousKnownSection, " followed by ", section);
+    m_section = section;
+    if (isKnownSection(section))
+        m_previousKnownSection = section;
+    return State::SectionSize;
+}
+
+auto StreamingParser::parseSectionSize(uint32_t sectionLength) -> State
+{
+    m_sectionLength = sectionLength;
+    if (m_section == Section::Code)
+        return State::CodeSectionSize;
+    return State::SectionPayload;
+}
+
+auto StreamingParser::parseCodeSectionSize(uint32_t functionCount) -> State
+{
+    m_functionCount = functionCount;
+    m_functionIndex = 0;
+    m_codeOffset = m_offset;
+
+    WASM_PARSER_FAIL_IF(functionCount == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", functionCount);
+    WASM_PARSER_FAIL_IF(functionCount != m_info->functions.size(), "Code section count ", functionCount, " exceeds the declared number of functions ", m_info->functions.size());
+
+    if (m_functionIndex == m_functionCount) {
+        WASM_PARSER_FAIL_IF((m_codeOffset + m_sectionLength) != m_nextOffset, "parsing ended before the end of ", m_section, " section");
+        return State::SectionID;
+    }
+    return State::FunctionSize;
+}
+
+auto StreamingParser::parseFunctionSize(uint32_t functionSize) -> State
+{
+    m_functionSize = functionSize;
+    WASM_PARSER_FAIL_IF(functionSize > maxFunctionSize, "Code function's size ", functionSize, " is too big");
+    return State::FunctionPayload;
+}
+
+auto StreamingParser::parseFunctionPayload(Vector<uint8_t>&& data) -> State
+{
+    auto& function = m_info->functions[m_functionIndex];
+    function.start = m_offset;
+    function.end = m_offset + m_functionSize;
+    function.data = WTFMove(data);
+    dataLogLnIf(WasmStreamingParserInternal::verbose, "Processing function starting at: ", function.start, " and ending at: ", function.end);
+    ++m_functionIndex;
+    if (m_functionIndex == m_functionCount) {
+        WASM_PARSER_FAIL_IF((m_codeOffset + m_sectionLength) != (m_offset + m_functionSize), "parsing ended before the end of ", m_section, " section");
+        return State::SectionID;
+    }
+    return State::FunctionSize;
+}
+
+auto StreamingParser::parseSectionPayload(Vector<uint8_t>&& data) -> State
+{
+    SectionParser parser(data.data(), data.size(), m_offset, m_info.get());
+    switch (m_section) {
+#define WASM_SECTION_PARSE(NAME, ID, DESCRIPTION) \
+    case Section::NAME: { \
+        WASM_STREAMING_PARSER_FAIL_IF_HELPER_FAILS(parser.parse ## NAME()); \
+        break; \
+    }
+    FOR_EACH_KNOWN_WASM_SECTION(WASM_SECTION_PARSE)
+#undef WASM_SECTION_PARSE
+
+    case Section::Custom: {
+        WASM_STREAMING_PARSER_FAIL_IF_HELPER_FAILS(parser.parseCustom());
+        break;
+    }
+
+    case Section::Begin: {
+        RELEASE_ASSERT_NOT_REACHED();
+        break;
+    }
+    }
+
+    WASM_PARSER_FAIL_IF(parser.length() != parser.offset(), "parsing ended before the end of ", m_section, " section");
+
+    return State::SectionID;
+}
+
+auto StreamingParser::consume(const uint8_t* bytes, size_t bytesSize, size_t& offsetInBytes, size_t requiredSize) -> std::optional<Vector<uint8_t>>
+{
+    if (m_remaining.size() == requiredSize) {
+        Vector<uint8_t> result = WTFMove(m_remaining);
+        m_nextOffset += requiredSize;
+        return WTFMove(result);
+    }
+
+    if (m_remaining.size() > requiredSize) {
+        Vector<uint8_t> result(requiredSize);
+        memcpy(result.data(), m_remaining.data(), requiredSize);
+        m_remaining.remove(0, requiredSize);
+        m_nextOffset += requiredSize;
+        return WTFMove(result);
+    }
+
+    ASSERT(m_remaining.size() < requiredSize);
+    size_t bytesRemainingSize = bytesSize - offsetInBytes;
+    size_t totalDataSize = m_remaining.size() + bytesRemainingSize;
+    if (totalDataSize < requiredSize) {
+        m_remaining.append(bytes + offsetInBytes, bytesRemainingSize);
+        offsetInBytes = bytesSize;
+        return std::nullopt;
+    }
+
+    size_t usedSize = requiredSize - m_remaining.size();
+    m_remaining.append(bytes + offsetInBytes, usedSize);
+    offsetInBytes += usedSize;
+    Vector<uint8_t> result = WTFMove(m_remaining);
+    m_nextOffset += requiredSize;
+    return WTFMove(result);
+}
+
+auto StreamingParser::consumeVarUInt32(const uint8_t* bytes, size_t bytesSize, size_t& offsetInBytes, IsEndOfStream isEndOfStream) -> Expected<uint32_t, State>
+{
+    constexpr size_t maxSize = WTF::LEBDecoder::maxByteLength<uint32_t>();
+    size_t bytesRemainingSize = bytesSize - offsetInBytes;
+    size_t totalDataSize = m_remaining.size() + bytesRemainingSize;
+    if (m_remaining.size() >= maxSize) {
+        // Do nothing.
+    } else if (totalDataSize >= maxSize) {
+        size_t usedSize = maxSize - m_remaining.size();
+        m_remaining.append(bytes + offsetInBytes, usedSize);
+        offsetInBytes += usedSize;
+    } else {
+        m_remaining.append(bytes + offsetInBytes, bytesRemainingSize);
+        offsetInBytes += bytesRemainingSize;
+        // If the given bytes are the end of the stream, we try to parse VarUInt32
+        // with the current remaining data since VarUInt32 may not require `maxSize`.
+        if (isEndOfStream == IsEndOfStream::No)
+            return makeUnexpected(m_state);
+    }
+
+    size_t offset = 0;
+    uint32_t result = 0;
+    if (!WTF::LEBDecoder::decodeUInt32(m_remaining.data(), m_remaining.size(), offset, result))
+        return makeUnexpected(State::FatalError);
+    size_t consumedSize = offset;
+    m_remaining.remove(0, consumedSize);
+    m_nextOffset += consumedSize;
+    return result;
+}
+
+auto StreamingParser::addBytes(const uint8_t* bytes, size_t bytesSize, IsEndOfStream isEndOfStream) -> State
+{
+    if (m_state == State::FatalError)
+        return m_state;
+
+    m_totalSize += bytesSize;
+    if (UNLIKELY(m_totalSize.hasOverflowed() || m_totalSize.unsafeGet() > maxModuleSize)) {
+        m_state = fail("module size is too large, maximum ", maxModuleSize);
+        return m_state;
+    }
+
+    if (UNLIKELY(Options::useEagerWebAssemblyModuleHashing()))
+        m_hasher.addBytes(bytes, bytesSize);
+
+    size_t offsetInBytes = 0;
+    while (true) {
+        ASSERT(offsetInBytes <= bytesSize);
+        switch (m_state) {
+        case State::ModuleHeader: {
+            auto result = consume(bytes, bytesSize, offsetInBytes, moduleHeaderSize);
+            if (!result)
+                return m_state;
+            m_state = parseModuleHeader(WTFMove(*result));
+            break;
+        }
+
+        case State::SectionID: {
+            auto result = consume(bytes, bytesSize, offsetInBytes, sectionIDSize);
+            if (!result)
+                return m_state;
+            m_state = parseSectionID(WTFMove(*result));
+            break;
+        }
+
+        case State::SectionSize: {
+            auto result = consumeVarUInt32(bytes, bytesSize, offsetInBytes, isEndOfStream);
+            if (!result) {
+                if (result.error() == State::FatalError)
+                    m_state = failOnState(m_state);
+                else
+                    m_state = result.error();
+                return m_state;
+            }
+            m_state = parseSectionSize(*result);
+            break;
+        }
+
+        case State::SectionPayload: {
+            auto result = consume(bytes, bytesSize, offsetInBytes, m_sectionLength);
+            if (!result)
+                return m_state;
+            m_state = parseSectionPayload(WTFMove(*result));
+            break;
+        }
+
+        case State::CodeSectionSize: {
+            auto result = consumeVarUInt32(bytes, bytesSize, offsetInBytes, isEndOfStream);
+            if (!result) {
+                if (result.error() == State::FatalError)
+                    m_state = failOnState(m_state);
+                else
+                    m_state = result.error();
+                return m_state;
+            }
+            m_state = parseCodeSectionSize(*result);
+            break;
+        }
+
+        case State::FunctionSize: {
+            auto result = consumeVarUInt32(bytes, bytesSize, offsetInBytes, isEndOfStream);
+            if (!result) {
+                if (result.error() == State::FatalError)
+                    m_state = failOnState(m_state);
+                else
+                    m_state = result.error();
+                return m_state;
+            }
+            m_state = parseFunctionSize(*result);
+            break;
+        }
+
+        case State::FunctionPayload: {
+            auto result = consume(bytes, bytesSize, offsetInBytes, m_functionSize);
+            if (!result)
+                return m_state;
+            m_state = parseFunctionPayload(WTFMove(*result));
+            break;
+        }
+
+        case State::Finished:
+        case State::FatalError:
+            return m_state;
+        }
+
+        m_offset = m_nextOffset;
+    }
+}
+
+auto StreamingParser::failOnState(State) -> State
+{
+    switch (m_state) {
+    case State::ModuleHeader:
+        return fail("expected a module of at least ", moduleHeaderSize, " bytes");
+    case State::SectionID:
+        return fail("can't get section byte");
+    case State::SectionSize:
+        return fail("can't get ", m_section, " section's length");
+    case State::SectionPayload:
+        return fail(m_section, " section of size ", m_sectionLength, " would overflow Module's size");
+    case State::CodeSectionSize:
+        return fail("can't get Code section's count");
+    case State::FunctionSize:
+        return fail("can't get ", m_functionIndex, "th Code function's size");
+    case State::FunctionPayload:
+        return fail("Code function's size ", m_functionSize, " exceeds the module's remaining size");
+    case State::Finished:
+    case State::FatalError:
+        return m_state;
+    }
+    return m_state;
+}
+
+auto StreamingParser::finalize() -> State
+{
+    addBytes(nullptr, 0, IsEndOfStream::Yes);
+    switch (m_state) {
+    case State::ModuleHeader:
+    case State::SectionSize:
+    case State::SectionPayload:
+    case State::CodeSectionSize:
+    case State::FunctionSize:
+    case State::FunctionPayload:
+        m_state = failOnState(m_state);
+        break;
+
+    case State::Finished:
+    case State::FatalError:
+        break;
+
+    case State::SectionID:
+        if (m_remaining.isEmpty()) {
+            if (UNLIKELY(Options::useEagerWebAssemblyModuleHashing()))
+                m_info->nameSection->setHash(m_hasher.computeHexDigest());
+            m_state = State::Finished;
+        } else
+            m_state = failOnState(State::SectionID);
+        break;
+    }
+    return m_state;
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmStreamingParserh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.h (0 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.h                           (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.h      2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -0,0 +1,127 @@
</span><ins>+/*
+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "WasmModuleInformation.h"
+#include "WasmParser.h"
+#include "WasmSections.h"
+#include <wtf/Expected.h>
+#include <wtf/Optional.h>
+#include <wtf/SHA1.h>
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC { namespace Wasm {
+
+class StreamingParserClient {
+};
+
+class StreamingParser {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    // The layout of the Wasm module is the following.
+    //
+    // Module:       [ Header ][ Section ]*
+    // Section:      [ ID ][ SizeOfPayload ][ Payload ]
+    // Code Section: [ ID ][ SizeOfPayload ][                   Payload of Code Section                   ]
+    //                                      [ NumberOfFunctions ]([ SizeOfFunction ][ PayloadOfFunction ])*
+    //
+    // Basically we can parse Wasm sections by repeatedly (1) reading the size of the payload, and (2) reading the payload based on the size read in (1).
+    // So this streaming parser handles Section as the unit for incremental parsing. The exception is the Code section. The Code section is large since it
+    // includes all the functions in the wasm module. Since we would like to compile each function and parse the Code section concurrently, the streaming
+    // parser specially handles the Code section. In the Code section, the streaming parser uses Function as the unit for incremental parsing.
+    enum class State : uint8_t {
+        ModuleHeader,
+        SectionID,
+        SectionSize,
+        SectionPayload,
+        CodeSectionSize,
+        FunctionSize,
+        FunctionPayload,
+        Finished,
+        FatalError,
+    };
+
+    enum class IsEndOfStream { Yes, No };
+
+    StreamingParser(ModuleInformation&);
+
+    State addBytes(const uint8_t* bytes, size_t length) { return addBytes(bytes, length, IsEndOfStream::No); }
+    State finalize();
+
+    const String& errorMessage() const { return m_errorMessage; }
+
+private:
+    static constexpr unsigned moduleHeaderSize = 8;
+    static constexpr unsigned sectionIDSize = 1;
+
+    State addBytes(const uint8_t* bytes, size_t length, IsEndOfStream);
+
+    State parseModuleHeader(Vector<uint8_t>&&);
+    State parseSectionID(Vector<uint8_t>&&);
+    State parseSectionSize(uint32_t);
+    State parseSectionPayload(Vector<uint8_t>&&);
+
+    State parseCodeSectionSize(uint32_t);
+    State parseFunctionSize(uint32_t);
+    State parseFunctionPayload(Vector<uint8_t>&&);
+
+    std::optional<Vector<uint8_t>> consume(const uint8_t* bytes, size_t, size_t&, size_t);
+    Expected<uint32_t, State> consumeVarUInt32(const uint8_t* bytes, size_t, size_t&, IsEndOfStream);
+
+    template <typename ...Args> NEVER_INLINE State WARN_UNUSED_RETURN fail(Args...);
+
+    State failOnState(State);
+
+    Ref<ModuleInformation> m_info;
+    Vector<uint8_t> m_remaining;
+    String m_errorMessage;
+
+    CheckedSize m_totalSize { 0 };
+    size_t m_offset { 0 };
+    size_t m_nextOffset { 0 };
+    size_t m_codeOffset { 0 };
+
+    SHA1 m_hasher;
+
+    uint32_t m_sectionLength { 0 };
+
+    uint32_t m_functionCount { 0 };
+    uint32_t m_functionIndex { 0 };
+
+    uint32_t m_functionSize { 0 };
+
+    State m_state { State::ModuleHeader };
+    Section m_section { Section::Begin };
+    Section m_previousKnownSection { Section::Begin };
+};
+
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyModulecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp      2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp 2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -140,11 +140,6 @@
</span><span class="cx">         visitor.append(thisObject->m_codeBlocks[i]);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const Vector<uint8_t>& JSWebAssemblyModule::source() const
-{
-    return moduleInformation().source;
-}
-
</del><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyModuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h        2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h   2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -68,8 +68,6 @@
</span><span class="cx">     JSWebAssemblyCodeBlock* codeBlock(Wasm::MemoryMode mode);
</span><span class="cx">     void setCodeBlock(VM&, Wasm::MemoryMode, JSWebAssemblyCodeBlock*);
</span><span class="cx"> 
</span><del>-    const Vector<uint8_t>& source() const;
-
</del><span class="cx">     JS_EXPORT_PRIVATE Wasm::Module& module();
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp     2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp        2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -294,10 +294,10 @@
</span><span class="cx">     size_t byteSize;
</span><span class="cx">     std::tie(base, byteSize) = getWasmBufferFromValue(exec, exec->argument(0));
</span><span class="cx">     RETURN_IF_EXCEPTION(scope, encodedJSValue());
</span><del>-    BBQPlan plan(&vm.wasmContext, base, byteSize, BBQPlan::Validation, Plan::dontFinalize());
</del><ins>+    BBQPlan plan(&vm.wasmContext, BBQPlan::Validation, Plan::dontFinalize());
</ins><span class="cx">     // FIXME: We might want to throw an OOM exception here if we detect that something will OOM.
</span><span class="cx">     // https://bugs.webkit.org/show_bug.cgi?id=166015
</span><del>-    return JSValue::encode(jsBoolean(plan.parseAndValidateModule()));
</del><ins>+    return JSValue::encode(jsBoolean(plan.parseAndValidateModule(base, byteSize)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL webAssemblyCompileStreamingInternal(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/WTF/ChangeLog  2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2018-08-27  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
+
+        [WebAssembly] Parse wasm modules in a streaming fashion
+        https://bugs.webkit.org/show_bug.cgi?id=188943
+
+        Reviewed by Mark Lam.
+
+        Add maxByteLength function to get the maximum size for T.
+
+        * wtf/LEBDecoder.h:
+        (WTF::LEBDecoder::maxByteLength):
+        (WTF::LEBDecoder::decodeUInt):
+        (WTF::LEBDecoder::decodeInt):
+
</ins><span class="cx"> 2018-08-27  Keith Rollin  <krollin@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Unreviewed build fix -- disable LTO for production builds
</span></span></pre></div>
<a id="trunkSourceWTFwtfLEBDecoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/LEBDecoder.h (235419 => 235420)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/LEBDecoder.h        2018-08-28 05:01:05 UTC (rev 235419)
+++ trunk/Source/WTF/wtf/LEBDecoder.h   2018-08-28 06:38:29 UTC (rev 235420)
</span><span class="lines">@@ -36,15 +36,20 @@
</span><span class="cx"> namespace WTF { namespace LEBDecoder {
</span><span class="cx"> 
</span><span class="cx"> template<typename T>
</span><ins>+inline constexpr size_t maxByteLength()
+{
+    const size_t numBits = sizeof(T) * CHAR_BIT;
+    return (numBits - 1) / 7 + 1; // numBits / 7 rounding up.
+}
+
+template<typename T>
</ins><span class="cx"> inline bool WARN_UNUSED_RETURN decodeUInt(const uint8_t* bytes, size_t length, size_t& offset, T& result)
</span><span class="cx"> {
</span><del>-    const size_t numBits = sizeof(T) * CHAR_BIT;
-    const size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up.
</del><span class="cx">     if (length <= offset)
</span><span class="cx">         return false;
</span><span class="cx">     result = 0;
</span><span class="cx">     unsigned shift = 0;
</span><del>-    size_t last = std::min(maxByteLength, length - offset) - 1;
</del><ins>+    size_t last = std::min(maxByteLength<T>(), length - offset) - 1;
</ins><span class="cx">     for (unsigned i = 0; true; ++i) {
</span><span class="cx">         uint8_t byte = bytes[offset++];
</span><span class="cx">         result |= static_cast<T>(byte & 0x7f) << shift;
</span><span class="lines">@@ -61,13 +66,11 @@
</span><span class="cx"> template<typename T>
</span><span class="cx"> inline bool WARN_UNUSED_RETURN decodeInt(const uint8_t* bytes, size_t length, size_t& offset, T& result)
</span><span class="cx"> {
</span><del>-    const size_t numBits = sizeof(T) * CHAR_BIT;
-    const size_t maxByteLength = (numBits - 1) / 7 + 1; // numBits / 7 rounding up.
</del><span class="cx">     if (length <= offset)
</span><span class="cx">         return false;
</span><span class="cx">     result = 0;
</span><span class="cx">     unsigned shift = 0;
</span><del>-    size_t last = std::min(maxByteLength, length - offset) - 1;
</del><ins>+    size_t last = std::min(maxByteLength<T>(), length - offset) - 1;
</ins><span class="cx">     uint8_t byte;
</span><span class="cx">     for (unsigned i = 0; true; ++i) {
</span><span class="cx">         byte = bytes[offset++];
</span><span class="lines">@@ -80,6 +83,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     using UnsignedT = typename std::make_unsigned<T>::type;
</span><ins>+    const size_t numBits = sizeof(T) * CHAR_BIT;
</ins><span class="cx">     if (shift < numBits && (byte & 0x40))
</span><span class="cx">         result = static_cast<T>(static_cast<UnsignedT>(result) | (static_cast<UnsignedT>(-1) << shift));
</span><span class="cx">     return true;
</span></span></pre>
</div>
</div>

</body>
</html>