<!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>[209771] 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/209771">209771</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2016-12-13 12:32:40 -0800 (Tue, 13 Dec 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebAssembly: implement the table section and table import
https://bugs.webkit.org/show_bug.cgi?id=165716

Reviewed by Keith Miller.

JSTests:

* wasm/Builder.js:
(const._importMemoryContinuation):
(const._importTableContinuation):
(export.default.Builder.prototype._registerSectionBuilders.switch.case.string_appeared_here.this.section):
(const._importMemoryContinuation.section): Deleted.
(const): Deleted.
(const._importMemoryContinuation.assert): Deleted.
* wasm/Builder_WebAssemblyBinary.js:
(const.putResizableLimits):
(const.putTable):
(const.emitters.Import):
(const.emitters.Table):
* wasm/function-tests/call-indirect-params.js:
* wasm/function-tests/call-indirect.js:
* wasm/function-tests/table-basic-2.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.makeInstance):
(func):
* wasm/function-tests/table-basic.js: Added.
(import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.makeInstance):
* wasm/js-api/call-indirect-results.js:
(const.wasmModuleWhichImportJS): Deleted.
(MonomorphicImport): Deleted.
* wasm/js-api/call-indirect.js:
(const.wasmModuleWhichImportJS):
(const.makeTable):
(Polyphic2Import):
(VirtualImport):
(MonomorphicImport): Deleted.
* wasm/js-api/table.js: Added.
(assertBadBinary):
(assert.truthy):
(assertBadTable):
(assertBadTableImport):
(assertBadBinary.assertBadTableInstance):
(assertBadTableInstance):
(new.WebAssembly.Table):
* wasm/js-api/test_basic_api.js:
(const.c.in.constructorProperties.switch):

Source/JavaScriptCore:

This patch implements the Table space for wasm:
https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#table-section

It only implements defining and importing a table. The bulk
of this patch is implementing the various wasm Table prototype
methods and the underlying Table object:
https://github.com/WebAssembly/design/blob/master/JS.md#webassemblytable-constructor

This patch also fixes a bug in our implementation with call_indirect.
We initially implemented call_indirect as a way to call functions that
are imported or defined in the module. This was the wrong
interpretation of the spec. Instead, call_indirect can only index into
the table index space.

* JavaScriptCore.xcodeproj/project.pbxproj:
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::parseAndCompile):
* wasm/WasmFormat.h:
(JSC::Wasm::TableInformation::TableInformation):
(JSC::Wasm::TableInformation::operator bool):
(JSC::Wasm::TableInformation::isImport):
(JSC::Wasm::TableInformation::initial):
(JSC::Wasm::TableInformation::maximum):
(JSC::Wasm::CallableFunction::CallableFunction):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser&lt;Context&gt;::parseExpression):
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseImport):
(JSC::Wasm::ModuleParser::parseResizableLimits):
(JSC::Wasm::ModuleParser::parseTableHelper):
(JSC::Wasm::ModuleParser::parseTable):
(JSC::Wasm::ModuleParser::parseMemoryHelper):
(JSC::Wasm::ModuleParser::parseExport):
* wasm/WasmModuleParser.h:
* wasm/js/JSWebAssemblyHelpers.h: Added.
(JSC::toNonWrappingUint32):
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::visitChildren):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::table):
(JSC::JSWebAssemblyInstance::setTable):
(JSC::JSWebAssemblyInstance::offsetOfTable):
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::create):
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::visitChildren):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::maximum):
(JSC::JSWebAssemblyTable::size):
(JSC::JSWebAssemblyTable::getFunction):
(JSC::JSWebAssemblyTable::offsetOfSize):
(JSC::JSWebAssemblyTable::offsetOfFunctions):
(JSC::JSWebAssemblyTable::isValidSize):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::call):
(JSC::WebAssemblyFunction::create):
(JSC::WebAssemblyFunction::visitChildren):
(JSC::WebAssemblyFunction::finishCreation):
* wasm/js/WebAssemblyFunction.h:
(JSC::WebAssemblyFunction::signature):
(JSC::WebAssemblyFunction::wasmEntrypoint):
(JSC::WebAssemblyFunction::webAssemblyCallee): Deleted.
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyMemoryConstructor.cpp:
(JSC::constructJSWebAssemblyMemory):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::finishCreation):
(JSC::WebAssemblyModuleRecord::link):
* wasm/js/WebAssemblyTableConstructor.cpp:
(JSC::constructJSWebAssemblyTable):
* wasm/js/WebAssemblyTablePrototype.cpp:
(JSC::getTable):
(JSC::webAssemblyTableProtoFuncLength):
(JSC::webAssemblyTableProtoFuncGrow):
(JSC::webAssemblyTableProtoFuncGet):
(JSC::webAssemblyTableProtoFuncSet):
(JSC::WebAssemblyTablePrototype::create):
(JSC::WebAssemblyTablePrototype::finishCreation):
* wasm/js/WebAssemblyTablePrototype.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestswasmBuilderjs">trunk/JSTests/wasm/Builder.js</a></li>
<li><a href="#trunkJSTestswasmBuilder_WebAssemblyBinaryjs">trunk/JSTests/wasm/Builder_WebAssemblyBinary.js</a></li>
<li><a href="#trunkJSTestswasmfunctiontestscallindirectparamsjs">trunk/JSTests/wasm/function-tests/call-indirect-params.js</a></li>
<li><a href="#trunkJSTestswasmfunctiontestscallindirectjs">trunk/JSTests/wasm/function-tests/call-indirect.js</a></li>
<li><a href="#trunkJSTestswasmjsapicallindirectresultsjs">trunk/JSTests/wasm/js-api/call-indirect-results.js</a></li>
<li><a href="#trunkJSTestswasmjsapicallindirectjs">trunk/JSTests/wasm/js-api/call-indirect.js</a></li>
<li><a href="#trunkJSTestswasmjsapitest_basic_apijs">trunk/JSTests/wasm/js-api/test_basic_api.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="#trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmFormath">trunk/Source/JavaScriptCore/wasm/WasmFormat.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmFunctionParserh">trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.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="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyMemoryConstructorcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyTableConstructorcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypecpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypeh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestswasmfunctionteststablebasic2js">trunk/JSTests/wasm/function-tests/table-basic-2.js</a></li>
<li><a href="#trunkJSTestswasmfunctionteststablebasicjs">trunk/JSTests/wasm/function-tests/table-basic.js</a></li>
<li><a href="#trunkJSTestswasmjsapitablejs">trunk/JSTests/wasm/js-api/table.js</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyHelpersh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/ChangeLog        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1,3 +1,49 @@
</span><ins>+2016-12-13  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        WebAssembly: implement the table section and table import
+        https://bugs.webkit.org/show_bug.cgi?id=165716
+
+        Reviewed by Keith Miller.
+
+        * wasm/Builder.js:
+        (const._importMemoryContinuation):
+        (const._importTableContinuation):
+        (export.default.Builder.prototype._registerSectionBuilders.switch.case.string_appeared_here.this.section):
+        (const._importMemoryContinuation.section): Deleted.
+        (const): Deleted.
+        (const._importMemoryContinuation.assert): Deleted.
+        * wasm/Builder_WebAssemblyBinary.js:
+        (const.putResizableLimits):
+        (const.putTable):
+        (const.emitters.Import):
+        (const.emitters.Table):
+        * wasm/function-tests/call-indirect-params.js:
+        * wasm/function-tests/call-indirect.js:
+        * wasm/function-tests/table-basic-2.js: Added.
+        (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.makeInstance):
+        (func):
+        * wasm/function-tests/table-basic.js: Added.
+        (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.makeInstance):
+        * wasm/js-api/call-indirect-results.js:
+        (const.wasmModuleWhichImportJS): Deleted.
+        (MonomorphicImport): Deleted.
+        * wasm/js-api/call-indirect.js:
+        (const.wasmModuleWhichImportJS):
+        (const.makeTable):
+        (Polyphic2Import):
+        (VirtualImport):
+        (MonomorphicImport): Deleted.
+        * wasm/js-api/table.js: Added.
+        (assertBadBinary):
+        (assert.truthy):
+        (assertBadTable):
+        (assertBadTableImport):
+        (assertBadBinary.assertBadTableInstance):
+        (assertBadTableInstance):
+        (new.WebAssembly.Table):
+        * wasm/js-api/test_basic_api.js:
+        (const.c.in.constructorProperties.switch):
+
</ins><span class="cx"> 2016-12-13  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r209725.
</span></span></pre></div>
<a id="trunkJSTestswasmBuilderjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/Builder.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/Builder.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/Builder.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -103,14 +103,23 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> const _importMemoryContinuation = (builder, section, nextBuilder) =&gt; {
</span><del>-    return (module, field, memoryDescription) =&gt; {
-        assert.isString(module, `Import function module should be a string, got &quot;${module}&quot;`);
-        assert.isString(field, `Import function field should be a string, got &quot;${field}&quot;`);
-        section.data.push({module, field, kind: &quot;Memory&quot;, memoryDescription});
</del><ins>+    return (module, field, {initial, maximum}) =&gt; {
+        assert.isString(module, `Import Memory module should be a string, got &quot;${module}&quot;`);
+        assert.isString(field, `Import Memory field should be a string, got &quot;${field}&quot;`);
+        section.data.push({module, field, kind: &quot;Memory&quot;, memoryDescription: {initial, maximum}});
</ins><span class="cx">         return nextBuilder;
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+const _importTableContinuation = (builder, section, nextBuilder) =&gt; {
+    return (module, field, {initial, maximum, element}) =&gt; {
+        assert.isString(module, `Import Table module should be a string, got &quot;${module}&quot;`);
+        assert.isString(field, `Import Table field should be a string, got &quot;${field}&quot;`);
+        section.data.push({module, field, kind: &quot;Table&quot;, tableDescription: {initial, maximum, element}});
+        return nextBuilder;
+    };
+};
+
</ins><span class="cx"> const _exportFunctionContinuation = (builder, section, nextBuilder) =&gt; {
</span><span class="cx">     return (field, index, type) =&gt; {
</span><span class="cx">         assert.isString(field, `Export function field should be a string, got &quot;${field}&quot;`);
</span><span class="lines">@@ -299,12 +308,31 @@
</span><span class="cx"> 
</span><span class="cx">         if (typeof(signature) === &quot;undefined&quot;)
</span><span class="cx">             signature = { params: [] };
</span><del>-        assert.hasObjectProperty(signature, &quot;params&quot;, `Expect function signature to be an object with a &quot;params&quot; field, got &quot;${signature}&quot;`);
-        const [params, ret] = _normalizeFunctionSignature(signature.params, signature.ret);
-        signature = { params: params, ret: ret };
</del><ins>+
+        let type;
+        let params;
+        if (typeof signature === &quot;object&quot;) {
+            assert.hasObjectProperty(signature, &quot;params&quot;, `Expect function signature to be an object with a &quot;params&quot; field, got &quot;${signature}&quot;`);
+            let ret;
+            ([params, ret] = _normalizeFunctionSignature(signature.params, signature.ret));
+            signature = {params, ret};
+            type = _maybeRegisterType(builder, signature);
+        } else {
+            assert.truthy(typeof signature === &quot;number&quot;);
+            const typeSection = builder._getSection(&quot;Type&quot;);
+            assert.truthy(!!typeSection);
+            // FIXME: we should allow indices that exceed this to be able to
+            // test JSCs validator is correct. https://bugs.webkit.org/show_bug.cgi?id=165786
+            assert.truthy(signature &lt; typeSection.data.length);
+            type = signature;
+            signature = typeSection.data[signature];
+            assert.hasObjectProperty(signature, &quot;params&quot;, `Expect function signature to be an object with a &quot;params&quot; field, got &quot;${signature}&quot;`);
+            params = signature.params;
+        }
+
</ins><span class="cx">         const func = {
</span><span class="cx">             name: functionName,
</span><del>-            type: _maybeRegisterType(builder, signature),
</del><ins>+            type,
</ins><span class="cx">             signature: signature,
</span><span class="cx">             locals: params.concat(locals), // Parameters are the first locals.
</span><span class="cx">             parameterCount: params.length,
</span><span class="lines">@@ -379,11 +407,11 @@
</span><span class="cx">                     const s = this._addSection(section);
</span><span class="cx">                     const importBuilder = {
</span><span class="cx">                         End: () =&gt; this,
</span><del>-                        Table: () =&gt; { throw new Error(`Unimplemented: import table`); },
</del><span class="cx">                         Global: () =&gt; { throw new Error(`Unimplemented: import global`); },
</span><span class="cx">                     };
</span><span class="cx">                     importBuilder.Function = _importFunctionContinuation(this, s, importBuilder);
</span><span class="cx">                     importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder);
</span><ins>+                    importBuilder.Table = _importTableContinuation(this, s, importBuilder);
</ins><span class="cx">                     return importBuilder;
</span><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="lines">@@ -400,8 +428,17 @@
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             case &quot;Table&quot;:
</span><del>-                // FIXME Implement table https://bugs.webkit.org/show_bug.cgi?id=164135
-                this[section] = () =&gt; { throw new Error(`Unimplemented: section type &quot;${section}&quot;`); };
</del><ins>+                this[section] = function() {
+                    const s = this._addSection(section);
+                    const exportBuilder = {
+                        End: () =&gt; this,
+                        Table: ({initial, maximum, element}) =&gt; {
+                            s.data.push({tableDescription: {initial, maximum, element}});
+                            return exportBuilder;
+                        }
+                    };
+                    return exportBuilder;
+                };
</ins><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             case &quot;Memory&quot;:
</span></span></pre></div>
<a id="trunkJSTestswasmBuilder_WebAssemblyBinaryjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/Builder_WebAssemblyBinary.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/Builder_WebAssemblyBinary.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/Builder_WebAssemblyBinary.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -29,6 +29,28 @@
</span><span class="cx"> 
</span><span class="cx"> const put = (bin, type, value) =&gt; bin[type](value);
</span><span class="cx"> 
</span><ins>+const putResizableLimits = (bin, initial, maximum) =&gt; {
+    assert.truthy(typeof initial === &quot;number&quot;, &quot;We expect 'initial' to be an integer&quot;);
+    let hasMaximum = 0;
+    if (typeof maximum === &quot;number&quot;) {
+        hasMaximum = 1;
+    } else {
+        assert.truthy(typeof maximum === &quot;undefined&quot;, &quot;We expect 'maximum' to be an integer if it's defined&quot;);
+    }
+
+    put(bin, &quot;varuint1&quot;, hasMaximum);
+    put(bin, &quot;varuint32&quot;, initial);
+    if (hasMaximum)
+        put(bin, &quot;varuint32&quot;, maximum);
+};
+
+const putTable = (bin, {initial, maximum, element}) =&gt; {
+    assert.truthy(WASM.isValidType(element), &quot;We expect 'element' to be a valid type. It was: &quot; + element);
+    put(bin, &quot;varint7&quot;, WASM.typeValue[element]);
+
+    putResizableLimits(bin, initial, maximum);
+};
+
</ins><span class="cx"> const emitters = {
</span><span class="cx">     Type: (section, bin) =&gt; {
</span><span class="cx">         put(bin, &quot;varuint32&quot;, section.data.length);
</span><span class="lines">@@ -57,23 +79,13 @@
</span><span class="cx">                 put(bin, &quot;varuint32&quot;, entry.type);
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><del>-            case &quot;Table&quot;: throw new Error(`Not yet implemented`);
</del><ins>+            case &quot;Table&quot;: {
+                putTable(bin, entry.tableDescription);
+                break;
+            }
</ins><span class="cx">             case &quot;Memory&quot;: {
</span><span class="cx">                 let {initial, maximum} = entry.memoryDescription;
</span><del>-                assert.truthy(typeof initial === &quot;number&quot;, &quot;We expect 'initial' to be a number&quot;);
-                initial |= 0;
-                let hasMaximum = 0;
-                if (typeof maximum === &quot;number&quot;) {
-                    maximum |= 0;
-                    hasMaximum = 1;
-                } else {
-                    assert.truthy(typeof maximum === &quot;undefined&quot;, &quot;We expect 'maximum' to be a number if it's defined&quot;);
-                }
-
-                put(bin, &quot;varuint1&quot;, hasMaximum);
-                put(bin, &quot;varuint32&quot;, initial);
-                if (hasMaximum)
-                    put(bin, &quot;varuint32&quot;, maximum);
</del><ins>+                putResizableLimits(bin, initial, maximum);
</ins><span class="cx">                 break;
</span><span class="cx">             };
</span><span class="cx">             case &quot;Global&quot;: throw new Error(`Not yet implemented`);
</span><span class="lines">@@ -87,7 +99,12 @@
</span><span class="cx">             put(bin, &quot;varuint32&quot;, signature);
</span><span class="cx">     },
</span><span class="cx"> 
</span><del>-    Table: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</del><ins>+    Table: (section, bin) =&gt; {
+        put(bin, &quot;varuint32&quot;, section.data.length);
+        for (const {tableDescription} of section.data) {
+            putTable(bin, tableDescription);
+        }
+    },
</ins><span class="cx"> 
</span><span class="cx">     Memory: (section, bin) =&gt; {
</span><span class="cx">         // Flags, currently can only be [0,1]
</span></span></pre></div>
<a id="trunkJSTestswasmfunctiontestscallindirectparamsjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/call-indirect-params.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/call-indirect-params.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/function-tests/call-indirect-params.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1,28 +0,0 @@
</span><del>-import Builder from '../Builder.js'
-
-const b = new Builder();
-b.Type().End()
-    .Function().End()
-    .Code()
-
-    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; })
-    .I32Const(1)
-    .End()
-
-    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; })
-    .GetLocal(0)
-    .End()
-
-    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; })
-    .GetLocal(1)
-    .GetLocal(0)
-    .CallIndirect(0, 0)
-    .End()
-
-
-const bin = b.WebAssembly()
-bin.trim();
-testWasmModuleFunctions(bin.get(), 3, [], [],
-                        [[{ type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 4 }]],
-                         [{ type: &quot;i32&quot;, value: 4 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 4 }]],
-                        ]);
</del></span></pre></div>
<a id="trunkJSTestswasmfunctiontestscallindirectjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/function-tests/call-indirect.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/call-indirect.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/function-tests/call-indirect.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1,27 +0,0 @@
</span><del>-import Builder from '../Builder.js'
-
-const b = new Builder();
-b.Type().End()
-    .Function().End()
-    .Code()
-
-    .Function({ params: [], ret: &quot;i32&quot; })
-    .I32Const(1)
-    .End()
-
-    .Function({ params: [], ret: &quot;i32&quot; })
-    .I32Const(2)
-    .End()
-
-    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; })
-    .GetLocal(0)
-    .CallIndirect(0, 0)
-    .End()
-
-
-const bin = b.WebAssembly()
-bin.trim();
-testWasmModuleFunctions(bin.get(), 3, [], [],
-                        [[{ type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
-                         [{ type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
-                        ]);
</del></span></pre></div>
<a id="trunkJSTestswasmfunctionteststablebasic2js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/function-tests/table-basic-2.js (0 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/table-basic-2.js                                (rev 0)
+++ trunk/JSTests/wasm/function-tests/table-basic-2.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+import Builder from '../Builder.js'
+import * as assert from '../assert.js'
+
+function makeInstance(func) {
+    const builder = new Builder()
+        .Type()
+            .Func([&quot;i32&quot;, &quot;i32&quot;], &quot;i32&quot;)
+            .Func([&quot;i32&quot;], &quot;i32&quot;)
+        .End()
+        .Import()
+            .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 20, element: &quot;anyfunc&quot;})
+            .Function(&quot;imp&quot;, &quot;func&quot;, { params: [&quot;i32&quot;], ret: &quot;i32&quot; })
+        .End()
+        .Function().End()
+        .Export()
+            .Function(&quot;foo&quot;)
+            .Function(&quot;bar&quot;)
+        .End()
+        .Code()
+            .Function(&quot;foo&quot;, 0 /*['i32', 'i32'] =&gt; 'i32'*/)
+                .GetLocal(1) // parameter to call
+                .GetLocal(0) // call index
+                .CallIndirect(1, 0) // calling function of type ['i32'] =&gt; 'i32'
+                .Return()
+            .End()
+            .Function(&quot;bar&quot;, 1 /*['i32'] =&gt; 'i32'*/)
+                .GetLocal(0)
+                .Call(0)
+                .Return()
+            .End()
+        .End();
+
+
+    const bin = builder.WebAssembly().get();
+    const module = new WebAssembly.Module(bin);
+    const table = new WebAssembly.Table({initial: 20, element: &quot;anyfunc&quot;});
+    return {instance: new WebAssembly.Instance(module, {imp: {table, func}}), table};
+}
+
+{
+    let i;
+    function func(x) {
+        if (x !== i)
+            throw new Error(&quot;Bad argument&quot;);
+        return x + 44;
+    }
+    const {instance, table} = makeInstance(func);
+    const exports = instance.exports;
+    const foo = exports.foo;
+    table.set(0, exports.bar);
+    assert.eq(table.get(0), exports.bar);
+
+    for (i = 0; i &lt; 10000; i++) {
+        if (foo(0, i) !== i + 44)
+            throw new Error(&quot;Bad call indirect&quot;);
+    }
+}
</ins></span></pre></div>
<a id="trunkJSTestswasmfunctionteststablebasicjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/function-tests/table-basic.js (0 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-tests/table-basic.js                                (rev 0)
+++ trunk/JSTests/wasm/function-tests/table-basic.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+import Builder from '../Builder.js'
+import * as assert from '../assert.js'
+
+function makeInstance() {
+    const builder = new Builder()
+        .Type()
+            .Func([&quot;i32&quot;, &quot;i32&quot;], &quot;i32&quot;)
+            .Func([&quot;i32&quot;], &quot;i32&quot;)
+        .End()
+        .Import()
+            .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 20, element: &quot;anyfunc&quot;})
+        .End()
+        .Function().End()
+        .Export()
+            .Function(&quot;foo&quot;)
+            .Function(&quot;bar&quot;)
+        .End()
+        .Code()
+            .Function(&quot;foo&quot;, 0 /*['i32', 'i32'] =&gt; 'i32'*/)
+                .GetLocal(1) // parameter to call
+                .GetLocal(0) // call index
+                .CallIndirect(1, 0) // calling function of type ['i32'] =&gt; 'i32'
+                .Return()
+            .End()
+            .Function(&quot;bar&quot;, 1 /*['i32'] =&gt; 'i32'*/)
+                .GetLocal(0)
+                .I32Const(42)
+                .I32Add()
+                .Return()
+            .End()
+        .End();
+
+
+    const bin = builder.WebAssembly().get();
+    const module = new WebAssembly.Module(bin);
+    const table = new WebAssembly.Table({initial: 20, element: &quot;anyfunc&quot;});
+    return {instance: new WebAssembly.Instance(module, {imp: {table}}), table};
+}
+
+{
+    const {instance, table} = makeInstance();
+    const exports = instance.exports;
+    const foo = exports.foo;
+    table.set(0, exports.bar);
+    assert.eq(table.get(0), exports.bar);
+
+    for (let i = 0; i &lt; 1000; i++) {
+        if (foo(0, i) !== i + 42)
+            throw new Error(&quot;Bad call indirect&quot;);
+    }
+}
+
+// FIXME: make this work cross module. The reason it doesn't
+// now is that we don't unique Signature*.
+// https://bugs.webkit.org/show_bug.cgi?id=165511
+/*
+{
+    const {instance, table} = makeInstance();
+    const foo = instance.exports.foo;
+    //table.set(0, makeInstance().instance.exports.bar); // Cross instance function.
+
+    for (let i = 0; i &lt; 1000; i++) {
+        if (foo(0, i) !== i + 42)
+            throw new Error(&quot;Bad call indirect&quot;);
+    }
+}
+*/
</ins></span></pre></div>
<a id="trunkJSTestswasmjsapicallindirectresultsjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/call-indirect-results.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/call-indirect-results.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/js-api/call-indirect-results.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1,41 +0,0 @@
</span><del>-import * as assert from '../assert.js';
-import Builder from '../Builder.js';
-
-const wasmModuleWhichImportJS = () =&gt; {
-    const builder = (new Builder())
-        .Type().End()
-        .Import()
-            .Function(&quot;imp&quot;, &quot;func&quot;, { params: [&quot;i32&quot;], ret: &quot;i32&quot; })
-        .End()
-        .Function().End()
-        .Export()
-            .Function(&quot;changeCounter&quot;)
-        .End()
-        .Code()
-            .Function(&quot;changeCounter&quot;, { params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; })
-                .I32Const(42)
-                .GetLocal(0)
-                .I32Add()
-                .GetLocal(1)
-                .CallIndirect(0, 0) // Calls func(param[0] + 42).
-                .I32Const(0)
-                .CallIndirect(0, 0) // Calls func(param[0] + 42).
-            .End()
-        .End();
-    const bin = builder.WebAssembly().get();
-    const module = new WebAssembly.Module(bin);
-    return module;
-};
-
-
-(function MonomorphicImport() {
-    let counter = 0;
-    const counterSetter = v =&gt; counter = v;
-    const module = wasmModuleWhichImportJS();
-    const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter } });
-    for (let i = 0; i &lt; 4096; ++i) {
-        // Invoke this a bunch of times to make sure the IC in the wasm -&gt; JS stub works correctly.
-        instance.exports.changeCounter(i, 0);
-        assert.eq(counter, i + 42);
-    }
-})();
</del></span></pre></div>
<a id="trunkJSTestswasmjsapicallindirectjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/call-indirect.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/call-indirect.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/js-api/call-indirect.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -6,10 +6,12 @@
</span><span class="cx">         .Type().End()
</span><span class="cx">         .Import()
</span><span class="cx">             .Function(&quot;imp&quot;, &quot;func&quot;, { params: [&quot;i32&quot;] })
</span><ins>+            .Table(&quot;imp&quot;, &quot;table&quot;, { initial: 1, maximum: 1, element: &quot;anyfunc&quot;})
</ins><span class="cx">         .End()
</span><span class="cx">         .Function().End()
</span><span class="cx">         .Export()
</span><span class="cx">             .Function(&quot;changeCounter&quot;)
</span><ins>+            .Function(&quot;callFunc&quot;)
</ins><span class="cx">         .End()
</span><span class="cx">         .Code()
</span><span class="cx">             .Function(&quot;changeCounter&quot;, { params: [&quot;i32&quot;, &quot;i32&quot;] })
</span><span class="lines">@@ -17,8 +19,12 @@
</span><span class="cx">                 .GetLocal(0)
</span><span class="cx">                 .I32Add()
</span><span class="cx">                 .GetLocal(1)
</span><del>-                .CallIndirect(0, 0) // Calls func(param[0] + 42).
</del><ins>+                .CallIndirect(0, 0) // Calls table[0](param[0] + 42).
</ins><span class="cx">             .End()
</span><ins>+            .Function(&quot;callFunc&quot;, { params: [&quot;i32&quot;] })
+                .GetLocal(0)
+                .Call(0) // Calls func(param[0] + 42)
+            .End()
</ins><span class="cx">         .End();
</span><span class="cx">     const bin = builder.WebAssembly().get();
</span><span class="cx">     const module = new WebAssembly.Module(bin);
</span><span class="lines">@@ -25,12 +31,17 @@
</span><span class="cx">     return module;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+const makeTable = () =&gt; {
+    return new WebAssembly.Table({initial: 1, maximum: 1, element: &quot;anyfunc&quot;});
+};
</ins><span class="cx"> 
</span><span class="cx"> (function MonomorphicImport() {
</span><span class="cx">     let counter = 0;
</span><span class="cx">     const counterSetter = v =&gt; counter = v;
</span><ins>+    const table = makeTable();
</ins><span class="cx">     const module = wasmModuleWhichImportJS();
</span><del>-    const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter } });
</del><ins>+    const instance = new WebAssembly.Instance(module, { imp: { func: counterSetter, table} });
+    table.set(0, instance.exports.callFunc);
</ins><span class="cx">     for (let i = 0; i &lt; 4096; ++i) {
</span><span class="cx">         // Invoke this a bunch of times to make sure the IC in the wasm -&gt; JS stub works correctly.
</span><span class="cx">         instance.exports.changeCounter(i, 0);
</span><span class="lines">@@ -44,8 +55,14 @@
</span><span class="cx">     const counterASetter = v =&gt; counterA = v;
</span><span class="cx">     const counterBSetter = v =&gt; counterB = { valueB: v };
</span><span class="cx">     const module = wasmModuleWhichImportJS();
</span><del>-    const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter } });
-    const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter } });
</del><ins>+
+    const tableA = makeTable();
+    const instanceA = new WebAssembly.Instance(module, { imp: { func: counterASetter, table: tableA} });
+    tableA.set(0, instanceA.exports.callFunc);
+
+    const tableB = makeTable();
+    const instanceB = new WebAssembly.Instance(module, { imp: { func: counterBSetter, table: tableB} });
+    tableB.set(0, instanceB.exports.callFunc);
</ins><span class="cx">     for (let i = 0; i &lt; 2048; ++i) {
</span><span class="cx">         instanceA.exports.changeCounter(i, 0);
</span><span class="cx">         assert.isA(counterA, &quot;number&quot;);
</span><span class="lines">@@ -57,8 +74,6 @@
</span><span class="cx"> })();
</span><span class="cx"> 
</span><span class="cx"> (function VirtualImport() {
</span><del>-    const num = 10; // It's definitely going virtual at 10!
-    let counters = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
</del><span class="cx">     const counterSetters = [
</span><span class="cx">         v =&gt; counters[0] = v,
</span><span class="cx">         v =&gt; counters[1] = v + 1,
</span><span class="lines">@@ -71,12 +86,16 @@
</span><span class="cx">         v =&gt; counters[8] = v + 8,
</span><span class="cx">         v =&gt; counters[9] = v + 9,
</span><span class="cx">     ];
</span><ins>+    const num = counterSetters.length;
+    let counters = counterSetters.map(() =&gt; 0);
</ins><span class="cx">     assert.eq(counters.length, num);
</span><del>-    assert.eq(counterSetters.length, num);
</del><span class="cx">     const module = wasmModuleWhichImportJS();
</span><span class="cx">     let instances = [];
</span><del>-    for (let i = 0; i &lt; num; ++i)
-        instances[i] = new WebAssembly.Instance(module, { imp: { func: counterSetters[i] } });
</del><ins>+    for (let i = 0; i &lt; num; ++i) {
+        let table = makeTable();
+        instances[i] = new WebAssembly.Instance(module, { imp: { func: counterSetters[i], table} });
+        table.set(0, instances[i].exports.callFunc);
+    }
</ins><span class="cx">     for (let i = 0; i &lt; 2048; ++i) {
</span><span class="cx">         for (let j = 0; j &lt; num; ++j) {
</span><span class="cx">             instances[j].exports.changeCounter(i, 0);
</span></span></pre></div>
<a id="trunkJSTestswasmjsapitablejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/table.js (0 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/table.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/table.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -0,0 +1,230 @@
</span><ins>+import Builder from '../Builder.js';
+import * as assert from '../assert.js';
+
+const badTableString = &quot;couldn't parse section Table&quot;;
+const badImportString = &quot;couldn't parse section Import&quot;;
+function assertBadBinary(builder, str) {
+    const bin = builder.WebAssembly().get();
+    let threw = false;
+    try {
+        new WebAssembly.Module(bin);
+    } catch(e) {
+        threw = true;
+        assert.truthy(e.toString().indexOf(str) !== -1);
+        assert.truthy(e instanceof WebAssembly.CompileError);
+    }
+    assert.truthy(threw);
+}
+
+{
+    const builder = new Builder()
+        .Type().End()
+        .Import()
+            .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 20, element: &quot;anyfunc&quot;})
+        .End()
+        .Function().End()
+        .Table()
+            .Table({initial: 20, maximum: 30, element: &quot;anyfunc&quot;})
+        .End()
+        .Code()
+        .End();
+    assertBadBinary(builder, badTableString);
+}
+
+{
+    const builder = new Builder()
+        .Type().End()
+        .Function().End()
+        .Table()
+            .Table({initial: 20, maximum: 30, element: &quot;anyfunc&quot;})
+            .Table({initial: 20, maximum: 30, element: &quot;anyfunc&quot;})
+        .End()
+        .Code()
+        .End();
+    assertBadBinary(builder, badTableString);
+}
+
+{
+    const builder = new Builder()
+        .Type().End()
+        .Function().End()
+        .Export()
+            .Function(&quot;foo&quot;)
+        .End()
+        .Code()
+            .Function(&quot;foo&quot;, {params: [&quot;i32&quot;]})
+                .GetLocal(0)
+                .CallIndirect(0, 0)
+            .End()
+        .End();
+    assertBadBinary(builder, &quot;call_indirect is only valid when a table is defined or imported&quot;);
+}
+
+{
+    const builder = new Builder()
+        .Type().End()
+        .Function().End()
+        .Table()
+            .Table({initial:20, element:&quot;anyfunc&quot;})
+        .End()
+        .Export()
+            .Function(&quot;foo&quot;)
+        .End()
+        .Code()
+            .Function(&quot;foo&quot;, {params: [&quot;i32&quot;]})
+                .GetLocal(0)
+                .CallIndirect(0, 1)
+            .End()
+        .End();
+    assertBadBinary(builder, &quot;call_indirect 'reserved' varuint1 must be 0x0&quot;);
+}
+
+function assertBadTable(tableDescription) {
+    const builder = new Builder()
+        .Type().End()
+        .Function().End()
+        .Table()
+            .Table(tableDescription)
+        .End()
+        .Code()
+        .End();
+    assertBadBinary(builder, badTableString);
+}
+
+function assertBadTableImport(tableDescription) {
+    const builder = new Builder()
+        .Type().End()
+        .Import()
+            .Table(&quot;imp&quot;, &quot;table&quot;, tableDescription)
+        .End()
+        .Function().End()
+        .Code()
+        .End();
+    assertBadBinary(builder, badImportString);
+}
+
+{
+    let badDescriptions = [
+        {initial: 10, element: &quot;i32&quot;},
+        {initial: 10, element: &quot;f32&quot;},
+        {initial: 10, element: &quot;f64&quot;},
+        {initial: 10, element: &quot;i64&quot;},
+        {initial: 10, maximum: 20, element: &quot;i32&quot;},
+        {initial: 10, maximum: 20, element: &quot;f32&quot;},
+        {initial: 10, maximum: 20, element: &quot;f64&quot;},
+        {initial: 10, maximum: 20, element: &quot;i64&quot;},
+
+        {initial: 10, maximum: 9, element: &quot;anyfunc&quot;},
+        {initial: 1, maximum: 0, element: &quot;anyfunc&quot;},
+        {initial: 2**32 - 1, maximum: 2**32 - 2, element: &quot;anyfunc&quot;},
+        {initial: 2**31, element: &quot;anyfunc&quot;},
+    ];
+
+    for (const d of badDescriptions) {
+        assertBadTable(d);
+        assertBadTableImport(d);
+    }
+}
+
+{
+    const builder = new Builder()
+        .Type().End()
+        .Import()
+            .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 20, element: &quot;anyfunc&quot;})
+            .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 20, element: &quot;anyfunc&quot;})
+        .End()
+        .Function().End()
+        .Code()
+        .End();
+    assertBadBinary(builder, badImportString);
+}
+
+
+{
+    function assertBadTableInstance(tableDescription, table, message) {
+        const builder = new Builder()
+            .Type().End()
+            .Import()
+                .Table(&quot;imp&quot;, &quot;table&quot;, tableDescription)
+            .End()
+            .Function().End()
+            .Code()
+            .End();
+
+        let threw = false;
+        const module = new WebAssembly.Module(builder.WebAssembly().get());
+        try {
+            new WebAssembly.Instance(module, {imp: {table}});
+        } catch (e) {
+            assert.eq(e.toString(), message);
+            threw = true;
+        }
+        assert.truthy(threw);
+    }
+
+    const badTables = [
+        [{initial: 100, maximum:100, element:&quot;anyfunc&quot;}, new WebAssembly.Table({initial:100, element: &quot;anyfunc&quot;}), &quot;TypeError: Table import does not have a 'maximum' but the module requires that it does&quot;],
+        [{initial: 100, maximum:100, element:&quot;anyfunc&quot;}, new WebAssembly.Table({initial:100, maximum:101, element: &quot;anyfunc&quot;}), &quot;TypeError: Imported Table's 'maximum' is larger than the module's expected 'maximum'&quot;],
+        [{initial: 100, element:&quot;anyfunc&quot;}, new WebAssembly.Table({initial:10, element: &quot;anyfunc&quot;}), &quot;TypeError: Table import provided an 'initial' that is too small&quot;],
+        [{initial: 10, element:&quot;anyfunc&quot;}, new WebAssembly.Table({initial:9, element: &quot;anyfunc&quot;}), &quot;TypeError: Table import provided an 'initial' that is too small&quot;],
+    ];
+    for (const [d, t, m] of badTables) {
+        assertBadTableInstance(d, t, m);
+    }
+}
+
+{
+    {
+        const table = new WebAssembly.Table({element: &quot;anyfunc&quot;, initial: 20, maximum: 30});
+        table.grow(30);
+        assert.throws(() =&gt; table.grow(31), TypeError, &quot;WebAssembly.Table.prototype.grow could not grow the table&quot;);
+        assert.throws(() =&gt; table.grow(29), TypeError, &quot;WebAssembly.Table.prototype.grow could not grow the table&quot;);
+    }
+
+    {
+        const table = new WebAssembly.Table({element: &quot;anyfunc&quot;, initial: 20});
+        assert.throws(() =&gt; table.grow({valueOf() { return 19; }}), TypeError, &quot;WebAssembly.Table.prototype.grow could not grow the table&quot;);
+        let called = false;
+        table.grow({valueOf() { called = true; return 21; }});
+        assert.truthy(called);
+    }
+
+    {
+        const table = new WebAssembly.Table({element: &quot;anyfunc&quot;, initial: 20});
+        assert.throws(() =&gt; table.get(20), RangeError, &quot;WebAssembly.Table.prototype.get expects an integer less than the size of the table&quot;);
+        for (let i = 0; i &lt; 20; i++)
+            assert.eq(table.get(i), null);
+    }
+
+    {
+        const table = new WebAssembly.Table({element: &quot;anyfunc&quot;, initial: 20});
+        assert.throws(() =&gt; table.set(20, null), RangeError, &quot;WebAssembly.Table.prototype.set expects an integer less than the size of the table&quot;);
+        for (let i = 0; i &lt; 20; i++)
+            table.set(i, null);
+    }
+
+    {
+        // This should not throw
+        new WebAssembly.Table({initial: 2**20, maximum: 2**32 - 1, element: &quot;anyfunc&quot;});
+    }
+}
+
+{
+
+    function assertBadTable(table) {
+        const builder = new Builder()
+            .Type().End()
+            .Import()
+                .Table(&quot;imp&quot;, &quot;table&quot;, {initial: 25, element: &quot;anyfunc&quot;})
+            .End()
+            .Function().End()
+            .Code()
+            .End();
+        const module = new WebAssembly.Module(builder.WebAssembly().get());
+        assert.throws(() =&gt; new WebAssembly.Instance(module, {imp: {table}}), TypeError, &quot;Table import is not an instance of WebAssembly.Table&quot;);
+    }
+    assertBadTable(25);
+    assertBadTable(new Object);
+    assertBadTable([]);
+    assertBadTable(new WebAssembly.Memory({initial:1}));
+}
</ins></span></pre></div>
<a id="trunkJSTestswasmjsapitest_basic_apijs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/js-api/test_basic_api.js (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/test_basic_api.js        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/JSTests/wasm/js-api/test_basic_api.js        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -78,8 +78,9 @@
</span><span class="cx">         new WebAssembly.Memory({initial: 20});
</span><span class="cx">         break;
</span><span class="cx">     case &quot;Table&quot;:
</span><del>-        // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
-        assert.throws(() =&gt; new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
</del><ins>+        new WebAssembly.Table({initial: 20, element: &quot;anyfunc&quot;});
+        new WebAssembly.Table({initial: 20, maximum: 20, element: &quot;anyfunc&quot;});
+        new WebAssembly.Table({initial: 20, maximum: 25, element: &quot;anyfunc&quot;});
</ins><span class="cx">         break;
</span><span class="cx">     case &quot;CompileError&quot;:
</span><span class="cx">     case &quot;RuntimeError&quot;: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1,3 +1,96 @@
</span><ins>+2016-12-13  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        WebAssembly: implement the table section and table import
+        https://bugs.webkit.org/show_bug.cgi?id=165716
+
+        Reviewed by Keith Miller.
+
+        This patch implements the Table space for wasm:
+        https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#table-section
+
+        It only implements defining and importing a table. The bulk
+        of this patch is implementing the various wasm Table prototype
+        methods and the underlying Table object:
+        https://github.com/WebAssembly/design/blob/master/JS.md#webassemblytable-constructor
+
+        This patch also fixes a bug in our implementation with call_indirect.
+        We initially implemented call_indirect as a way to call functions that
+        are imported or defined in the module. This was the wrong
+        interpretation of the spec. Instead, call_indirect can only index into
+        the table index space.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
+        (JSC::Wasm::B3IRGenerator::addCallIndirect):
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmFormat.h:
+        (JSC::Wasm::TableInformation::TableInformation):
+        (JSC::Wasm::TableInformation::operator bool):
+        (JSC::Wasm::TableInformation::isImport):
+        (JSC::Wasm::TableInformation::initial):
+        (JSC::Wasm::TableInformation::maximum):
+        (JSC::Wasm::CallableFunction::CallableFunction):
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser&lt;Context&gt;::parseExpression):
+        * wasm/WasmModuleParser.cpp:
+        (JSC::Wasm::ModuleParser::parseImport):
+        (JSC::Wasm::ModuleParser::parseResizableLimits):
+        (JSC::Wasm::ModuleParser::parseTableHelper):
+        (JSC::Wasm::ModuleParser::parseTable):
+        (JSC::Wasm::ModuleParser::parseMemoryHelper):
+        (JSC::Wasm::ModuleParser::parseExport):
+        * wasm/WasmModuleParser.h:
+        * wasm/js/JSWebAssemblyHelpers.h: Added.
+        (JSC::toNonWrappingUint32):
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::visitChildren):
+        * wasm/js/JSWebAssemblyInstance.h:
+        (JSC::JSWebAssemblyInstance::table):
+        (JSC::JSWebAssemblyInstance::setTable):
+        (JSC::JSWebAssemblyInstance::offsetOfTable):
+        * wasm/js/JSWebAssemblyTable.cpp:
+        (JSC::JSWebAssemblyTable::create):
+        (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+        (JSC::JSWebAssemblyTable::visitChildren):
+        (JSC::JSWebAssemblyTable::grow):
+        (JSC::JSWebAssemblyTable::clearFunction):
+        (JSC::JSWebAssemblyTable::setFunction):
+        * wasm/js/JSWebAssemblyTable.h:
+        (JSC::JSWebAssemblyTable::maximum):
+        (JSC::JSWebAssemblyTable::size):
+        (JSC::JSWebAssemblyTable::getFunction):
+        (JSC::JSWebAssemblyTable::offsetOfSize):
+        (JSC::JSWebAssemblyTable::offsetOfFunctions):
+        (JSC::JSWebAssemblyTable::isValidSize):
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::WebAssemblyFunction::call):
+        (JSC::WebAssemblyFunction::create):
+        (JSC::WebAssemblyFunction::visitChildren):
+        (JSC::WebAssemblyFunction::finishCreation):
+        * wasm/js/WebAssemblyFunction.h:
+        (JSC::WebAssemblyFunction::signature):
+        (JSC::WebAssemblyFunction::wasmEntrypoint):
+        (JSC::WebAssemblyFunction::webAssemblyCallee): Deleted.
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::constructJSWebAssemblyInstance):
+        * wasm/js/WebAssemblyMemoryConstructor.cpp:
+        (JSC::constructJSWebAssemblyMemory):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::finishCreation):
+        (JSC::WebAssemblyModuleRecord::link):
+        * wasm/js/WebAssemblyTableConstructor.cpp:
+        (JSC::constructJSWebAssemblyTable):
+        * wasm/js/WebAssemblyTablePrototype.cpp:
+        (JSC::getTable):
+        (JSC::webAssemblyTableProtoFuncLength):
+        (JSC::webAssemblyTableProtoFuncGrow):
+        (JSC::webAssemblyTableProtoFuncGet):
+        (JSC::webAssemblyTableProtoFuncSet):
+        (JSC::WebAssemblyTablePrototype::create):
+        (JSC::WebAssemblyTablePrototype::finishCreation):
+        * wasm/js/WebAssemblyTablePrototype.h:
+
</ins><span class="cx"> 2016-12-13  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add null checks to opaque root APIs.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -1413,6 +1413,7 @@
</span><span class="cx">                 795B19971D78BE3500262FA0 /* MapBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 795B19951D78BE3500262FA0 /* MapBase.cpp */; };
</span><span class="cx">                 795B19981D78BE3500262FA0 /* MapBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 795B19961D78BE3500262FA0 /* MapBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
</span><span class="cx">                 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 798937781DCAB57300F8D4FB /* JSFixedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */; };
</span><span class="lines">@@ -3842,6 +3843,7 @@
</span><span class="cx">                 795B19951D78BE3500262FA0 /* MapBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapBase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 795B19961D78BE3500262FA0 /* MapBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapBase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyHelpers.h; path = js/JSWebAssemblyHelpers.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7586,6 +7588,7 @@
</span><span class="cx">                                 79E423E11DEE65320078D355 /* JSWebAssemblyCallee.h */,
</span><span class="cx">                                 AD2FCBA61DB58DA400B3E736 /* JSWebAssemblyCompileError.cpp */,
</span><span class="cx">                                 AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */,
</span><ins>+                                796FB4391DFF8C3F0039C95D /* JSWebAssemblyHelpers.h */,
</ins><span class="cx">                                 AD2FCBA81DB58DA400B3E736 /* JSWebAssemblyInstance.cpp */,
</span><span class="cx">                                 AD2FCBA91DB58DA400B3E736 /* JSWebAssemblyInstance.h */,
</span><span class="cx">                                 AD2FCBAA1DB58DA400B3E736 /* JSWebAssemblyMemory.cpp */,
</span><span class="lines">@@ -8695,6 +8698,7 @@
</span><span class="cx">                                 43422A671C16267800E2EB98 /* B3ReduceDoubleToFloat.h in Headers */,
</span><span class="cx">                                 0F070A4B1D543A98006E7232 /* LargeAllocation.h in Headers */,
</span><span class="cx">                                 86D3B2C610156BDE002865E7 /* MacroAssemblerARM.h in Headers */,
</span><ins>+                                796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */,
</ins><span class="cx">                                 A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */,
</span><span class="cx">                                 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */,
</span><span class="cx">                                 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -137,7 +137,7 @@
</span><span class="cx"> 
</span><span class="cx">     static constexpr ExpressionType emptyExpression = nullptr;
</span><span class="cx"> 
</span><del>-    B3IRGenerator(const MemoryInformation&amp;, Procedure&amp;, WasmInternalFunction*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ImmutableFunctionIndexSpace&amp;);
</del><ins>+    B3IRGenerator(VM&amp;, const MemoryInformation&amp;, Procedure&amp;, WasmInternalFunction*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ImmutableFunctionIndexSpace&amp;);
</ins><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN addArguments(const Vector&lt;Type&gt;&amp;);
</span><span class="cx">     bool WARN_UNUSED_RETURN addLocal(Type, uint32_t);
</span><span class="lines">@@ -188,6 +188,7 @@
</span><span class="cx">     void unifyValuesWithBlock(const ExpressionList&amp; resultStack, ResultList&amp; stack);
</span><span class="cx">     Value* zeroForType(Type);
</span><span class="cx"> 
</span><ins>+    VM&amp; m_vm;
</ins><span class="cx">     const ImmutableFunctionIndexSpace&amp; m_functionIndexSpace;
</span><span class="cx">     Procedure&amp; m_proc;
</span><span class="cx">     BasicBlock* m_currentBlock;
</span><span class="lines">@@ -199,8 +200,9 @@
</span><span class="cx">     Value* m_functionIndexSpaceValue;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-B3IRGenerator::B3IRGenerator(const MemoryInformation&amp; memory, Procedure&amp; procedure, WasmInternalFunction* compilation, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp; unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace&amp; functionIndexSpace)
-    : m_functionIndexSpace(functionIndexSpace)
</del><ins>+B3IRGenerator::B3IRGenerator(VM&amp; vm, const MemoryInformation&amp; memory, Procedure&amp; procedure, WasmInternalFunction* compilation, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp; unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace&amp; functionIndexSpace)
+    : m_vm(vm)
+    , m_functionIndexSpace(functionIndexSpace)
</ins><span class="cx">     , m_proc(procedure)
</span><span class="cx">     , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls)
</span><span class="cx"> {
</span><span class="lines">@@ -669,12 +671,23 @@
</span><span class="cx">     ExpressionType calleeIndex = args.takeLast();
</span><span class="cx">     ASSERT(signature-&gt;arguments.size() == args.size());
</span><span class="cx"> 
</span><ins>+    ExpressionType callableFunctionBuffer;
+    ExpressionType callableFunctionBufferSize;
+    {
+        ExpressionType topInstance = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(),
+            m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), &amp;m_vm.topJSWebAssemblyInstance));
+        ExpressionType table = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(),
+            topInstance, JSWebAssemblyInstance::offsetOfTable());
+        callableFunctionBuffer = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(),
+            table, JSWebAssemblyTable::offsetOfFunctions());
+        callableFunctionBufferSize = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, Int32, Origin(),
+            table, JSWebAssemblyTable::offsetOfSize());
+    }
+
</ins><span class="cx">     // Check the index we are looking for is valid.
</span><span class="cx">     {
</span><del>-        ExpressionType maxValidIndex = m_currentBlock-&gt;appendIntConstant(m_proc, Origin(), Int32, m_functionIndexSpace.size);
</del><span class="cx">         CheckValue* check = m_currentBlock-&gt;appendNew&lt;CheckValue&gt;(m_proc, Check, Origin(),
</span><del>-            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Equal, Origin(), m_zeroValues[linearizeType(I32)],
-                m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, LessThan, Origin(), calleeIndex, maxValidIndex)));
</del><ins>+            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, AboveEqual, Origin(), calleeIndex, callableFunctionBufferSize));
</ins><span class="cx"> 
</span><span class="cx">         check-&gt;setGenerator([] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
</span><span class="cx">             jit.breakpoint();
</span><span class="lines">@@ -681,15 +694,27 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Compute the offset in the function index space we are looking for.
</del><ins>+    // Compute the offset in the table index space we are looking for.
</ins><span class="cx">     ExpressionType offset = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Mul, Origin(),
</span><span class="cx">         m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, ZExt32, Origin(), calleeIndex),
</span><span class="cx">         m_currentBlock-&gt;appendIntConstant(m_proc, Origin(), pointerType(), sizeof(CallableFunction)));
</span><del>-    ExpressionType callableFunction = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Add, Origin(), m_functionIndexSpaceValue, offset);
</del><ins>+    ExpressionType callableFunction = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Add, Origin(), callableFunctionBuffer, offset);
</ins><span class="cx"> 
</span><ins>+    // Check that the CallableFunction is initialized. We trap if it isn't. A null Signature* indicates it's not initialized.
+    ExpressionType calleeSignature = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signature));
+    {
+        CheckValue* check = m_currentBlock-&gt;appendNew&lt;CheckValue&gt;(m_proc, Check, Origin(),
+            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Equal, Origin(), 
+                calleeSignature, 
+                m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), 0)));
+
+        check-&gt;setGenerator([] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
+            jit.breakpoint();
+        });
+    }
+
</ins><span class="cx">     // Check the signature matches the value we expect.
</span><span class="cx">     {
</span><del>-        ExpressionType calleeSignature = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signature));
</del><span class="cx">         ExpressionType expectedSignature = m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), signature);
</span><span class="cx">         CheckValue* check = m_currentBlock-&gt;appendNew&lt;CheckValue&gt;(m_proc, Check, Origin(),
</span><span class="cx">             m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, NotEqual, Origin(), calleeSignature, expectedSignature));
</span><span class="lines">@@ -713,6 +738,7 @@
</span><span class="cx">                 jit.call(params[returnType == Void ? 0 : 1].gpr());
</span><span class="cx">             });
</span><span class="cx">         });
</span><ins>+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -846,7 +872,7 @@
</span><span class="cx">     auto result = std::make_unique&lt;WasmInternalFunction&gt;();
</span><span class="cx"> 
</span><span class="cx">     Procedure procedure;
</span><del>-    B3IRGenerator context(info.memory, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);
</del><ins>+    B3IRGenerator context(vm, info.memory, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);
</ins><span class="cx">     FunctionParser&lt;B3IRGenerator&gt; parser(context, functionStart, functionLength, signature, functionIndexSpace, info);
</span><span class="cx">     if (!parser.parse())
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFormath"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFormat.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFormat.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/WasmFormat.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -106,7 +106,7 @@
</span><span class="cx">     External::Kind kind;
</span><span class="cx">     union {
</span><span class="cx">         uint32_t functionIndex;
</span><del>-        // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+        // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=165782
</ins><span class="cx">         // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=165671
</span><span class="cx">         // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133
</span><span class="cx">     };
</span><span class="lines">@@ -147,11 +147,38 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+class TableInformation {
+public:
+    TableInformation()
+    {
+        ASSERT(!*this);
+    }
+
+    TableInformation(uint32_t initial, std::optional&lt;uint32_t&gt; maximum, bool isImport)
+        : m_initial(initial)
+        , m_maximum(maximum)
+        , m_isImport(isImport)
+        , m_isValid(true)
+    {
+        ASSERT(*this);
+    }
+
+    explicit operator bool() const { return m_isValid; }
+    bool isImport() const { return m_isImport; }
+    uint32_t initial() const { return m_initial; }
+    std::optional&lt;uint32_t&gt; maximum() const { return m_maximum; }
+
+private:
+    uint32_t m_initial;
+    std::optional&lt;uint32_t&gt; m_maximum;
+    bool m_isImport { false };
+    bool m_isValid { false };
+};
+
</ins><span class="cx"> struct ModuleInformation {
</span><span class="cx">     Vector&lt;Signature&gt; signatures;
</span><span class="cx">     Vector&lt;Import&gt; imports;
</span><span class="cx">     Vector&lt;Signature*&gt; importFunctions;
</span><del>-    // FIXME implement import Table https://bugs.webkit.org/show_bug.cgi?id=164135
</del><span class="cx">     // FIXME implement import Global https://bugs.webkit.org/show_bug.cgi?id=164133
</span><span class="cx">     Vector&lt;Signature*&gt; internalFunctionSignatures;
</span><span class="cx">     MemoryInformation memory;
</span><span class="lines">@@ -158,6 +185,7 @@
</span><span class="cx">     Vector&lt;Export&gt; exports;
</span><span class="cx">     std::optional&lt;uint32_t&gt; startFunctionIndexSpace;
</span><span class="cx">     Vector&lt;Segment::Ptr&gt; data;
</span><ins>+    TableInformation tableInformation;
</ins><span class="cx"> 
</span><span class="cx">     ~ModuleInformation();
</span><span class="cx"> };
</span><span class="lines">@@ -185,13 +213,18 @@
</span><span class="cx"> // WebAssembly direct calls and call_indirect use indices into &quot;function index space&quot;. This space starts with all imports, and then all internal functions.
</span><span class="cx"> // CallableFunction and FunctionIndexSpace are only meant as fast lookup tables for these opcodes, and do not own code.
</span><span class="cx"> struct CallableFunction {
</span><del>-    CallableFunction(Signature* signature)
</del><ins>+    CallableFunction() = default;
+
+    CallableFunction(Signature* signature, void* code = nullptr)
</ins><span class="cx">         : signature(signature)
</span><del>-        , code(nullptr)
</del><ins>+        , code(code)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><del>-    Signature* signature; // FIXME pack this inside a (uniqued) integer (for correctness the parser should unique Signatures), and then pack that integer into the code pointer. https://bugs.webkit.org/show_bug.cgi?id=165511
-    void* code;
</del><ins>+
+    // FIXME pack this inside a (uniqued) integer (for correctness the parser should unique Signatures),
+    // and then pack that integer into the code pointer. https://bugs.webkit.org/show_bug.cgi?id=165511
+    Signature* signature { nullptr }; 
+    void* code { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> typedef Vector&lt;CallableFunction&gt; FunctionIndexSpace;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -382,6 +382,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     case OpType::CallIndirect: {
</span><ins>+        if (!m_info.tableInformation)
+            return setErrorMessage(&quot;call_indirect is only valid when a table is defined or imported&quot;);
</ins><span class="cx">         uint32_t signatureIndex;
</span><span class="cx">         if (!parseVarUInt32(signatureIndex))
</span><span class="cx">             return false;
</span><span class="lines">@@ -390,6 +392,9 @@
</span><span class="cx">         if (!parseVarUInt1(reserved))
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><ins>+        if (reserved != 0)
+            return setErrorMessage(&quot;call_indirect 'reserved' varuint1 must be 0x0&quot;);
+
</ins><span class="cx">         if (m_info.signatures.size() &lt;= signatureIndex)
</span><span class="cx">             return setErrorMessage(&quot;Tried to use a signature outside the range of valid signatures&quot;);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;IdentifierInlines.h&quot;
</span><ins>+#include &quot;JSWebAssemblyTable.h&quot;
</ins><span class="cx"> #include &quot;WasmFormat.h&quot;
</span><span class="cx"> #include &quot;WasmMemoryInformation.h&quot;
</span><span class="cx"> #include &quot;WasmOps.h&quot;
</span><span class="lines">@@ -250,7 +251,9 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case External::Table: {
</span><del>-            // FIXME https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+            bool isImport = true;
+            if (!parseTableHelper(isImport))
+                return false;
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case External::Memory: {
</span><span class="lines">@@ -300,45 +303,101 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ModuleParser::parseTable()
</del><ins>+bool ModuleParser::parseResizableLimits(uint32_t&amp; initial, std::optional&lt;uint32_t&gt;&amp; maximum)
</ins><span class="cx"> {
</span><del>-    // FIXME implement table https://bugs.webkit.org/show_bug.cgi?id=164135
-    RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    ASSERT(!maximum);
+
+    uint8_t flags;
+    if (!parseVarUInt1(flags))
+        return false;
+
+    if (!parseVarUInt32(initial))
+        return false;
+
+    if (flags) {
+        uint32_t maximumInt;
+        if (!parseVarUInt32(maximumInt))
+            return false;
+
+        if (initial &gt; maximumInt)
+            return false;
+
+        maximum = maximumInt;
+    }
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ModuleParser::parseMemoryHelper(bool isImport)
</del><ins>+bool ModuleParser::parseTableHelper(bool isImport)
</ins><span class="cx"> {
</span><del>-    // We don't allow redeclaring memory. Either via import or definition.
-    if (m_module-&gt;memory)
</del><ins>+    // We're only allowed a total of one Table import or definition.
+    if (m_hasTable)
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    uint8_t flags;
-    if (!parseVarUInt1(flags))
</del><ins>+    m_hasTable = true;
+
+    int8_t type;
+    if (!parseInt7(type))
</ins><span class="cx">         return false;
</span><ins>+    if (type != Wasm::Anyfunc)
+        return false;
</ins><span class="cx"> 
</span><span class="cx">     uint32_t initial;
</span><del>-    if (!parseVarUInt32(initial))
</del><ins>+    std::optional&lt;uint32_t&gt; maximum;
+    if (!parseResizableLimits(initial, maximum))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    if (!PageCount::isValid(initial))
</del><ins>+    if (!JSWebAssemblyTable::isValidSize(initial))
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    PageCount initialPageCount(initial);
</del><ins>+    ASSERT(!maximum || *maximum &gt;= initial);
</ins><span class="cx"> 
</span><ins>+    m_module-&gt;tableInformation = TableInformation(initial, maximum, isImport);
+
+    return true;
+}
+
+bool ModuleParser::parseTable()
+{
+    uint32_t count;
+    if (!parseVarUInt32(count))
+        return false;
+
+    // We only allow one table for now.
+    if (count != 1)
+        return false;
+
+    bool isImport = false;
+    return parseTableHelper(isImport);
+}
+
+bool ModuleParser::parseMemoryHelper(bool isImport)
+{
+    // We don't allow redeclaring memory. Either via import or definition.
+    if (m_module-&gt;memory)
+        return false;
+
+    PageCount initialPageCount;
</ins><span class="cx">     PageCount maximumPageCount;
</span><del>-    if (flags) {
-        uint32_t maximum;
-        if (!parseVarUInt32(maximum))
</del><ins>+    {
+        uint32_t initial;
+        std::optional&lt;uint32_t&gt; maximum;
+        if (!parseResizableLimits(initial, maximum))
</ins><span class="cx">             return false;
</span><del>-
-        if (!PageCount::isValid(maximum))
</del><ins>+        ASSERT(!maximum || *maximum &gt;= initial);
+        if (!PageCount::isValid(initial))
</ins><span class="cx">             return false;
</span><span class="cx"> 
</span><del>-        maximumPageCount = PageCount(maximum);
-        if (initialPageCount &gt; maximumPageCount)
-            return false;
</del><ins>+        initialPageCount = PageCount(initial);
+
+        if (maximum) {
+            if (!PageCount::isValid(*maximum))
+                return false;
+            maximumPageCount = PageCount(*maximum);
+        }
</ins><span class="cx">     }
</span><ins>+    ASSERT(initialPageCount);
+    ASSERT(!maximumPageCount || maximumPageCount &gt;= initialPageCount);
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;unsigned&gt; pinnedSizes = { 0 };
</span><span class="cx">     m_module-&gt;memory = MemoryInformation(initialPageCount, maximumPageCount, pinnedSizes, isImport);
</span><span class="lines">@@ -397,7 +456,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case External::Table: {
</span><del>-            // FIXME https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+            // FIXME https://bugs.webkit.org/show_bug.cgi?id=165782
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case External::Memory: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -79,6 +79,8 @@
</span><span class="cx"> #undef WASM_SECTION_DECLARE_PARSER
</span><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN parseMemoryHelper(bool isImport);
</span><ins>+    bool WARN_UNUSED_RETURN parseTableHelper(bool isImport);
+    bool WARN_UNUSED_RETURN parseResizableLimits(uint32_t&amp; initial, std::optional&lt;uint32_t&gt;&amp; maximum);
</ins><span class="cx"> 
</span><span class="cx">     VM* m_vm;
</span><span class="cx">     std::unique_ptr&lt;ModuleInformation&gt; m_module;
</span><span class="lines">@@ -85,6 +87,7 @@
</span><span class="cx">     FunctionIndexSpace m_functionIndexSpace;
</span><span class="cx">     Vector&lt;FunctionLocationInBinary&gt; m_functionLocationInBinary;
</span><span class="cx">     bool m_failed { true };
</span><ins>+    bool m_hasTable { false };
</ins><span class="cx">     String m_errorMessage;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyHelpersh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h (0 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;JSCJSValue.h&quot;
+
+namespace JSC {
+
+ALWAYS_INLINE uint32_t toNonWrappingUint32(ExecState* exec, JSValue value)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    double doubleValue = value.toInteger(exec);
+    RETURN_IF_EXCEPTION(throwScope, { });
+    if (doubleValue &lt; 0 || doubleValue &gt; UINT_MAX) {
+        throwException(exec, throwScope,
+            createRangeError(exec, ASCIILiteral(&quot;Expect an integer argument in the range: [0, 2^32 - 1]&quot;)));
+        return { };
+    }
+
+    return static_cast&lt;uint32_t&gt;(doubleValue);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_module);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_moduleNamespaceObject);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_memory);
</span><ins>+    visitor.append(&amp;thisObject-&gt;m_table);
</ins><span class="cx">     for (unsigned i = 0; i &lt; thisObject-&gt;m_numImportFunctions; ++i)
</span><span class="cx">         visitor.append(thisObject-&gt;importFunction(i));
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;JSDestructibleObject.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><span class="cx"> #include &quot;JSWebAssemblyMemory.h&quot;
</span><ins>+#include &quot;JSWebAssemblyTable.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -71,11 +72,16 @@
</span><span class="cx">     JSWebAssemblyMemory* memory() { return m_memory.get(); }
</span><span class="cx">     void setMemory(VM&amp; vm, JSWebAssemblyMemory* memory) { m_memory.set(vm, this, memory); }
</span><span class="cx"> 
</span><ins>+    JSWebAssemblyTable* table() { return m_table.get(); }
+    void setTable(VM&amp; vm, JSWebAssemblyTable* table) { m_table.set(vm, this, table); }
+
</ins><span class="cx">     static size_t offsetOfImportFunction(unsigned idx)
</span><span class="cx">     {
</span><span class="cx">         return offsetOfImportFunctions() + sizeof(WriteBarrier&lt;JSCell&gt;) * idx;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_table); }
+
</ins><span class="cx"> protected:
</span><span class="cx">     JSWebAssemblyInstance(VM&amp;, Structure*, unsigned);
</span><span class="cx">     void finishCreation(VM&amp;, JSWebAssemblyModule*, JSModuleNamespaceObject*);
</span><span class="lines">@@ -96,6 +102,7 @@
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyModule&gt; m_module;
</span><span class="cx">     WriteBarrier&lt;JSModuleNamespaceObject&gt; m_moduleNamespaceObject;
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyMemory&gt; m_memory;
</span><ins>+    WriteBarrier&lt;JSWebAssemblyTable&gt; m_table;
</ins><span class="cx">     unsigned m_numImportFunctions;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -29,12 +29,21 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;WasmFormat.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-JSWebAssemblyTable* JSWebAssemblyTable::create(VM&amp; vm, Structure* structure)
</del><ins>+const ClassInfo JSWebAssemblyTable::s_info = { &quot;WebAssembly.Table&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyTable) };
+
+JSWebAssemblyTable* JSWebAssemblyTable::create(ExecState* exec, VM&amp; vm, Structure* structure, uint32_t initial, std::optional&lt;uint32_t&gt; maximum)
</ins><span class="cx"> {
</span><del>-    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyTable&gt;(vm.heap)) JSWebAssemblyTable(vm, structure);
</del><ins>+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    if (!isValidSize(initial)) {
+        throwException(exec, throwScope, createOutOfMemoryError(exec));
+        return nullptr;
+    }
+
+    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyTable&gt;(vm.heap)) JSWebAssemblyTable(vm, structure, initial, maximum);
</ins><span class="cx">     instance-&gt;finishCreation(vm);
</span><span class="cx">     return instance;
</span><span class="cx"> }
</span><span class="lines">@@ -44,9 +53,23 @@
</span><span class="cx">     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSWebAssemblyTable::JSWebAssemblyTable(VM&amp; vm, Structure* structure)
</del><ins>+JSWebAssemblyTable::JSWebAssemblyTable(VM&amp; vm, Structure* structure, uint32_t initial, std::optional&lt;uint32_t&gt; maximum)
</ins><span class="cx">     : Base(vm, structure)
</span><span class="cx"> {
</span><ins>+    m_size = initial;
+    ASSERT(isValidSize(m_size));
+    m_maximum = maximum;
+    ASSERT(!m_maximum || *m_maximum &gt;= m_size);
+
+    // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
+    // But for now, we're not doing that.
+    m_functions = MallocPtr&lt;Wasm::CallableFunction&gt;::malloc(sizeof(Wasm::CallableFunction) * static_cast&lt;size_t&gt;(m_size));
+    m_jsFunctions = MallocPtr&lt;WriteBarrier&lt;WebAssemblyFunction&gt;&gt;::malloc(sizeof(WriteBarrier&lt;WebAssemblyFunction&gt;) * static_cast&lt;size_t&gt;(m_size));
+    for (uint32_t i = 0; i &lt; m_size; ++i) {
+        new (&amp;m_functions.get()[i]) Wasm::CallableFunction();
+        ASSERT(!m_functions.get()[i].signature); // We rely on this in compiled code.
+        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;WebAssemblyFunction&gt;();
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSWebAssemblyTable::finishCreation(VM&amp; vm)
</span><span class="lines">@@ -62,14 +85,52 @@
</span><span class="cx"> 
</span><span class="cx"> void JSWebAssemblyTable::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
</span><span class="cx"> {
</span><del>-    auto* thisObject = jsCast&lt;JSWebAssemblyTable*&gt;(cell);
</del><ins>+    JSWebAssemblyTable* thisObject = jsCast&lt;JSWebAssemblyTable*&gt;(cell);
</ins><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx"> 
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><ins>+
+    for (unsigned i = 0; i &lt; thisObject-&gt;m_size; ++i)
+        visitor.append(&amp;thisObject-&gt;m_jsFunctions.get()[i]);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-const ClassInfo JSWebAssemblyTable::s_info = { &quot;WebAssembly.Table&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyTable) };
</del><ins>+bool JSWebAssemblyTable::grow(uint32_t newSize)
+{
+    if (newSize &lt; m_size)
+        return false;
+    if (newSize == m_size)
+        return true;
+    if (maximum() &amp;&amp; newSize &gt; *maximum())
+        return false;
+    if (!isValidSize(newSize))
+        return false;
</ins><span class="cx"> 
</span><ins>+    m_functions.realloc(sizeof(Wasm::CallableFunction) * static_cast&lt;size_t&gt;(newSize));
+    m_jsFunctions.realloc(sizeof(WriteBarrier&lt;WebAssemblyFunction&gt;) * static_cast&lt;size_t&gt;(newSize));
+
+    for (uint32_t i = m_size; i &lt; newSize; ++i) {
+        new (&amp;m_functions.get()[i]) Wasm::CallableFunction();
+        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;WebAssemblyFunction&gt;();
+    }
+    m_size = newSize;
+    return true;
+}
+
+void JSWebAssemblyTable::clearFunction(uint32_t index)
+{
+    RELEASE_ASSERT(index &lt; m_size);
+    m_jsFunctions.get()[index] = WriteBarrier&lt;WebAssemblyFunction&gt;();
+    m_functions.get()[index] = Wasm::CallableFunction();
+    ASSERT(!m_functions.get()[index].signature); // We rely on this in compiled code.
+}
+
+void JSWebAssemblyTable::setFunction(VM&amp; vm, uint32_t index, WebAssemblyFunction* function)
+{
+    RELEASE_ASSERT(index &lt; m_size);
+    m_jsFunctions.get()[index].set(vm, this, function);
+    m_functions.get()[index] = Wasm::CallableFunction(function-&gt;signature(), function-&gt;wasmEntrypoint());
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -29,23 +29,54 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSDestructibleObject.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><ins>+#include &quot;WebAssemblyFunction.h&quot;
+#include &lt;wtf/MallocPtr.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+namespace Wasm {
+struct CallableFunction;
+}
+
</ins><span class="cx"> class JSWebAssemblyTable : public JSDestructibleObject {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSDestructibleObject Base;
</span><span class="cx"> 
</span><del>-    static JSWebAssemblyTable* create(VM&amp;, Structure*);
</del><ins>+    static JSWebAssemblyTable* create(ExecState*, VM&amp;, Structure*, uint32_t initial, std::optional&lt;uint32_t&gt; maximum);
</ins><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><del>-protected:
-    JSWebAssemblyTable(VM&amp;, Structure*);
</del><ins>+    std::optional&lt;uint32_t&gt; maximum() const { return m_maximum; }
+    uint32_t size() const { return m_size; }
+    bool grow(uint32_t newSize) WARN_UNUSED_RETURN;
+    WebAssemblyFunction* getFunction(uint32_t index)
+    {
+        RELEASE_ASSERT(index &lt; m_size);
+        return m_jsFunctions.get()[index].get();
+    }
+    void clearFunction(uint32_t index);
+    void setFunction(VM&amp;, uint32_t index, WebAssemblyFunction*);
+
+    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(JSWebAssemblyTable, m_size); }
+    static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(JSWebAssemblyTable, m_functions); }
+
+    static bool isValidSize(uint32_t size)
+    {
+        // This tops out at ~384 MB worth of data in this class.
+        return size &lt; (1 &lt;&lt; 24);
+    }
+
+private:
+    JSWebAssemblyTable(VM&amp;, Structure*, uint32_t initial, std::optional&lt;uint32_t&gt; maximum);
</ins><span class="cx">     void finishCreation(VM&amp;);
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><ins>+
+    MallocPtr&lt;Wasm::CallableFunction&gt; m_functions;
+    MallocPtr&lt;WriteBarrier&lt;WebAssemblyFunction&gt;&gt; m_jsFunctions;
+    std::optional&lt;uint32_t&gt; m_maximum;
+    uint32_t m_size;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -117,7 +117,7 @@
</span><span class="cx">     JSWebAssemblyInstance* prevJSWebAssemblyInstance = vm.topJSWebAssemblyInstance;
</span><span class="cx">     vm.topJSWebAssemblyInstance = instance();
</span><span class="cx">     ASSERT(instance());
</span><del>-    EncodedJSValue rawResult = vmEntryToWasm(webAssemblyCallee()-&gt;entrypoint(), &amp;vm, protoCallFrame);
</del><ins>+    EncodedJSValue rawResult = vmEntryToWasm(m_jsEntrypoint-&gt;entrypoint(), &amp;vm, protoCallFrame);
</ins><span class="cx">     vm.topJSWebAssemblyInstance = prevJSWebAssemblyInstance;
</span><span class="cx"> 
</span><span class="cx">     // FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876
</span><span class="lines">@@ -140,12 +140,12 @@
</span><span class="cx">     return EncodedJSValue();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebAssemblyFunction* WebAssemblyFunction::create(VM&amp; vm, JSGlobalObject* globalObject, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* callee, Wasm::Signature* signature)
</del><ins>+WebAssemblyFunction* WebAssemblyFunction::create(VM&amp; vm, JSGlobalObject* globalObject, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
</ins><span class="cx"> {
</span><span class="cx">     NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
</span><span class="cx">     Structure* structure = globalObject-&gt;webAssemblyFunctionStructure();
</span><span class="cx">     WebAssemblyFunction* function = new (NotNull, allocateCell&lt;WebAssemblyFunction&gt;(vm.heap)) WebAssemblyFunction(vm, globalObject, structure);
</span><del>-    function-&gt;finishCreation(vm, executable, length, name, instance, callee, signature);
</del><ins>+    function-&gt;finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint, signature);
</ins><span class="cx">     return function;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -166,15 +166,18 @@
</span><span class="cx">     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><span class="cx">     visitor.append(&amp;thisObject-&gt;m_instance);
</span><del>-    visitor.append(&amp;thisObject-&gt;m_wasmCallee);
</del><ins>+    visitor.append(&amp;thisObject-&gt;m_jsEntrypoint);
+    visitor.append(&amp;thisObject-&gt;m_wasmEntrypoint);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebAssemblyFunction::finishCreation(VM&amp; vm, NativeExecutable* executable, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* wasmCallee, Wasm::Signature* signature)
</del><ins>+void WebAssemblyFunction::finishCreation(VM&amp; vm, NativeExecutable* executable, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm, executable, length, name);
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="cx">     m_instance.set(vm, this, instance);
</span><del>-    m_wasmCallee.set(vm, this, wasmCallee);
</del><ins>+    ASSERT(jsEntrypoint != wasmEntrypoint);
+    m_jsEntrypoint.set(vm, this, jsEntrypoint);
+    m_wasmEntrypoint.set(vm, this, wasmEntrypoint);
</ins><span class="cx">     m_signature = signature;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -28,12 +28,12 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSFunction.h&quot;
</span><ins>+#include &quot;JSWebAssemblyCallee.h&quot;
</ins><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class JSGlobalObject;
</span><del>-class JSWebAssemblyCallee;
</del><span class="cx"> struct ProtoCallFrame;
</span><span class="cx"> class WebAssemblyInstance;
</span><span class="cx"> 
</span><span class="lines">@@ -53,28 +53,29 @@
</span><span class="cx"> 
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&amp;, JSGlobalObject*, unsigned, const String&amp;, JSWebAssemblyInstance*, JSWebAssemblyCallee*, Wasm::Signature*);
</del><ins>+    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&amp;, JSGlobalObject*, unsigned, const String&amp;, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature*);
</ins><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><del>-    JSWebAssemblyCallee* webAssemblyCallee() const { return m_wasmCallee.get(); }
</del><span class="cx">     JSWebAssemblyInstance* instance() const { return m_instance.get(); }
</span><del>-    const Wasm::Signature* signature()
</del><ins>+    Wasm::Signature* signature()
</ins><span class="cx">     { 
</span><span class="cx">         ASSERT(m_signature);
</span><span class="cx">         return m_signature;
</span><span class="cx">     }
</span><span class="cx">     EncodedJSValue call(VM&amp;, ProtoCallFrame*);
</span><ins>+    void* wasmEntrypoint() { return m_wasmEntrypoint-&gt;entrypoint(); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><del>-    void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSWebAssemblyInstance*, JSWebAssemblyCallee*, Wasm::Signature*);
</del><ins>+    void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature*);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebAssemblyFunction(VM&amp;, JSGlobalObject*, Structure*);
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyInstance&gt; m_instance;
</span><del>-    WriteBarrier&lt;JSWebAssemblyCallee&gt; m_wasmCallee;
</del><ins>+    WriteBarrier&lt;JSWebAssemblyCallee&gt; m_jsEntrypoint;
+    WriteBarrier&lt;JSWebAssemblyCallee&gt; m_wasmEntrypoint;
</ins><span class="cx">     Wasm::Signature* m_signature;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -88,10 +88,10 @@
</span><span class="cx">     // Let imports be an initially-empty list of external values.
</span><span class="cx">     unsigned numImportFunctions = 0;
</span><span class="cx"> 
</span><del>-    // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=164135
</del><span class="cx">     // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133
</span><span class="cx"> 
</span><span class="cx">     bool hasMemoryImport = false;
</span><ins>+    bool hasTableImport = false;
</ins><span class="cx">     // For each import i in module.imports:
</span><span class="cx">     for (auto&amp; import : moduleInformation.imports) {
</span><span class="cx">         // 1. Let o be the resultant value of performing Get(importObject, i.module_name).
</span><span class="lines">@@ -131,12 +131,34 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Table: {
</span><ins>+            RELEASE_ASSERT(!hasTableImport); // This should be guaranteed by a validation failure.
</ins><span class="cx">             // 7. Otherwise (i is a table import):
</span><del>-            // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+            hasTableImport = true;
+            JSWebAssemblyTable* table = jsDynamicCast&lt;JSWebAssemblyTable*&gt;(value);
</ins><span class="cx">             // i. If v is not a WebAssembly.Table object, throw a TypeError.
</span><ins>+            if (!table)
+                return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;Table import is not an instance of WebAssembly.Table&quot;))));
+
+            uint32_t expectedInitial = moduleInformation.tableInformation.initial();
+            uint32_t actualInitial = table-&gt;size();
+            if (actualInitial &lt; expectedInitial)
+                return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;Table import provided an 'initial' that is too small&quot;))));
+
+            if (std::optional&lt;uint32_t&gt; expectedMaximum = moduleInformation.tableInformation.maximum()) {
+                std::optional&lt;uint32_t&gt; actualMaximum = table-&gt;maximum();
+                if (!actualMaximum) {
+                    return JSValue::encode(
+                        throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;Table import does not have a 'maximum' but the module requires that it does&quot;))));
+                }
+                if (*actualMaximum &gt; *expectedMaximum) {
+                    return JSValue::encode(
+                        throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;Imported Table's 'maximum' is larger than the module's expected 'maximum'&quot;))));
+                }
+            }
+
</ins><span class="cx">             // ii. Append v to tables.
</span><span class="cx">             // iii. Append v.[[Table]] to imports.
</span><del>-            RELEASE_ASSERT_NOT_REACHED();
</del><ins>+            instance-&gt;setTable(vm, table);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Memory: {
</span><span class="lines">@@ -185,7 +207,7 @@
</span><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         if (!!moduleInformation.memory &amp;&amp; moduleInformation.memory.isImport()) {
</span><del>-            // We should either have an import or we should have thrown an exception.
</del><ins>+            // We should either have a Memory import or we should have thrown an exception.
</ins><span class="cx">             RELEASE_ASSERT(hasMemoryImport);
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -200,6 +222,25 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    {
+        if (!!moduleInformation.tableInformation &amp;&amp; moduleInformation.tableInformation.isImport()) {
+            // We should either have a Table import or we should have thrown an exception.
+            RELEASE_ASSERT(hasTableImport);
+        }
+
+        if (!!moduleInformation.tableInformation &amp;&amp; !hasTableImport) {
+            RELEASE_ASSERT(!moduleInformation.tableInformation.isImport());
+            // We create a Table when it's a Table definition.
+            JSWebAssemblyTable* table = JSWebAssemblyTable::create(exec, vm, exec-&gt;lexicalGlobalObject()-&gt;WebAssemblyMemoryStructure(),
+                moduleInformation.tableInformation.initial(), moduleInformation.tableInformation.maximum());
+            // We should always be able to allocate a JSWebAssemblyTable we've defined.
+            // If it's defined to be too large, we should have thrown a validation error.
+            ASSERT(!throwScope.exception());
+            ASSERT(table); 
+            instance-&gt;setTable(vm, table);
+        }
+    }
+
</ins><span class="cx">     moduleRecord-&gt;link(exec, instance);
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, { });
</span><span class="cx">     if (verbose)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyMemoryConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FunctionPrototype.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSWebAssemblyHelpers.h&quot;
</ins><span class="cx"> #include &quot;JSWebAssemblyMemory.h&quot;
</span><span class="cx"> #include &quot;WasmMemory.h&quot;
</span><span class="cx"> #include &quot;WasmPageCount.h&quot;
</span><span class="lines">@@ -54,17 +55,6 @@
</span><span class="cx">     if (exec-&gt;argumentCount() != 1)
</span><span class="cx">         return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Memory expects exactly one argument&quot;))));
</span><span class="cx"> 
</span><del>-    auto getUint32 = [&amp;] (JSValue value) -&gt; uint32_t {
-        double doubleValue = value.toInteger(exec);
-        RETURN_IF_EXCEPTION(throwScope, { });
-        if (doubleValue &lt; 0 || doubleValue &gt; UINT_MAX) {
-            throwException(exec, throwScope,
-                createRangeError(exec, ASCIILiteral(&quot;WebAssembly.Memory expects the 'initial' and 'maximum' properties to be integers in the range: [0, 2^32 - 1]&quot;)));
-            return 0;
-        }
-        return static_cast&lt;uint32_t&gt;(doubleValue);
-    };
-
</del><span class="cx">     JSObject* memoryDescriptor;
</span><span class="cx">     {
</span><span class="cx">         JSValue argument = exec-&gt;argument(0);
</span><span class="lines">@@ -78,7 +68,7 @@
</span><span class="cx">         Identifier initial = Identifier::fromString(&amp;vm, &quot;initial&quot;);
</span><span class="cx">         JSValue minSizeValue = memoryDescriptor-&gt;get(exec, initial);
</span><span class="cx">         RETURN_IF_EXCEPTION(throwScope, { });
</span><del>-        uint32_t size = getUint32(minSizeValue);
</del><ins>+        uint32_t size = toNonWrappingUint32(exec, minSizeValue);
</ins><span class="cx">         RETURN_IF_EXCEPTION(throwScope, { });
</span><span class="cx">         if (!Wasm::PageCount::isValid(size))
</span><span class="cx">             return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral(&quot;WebAssembly.Memory 'initial' page count is too large&quot;))));
</span><span class="lines">@@ -93,10 +83,10 @@
</span><span class="cx">         if (hasProperty) {
</span><span class="cx">             JSValue maxSizeValue = memoryDescriptor-&gt;get(exec, maximum);
</span><span class="cx">             RETURN_IF_EXCEPTION(throwScope, { });
</span><del>-            uint32_t size = getUint32(maxSizeValue);
</del><ins>+            uint32_t size = toNonWrappingUint32(exec, maxSizeValue);
+            RETURN_IF_EXCEPTION(throwScope, { });
</ins><span class="cx">             if (!Wasm::PageCount::isValid(size))
</span><span class="cx">                 return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral(&quot;WebAssembly.Memory 'maximum' page count is too large&quot;))));
</span><del>-            RETURN_IF_EXCEPTION(throwScope, { });
</del><span class="cx">             maximumPageCount = Wasm::PageCount(size);
</span><span class="cx"> 
</span><span class="cx">             if (initialPageCount &gt; maximumPageCount) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Table: {
</span><del>-            // FIXME https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+            // FIXME https://bugs.webkit.org/show_bug.cgi?id=165782
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Memory: {
</span><span class="lines">@@ -136,9 +136,10 @@
</span><span class="cx">             //     a. Let func be an Exported Function Exotic Object created from c.
</span><span class="cx">             //     b. Append func to funcs.
</span><span class="cx">             //     c. Return func.
</span><del>-            JSWebAssemblyCallee* wasmCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(exp.functionIndex);
</del><ins>+            JSWebAssemblyCallee* jsEntrypointCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(exp.functionIndex);
+            JSWebAssemblyCallee* wasmEntrypointCallee = module-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(exp.functionIndex);
</ins><span class="cx">             Wasm::Signature* signature = module-&gt;signatureForFunctionIndexSpace(exp.functionIndex);
</span><del>-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), exp.field.string(), instance, wasmCallee, signature);
</del><ins>+            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signature);
</ins><span class="cx">             exportedValue = function;
</span><span class="cx">             if (hasStart &amp;&amp; startFunctionIndexSpace == exp.functionIndex)
</span><span class="cx">                 m_startFunction.set(vm, this, function);
</span><span class="lines">@@ -145,7 +146,7 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Table: {
</span><del>-            // FIXME https://bugs.webkit.org/show_bug.cgi?id=164135
</del><ins>+            // FIXME https://bugs.webkit.org/show_bug.cgi?id=165782
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::External::Memory: {
</span><span class="lines">@@ -174,8 +175,9 @@
</span><span class="cx">         // FIXME can start call imports / tables? This assumes not. https://github.com/WebAssembly/design/issues/896
</span><span class="cx">         if (!m_startFunction.get()) {
</span><span class="cx">             // The start function wasn't added above. It must be a purely internal function.
</span><del>-            JSWebAssemblyCallee* wasmCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), &quot;start&quot;, instance, wasmCallee, signature);
</del><ins>+            JSWebAssemblyCallee* jsEntrypointCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
+            JSWebAssemblyCallee* wasmEntrypointCallee = module-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
+            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), &quot;start&quot;, instance, jsEntrypointCallee, wasmEntrypointCallee, signature);
</ins><span class="cx">             m_startFunction.set(vm, this, function);
</span><span class="cx">         }
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyTableConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -30,6 +30,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FunctionPrototype.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSWebAssemblyHelpers.h&quot;
+#include &quot;JSWebAssemblyTable.h&quot;
</ins><span class="cx"> #include &quot;WebAssemblyTablePrototype.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;WebAssemblyTableConstructor.lut.h&quot;
</span><span class="lines">@@ -43,12 +45,53 @@
</span><span class="cx">  @end
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyTable(ExecState* state)
</del><ins>+static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyTable(ExecState* exec)
</ins><span class="cx"> {
</span><del>-    VM&amp; vm = state-&gt;vm();
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    // FIXME https://bugs.webkit.org/show_bug.cgi?id=164135
-    return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral(&quot;WebAssembly doesn't yet implement the Table constructor property&quot;))));
</del><ins>+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSObject* memoryDescriptor;
+    {
+        JSValue argument = exec-&gt;argument(0);
+        if (!argument.isObject())
+            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Table expects its first argument to be an object&quot;))));
+        memoryDescriptor = jsCast&lt;JSObject*&gt;(argument);
+    }
+
+    {
+        Identifier elementIdent = Identifier::fromString(&amp;vm, &quot;element&quot;);
+        JSValue elementValue = memoryDescriptor-&gt;get(exec, elementIdent);
+        RETURN_IF_EXCEPTION(throwScope, { });
+        String elementString = elementValue.toWTFString(exec);
+        RETURN_IF_EXCEPTION(throwScope, { });
+        if (elementString != &quot;anyfunc&quot;)
+            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Table expects its 'element' field to be the string 'anyfunc'&quot;))));
+    }
+
+    Identifier initialIdent = Identifier::fromString(&amp;vm, &quot;initial&quot;);
+    JSValue initialSizeValue = memoryDescriptor-&gt;get(exec, initialIdent);
+    RETURN_IF_EXCEPTION(throwScope, { });
+    uint32_t initial = toNonWrappingUint32(exec, initialSizeValue);
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    std::optional&lt;uint32_t&gt; maximum;
+    Identifier maximumIdent = Identifier::fromString(&amp;vm, &quot;maximum&quot;);
+    bool hasProperty = memoryDescriptor-&gt;hasProperty(exec, maximumIdent);
+    RETURN_IF_EXCEPTION(throwScope, { });
+    if (hasProperty) {
+        JSValue maxSizeValue = memoryDescriptor-&gt;get(exec, maximumIdent);
+        RETURN_IF_EXCEPTION(throwScope, { });
+        maximum = toNonWrappingUint32(exec, maxSizeValue);
+        RETURN_IF_EXCEPTION(throwScope, { });
+
+        if (initial &gt; *maximum) {
+            return JSValue::encode(throwException(exec, throwScope,
+                createRangeError(exec, ASCIILiteral(&quot;'maximum' property must be greater than or equal to the 'initial' property&quot;))));
+        }
+    }
+
+    throwScope.release();
+    return JSValue::encode(JSWebAssemblyTable::create(exec, vm, exec-&gt;lexicalGlobalObject()-&gt;WebAssemblyTableStructure(), initial, maximum));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyTable(ExecState* state)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -30,6 +30,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FunctionPrototype.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;JSWebAssemblyHelpers.h&quot;
+#include &quot;JSWebAssemblyTable.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;WebAssemblyTablePrototype.lut.h&quot;
</span><span class="cx"> 
</span><span class="lines">@@ -42,10 +44,112 @@
</span><span class="cx">  @end
</span><span class="cx">  */
</span><span class="cx"> 
</span><del>-WebAssemblyTablePrototype* WebAssemblyTablePrototype::create(VM&amp; vm, JSGlobalObject*, Structure* structure)
</del><ins>+static ALWAYS_INLINE JSWebAssemblyTable* getTable(ExecState* exec, VM&amp; vm, JSValue v)
</ins><span class="cx"> {
</span><ins>+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+    JSWebAssemblyTable* result = jsDynamicCast&lt;JSWebAssemblyTable*&gt;(v);
+    if (!result) {
+        throwException(exec, throwScope, 
+            createTypeError(exec, ASCIILiteral(&quot;expected |this| value to be an instance of WebAssembly.Table&quot;)));
+        return nullptr;
+    }
+    return result;
+}
+
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncLength(ExecState*);
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGrow(ExecState*);
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGet(ExecState*);
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncSet(ExecState*);
+
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncLength(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSWebAssemblyTable* table = getTable(exec, vm, exec-&gt;thisValue());
+    RETURN_IF_EXCEPTION(throwScope, { });
+    return JSValue::encode(jsNumber(table-&gt;size()));
+}
+
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGrow(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSWebAssemblyTable* table = getTable(exec, vm, exec-&gt;thisValue());
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    uint32_t index = toNonWrappingUint32(exec, exec-&gt;argument(0));
+    RETURN_IF_EXCEPTION(throwScope, { });
+    if (!table-&gt;grow(index)) {
+        throwException(exec, throwScope,
+            createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Table.prototype.grow could not grow the table&quot;)));
+        return { };
+    }
+
+    return JSValue::encode(jsUndefined());
+}
+
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGet(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSWebAssemblyTable* table = getTable(exec, vm, exec-&gt;thisValue());
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    uint32_t index = toNonWrappingUint32(exec, exec-&gt;argument(0));
+    RETURN_IF_EXCEPTION(throwScope, { });
+    if (index &gt;= table-&gt;size()) {
+        throwException(exec, throwScope,
+            createRangeError(exec, ASCIILiteral(&quot;WebAssembly.Table.prototype.get expects an integer less than the size of the table&quot;)));
+        return { };
+    }
+
+    if (WebAssemblyFunction* result = table-&gt;getFunction(index))
+        return JSValue::encode(result);
+    return JSValue::encode(jsNull());
+}
+
+EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncSet(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto throwScope = DECLARE_THROW_SCOPE(vm);
+
+    JSWebAssemblyTable* table = getTable(exec, vm, exec-&gt;thisValue());
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    JSValue value = exec-&gt;argument(1);
+    WebAssemblyFunction* function = jsDynamicCast&lt;WebAssemblyFunction*&gt;(value);
+    if (!value.isNull() &amp;&amp; !function) {
+        throwException(exec, throwScope,
+            createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Table.prototype.set expects the second argument to be null or an instance of WebAssembly.Function&quot;)));
+        return { };
+    }
+
+    uint32_t index = toNonWrappingUint32(exec, exec-&gt;argument(0));
+    RETURN_IF_EXCEPTION(throwScope, { });
+
+    if (index &gt;= table-&gt;size()) {
+        throwException(exec, throwScope,
+            createRangeError(exec, ASCIILiteral(&quot;WebAssembly.Table.prototype.set expects an integer less than the size of the table&quot;)));
+        return { };
+    }
+
+    if (value.isNull())
+        table-&gt;clearFunction(index);
+    else {
+        ASSERT(!!function);
+        table-&gt;setFunction(vm, index, function);
+    }
+    
+    return JSValue::encode(jsUndefined());
+}
+
+WebAssemblyTablePrototype* WebAssemblyTablePrototype::create(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure)
+{
</ins><span class="cx">     auto* object = new (NotNull, allocateCell&lt;WebAssemblyTablePrototype&gt;(vm.heap)) WebAssemblyTablePrototype(vm, structure);
</span><del>-    object-&gt;finishCreation(vm);
</del><ins>+    object-&gt;finishCreation(vm, globalObject);
</ins><span class="cx">     return object;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -54,9 +158,14 @@
</span><span class="cx">     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebAssemblyTablePrototype::finishCreation(VM&amp; vm)
</del><ins>+void WebAssemblyTablePrototype::finishCreation(VM&amp; vm, JSGlobalObject* globalObject)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm);
</span><ins>+
+    JSC_NATIVE_GETTER(&quot;length&quot;, webAssemblyTableProtoFuncLength, DontEnum | Accessor);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;grow&quot;, webAssemblyTableProtoFuncGrow, DontEnum, 1);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;get&quot;, webAssemblyTableProtoFuncGet, DontEnum, 1);
+    JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION(&quot;set&quot;, webAssemblyTableProtoFuncSet, DontEnum, 2);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebAssemblyTablePrototype::WebAssemblyTablePrototype(VM&amp; vm, Structure* structure)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.h (209770 => 209771)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.h        2016-12-13 20:24:11 UTC (rev 209770)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.h        2016-12-13 20:32:40 UTC (rev 209771)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    void finishCreation(VM&amp;);
</del><ins>+    void finishCreation(VM&amp;, JSGlobalObject*);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebAssemblyTablePrototype(VM&amp;, Structure*);
</span></span></pre>
</div>
</div>

</body>
</html>