<!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>[209934] trunk/Source/JavaScriptCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Add missing cases to parseUnreachableExpression and cleanup FunctionParser
https://bugs.webkit.org/show_bug.cgi?id=165966

Reviewed by Saam Barati.

This patch adds a number of missing cases to the Wasm FunctionParser's unreachable
code decoder. It also, removes unneeded OpType namespaces where they were not
needed and has the unary / binary macros cover all the cases rather than
just the simple cases.

* wasm/WasmFunctionParser.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmFunctionParserh">trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (209933 => 209934)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-12-16 21:20:53 UTC (rev 209933)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-12-16 21:36:40 UTC (rev 209934)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2016-12-16  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Add missing cases to parseUnreachableExpression and cleanup FunctionParser
+        https://bugs.webkit.org/show_bug.cgi?id=165966
+
+        Reviewed by Saam Barati.
+
+        This patch adds a number of missing cases to the Wasm FunctionParser's unreachable
+        code decoder. It also, removes unneeded OpType namespaces where they were not
+        needed and has the unary / binary macros cover all the cases rather than
+        just the simple cases.
+
+        * wasm/WasmFunctionParser.h:
+
</ins><span class="cx"> 2016-12-16  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Add predecessor info to dumps from JSC_dumpBytecodeLivenessResults=true.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h (209933 => 209934)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-12-16 21:20:53 UTC (rev 209933)
+++ trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-12-16 21:36:40 UTC (rev 209934)
</span><span class="lines">@@ -136,7 +136,7 @@
</span><span class="cx">             m_context.dump(m_controlStack, m_expressionStack);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        if (op == OpType::End &amp;&amp; !m_controlStack.size()) {
</del><ins>+        if (op == End &amp;&amp; !m_controlStack.size()) {
</ins><span class="cx">             if (m_unreachableBlocks)
</span><span class="cx">                 return { };
</span><span class="cx">             return addReturn();
</span><span class="lines">@@ -201,32 +201,14 @@
</span><span class="cx"> {
</span><span class="cx">     switch (op) {
</span><span class="cx"> #define CREATE_CASE(name, id, b3op, inc) case OpType::name: return binaryCase&lt;OpType::name&gt;();
</span><del>-    FOR_EACH_WASM_SIMPLE_BINARY_OP(CREATE_CASE)
</del><ins>+    FOR_EACH_WASM_BINARY_OP(CREATE_CASE)
</ins><span class="cx"> #undef CREATE_CASE
</span><span class="cx"> 
</span><del>-    case OpType::F32ConvertUI64: return unaryCase&lt;OpType::F32ConvertUI64&gt;();
-    case OpType::F64ConvertUI64: return unaryCase&lt;OpType::F64ConvertUI64&gt;();
-    case OpType::F32Nearest: return unaryCase&lt;OpType::F32Nearest&gt;();
-    case OpType::F64Nearest: return unaryCase&lt;OpType::F64Nearest&gt;();
-    case OpType::F32Trunc: return unaryCase&lt;OpType::F32Trunc&gt;();
-    case OpType::F64Trunc: return unaryCase&lt;OpType::F64Trunc&gt;();
-    case OpType::I32Ctz: return unaryCase&lt;OpType::I32Ctz&gt;();
-    case OpType::I64Ctz: return unaryCase&lt;OpType::I64Ctz&gt;();
-    case OpType::I32Popcnt: return unaryCase&lt;OpType::I32Popcnt&gt;();
-    case OpType::I64Popcnt: return unaryCase&lt;OpType::I64Popcnt&gt;();
-    case OpType::I32TruncSF32: return unaryCase&lt;OpType::I32TruncSF32&gt;();
-    case OpType::I32TruncUF32: return unaryCase&lt;OpType::I32TruncUF32&gt;();
-    case OpType::I32TruncSF64: return unaryCase&lt;OpType::I32TruncSF64&gt;();
-    case OpType::I32TruncUF64: return unaryCase&lt;OpType::I32TruncUF64&gt;();
-    case OpType::I64TruncSF32: return unaryCase&lt;OpType::I64TruncSF32&gt;();
-    case OpType::I64TruncUF32: return unaryCase&lt;OpType::I64TruncUF32&gt;();
-    case OpType::I64TruncSF64: return unaryCase&lt;OpType::I64TruncSF64&gt;();
-    case OpType::I64TruncUF64: return unaryCase&lt;OpType::I64TruncUF64&gt;();
</del><span class="cx"> #define CREATE_CASE(name, id, b3op, inc) case OpType::name: return unaryCase&lt;OpType::name&gt;();
</span><del>-    FOR_EACH_WASM_SIMPLE_UNARY_OP(CREATE_CASE)
</del><ins>+    FOR_EACH_WASM_UNARY_OP(CREATE_CASE)
</ins><span class="cx"> #undef CREATE_CASE
</span><span class="cx"> 
</span><del>-    case OpType::Select: {
</del><ins>+    case Select: {
</ins><span class="cx">         ExpressionType condition;
</span><span class="cx">         ExpressionType zero;
</span><span class="cx">         ExpressionType nonZero;
</span><span class="lines">@@ -270,7 +252,7 @@
</span><span class="cx">     }
</span><span class="cx"> #undef CREATE_CASE
</span><span class="cx"> 
</span><del>-    case OpType::F32Const: {
</del><ins>+    case F32Const: {
</ins><span class="cx">         uint32_t constant;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseUInt32(constant), &quot;can't parse 32-bit floating-point constant&quot;);
</span><span class="cx">         m_expressionStack.append(m_context.addConstant(F32, constant));
</span><span class="lines">@@ -277,7 +259,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::I32Const: {
</del><ins>+    case I32Const: {
</ins><span class="cx">         int32_t constant;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarInt32(constant), &quot;can't parse 32-bit constant&quot;);
</span><span class="cx">         m_expressionStack.append(m_context.addConstant(I32, constant));
</span><span class="lines">@@ -284,7 +266,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::F64Const: {
</del><ins>+    case F64Const: {
</ins><span class="cx">         uint64_t constant;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseUInt64(constant), &quot;can't parse 64-bit floating-point constant&quot;);
</span><span class="cx">         m_expressionStack.append(m_context.addConstant(F64, constant));
</span><span class="lines">@@ -291,7 +273,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::I64Const: {
</del><ins>+    case I64Const: {
</ins><span class="cx">         int64_t constant;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarInt64(constant), &quot;can't parse 64-bit constant&quot;);
</span><span class="cx">         m_expressionStack.append(m_context.addConstant(I64, constant));
</span><span class="lines">@@ -298,7 +280,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::GetLocal: {
</del><ins>+    case GetLocal: {
</ins><span class="cx">         uint32_t index;
</span><span class="cx">         ExpressionType result;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), &quot;can't get index for get_local&quot;);
</span><span class="lines">@@ -307,7 +289,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::SetLocal: {
</del><ins>+    case SetLocal: {
</ins><span class="cx">         uint32_t index;
</span><span class="cx">         ExpressionType value;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), &quot;can't get index for set_local&quot;);
</span><span class="lines">@@ -316,7 +298,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::TeeLocal: {
</del><ins>+    case TeeLocal: {
</ins><span class="cx">         uint32_t index;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), &quot;can't get index for tee_local&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(m_expressionStack.isEmpty(), &quot;can't tee_local on empty expression stack&quot;);
</span><span class="lines">@@ -324,7 +306,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::GetGlobal: {
</del><ins>+    case GetGlobal: {
</ins><span class="cx">         uint32_t index;
</span><span class="cx">         ExpressionType result;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), &quot;can't get get_global's index&quot;);
</span><span class="lines">@@ -333,7 +315,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::SetGlobal: {
</del><ins>+    case SetGlobal: {
</ins><span class="cx">         uint32_t index;
</span><span class="cx">         ExpressionType value;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(index), &quot;can't get set_global's index&quot;);
</span><span class="lines">@@ -342,7 +324,7 @@
</span><span class="cx">         return m_context.setGlobal(index, value);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Call: {
</del><ins>+    case Call: {
</ins><span class="cx">         uint32_t functionIndex;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), &quot;can't parse call's function index&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(functionIndex &gt;= m_functionIndexSpace.size, &quot;call function index &quot;, functionIndex, &quot; exceeds function index space &quot;, m_functionIndexSpace.size);
</span><span class="lines">@@ -366,7 +348,7 @@
</span><span class="cx">             return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::CallIndirect: {
</del><ins>+    case CallIndirect: {
</ins><span class="cx">         uint32_t signatureIndex;
</span><span class="cx">         uint8_t reserved;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!m_info.tableInformation, &quot;call_indirect is only valid when a table is defined or imported&quot;);
</span><span class="lines">@@ -395,7 +377,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Block: {
</del><ins>+    case Block: {
</ins><span class="cx">         Type inlineSignature;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseResultType(inlineSignature), &quot;can't get block's inline signature&quot;);
</span><span class="cx">         m_controlStack.append({ WTFMove(m_expressionStack), m_context.addBlock(inlineSignature) });
</span><span class="lines">@@ -403,7 +385,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Loop: {
</del><ins>+    case Loop: {
</ins><span class="cx">         Type inlineSignature;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseResultType(inlineSignature), &quot;can't get loop's inline signature&quot;);
</span><span class="cx">         m_controlStack.append({ WTFMove(m_expressionStack), m_context.addLoop(inlineSignature) });
</span><span class="lines">@@ -411,7 +393,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::If: {
</del><ins>+    case If: {
</ins><span class="cx">         Type inlineSignature;
</span><span class="cx">         ExpressionType condition;
</span><span class="cx">         ControlType control;
</span><span class="lines">@@ -423,7 +405,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Else: {
</del><ins>+    case Else: {
</ins><span class="cx">         WASM_PARSER_FAIL_IF(m_controlStack.isEmpty(), &quot;can't use else block at the top-level of a function&quot;);
</span><span class="cx">         WASM_TRY_ADD_TO_CONTEXT(addElse(m_controlStack.last().controlData, m_expressionStack));
</span><span class="cx">         m_expressionStack.shrink(0);
</span><span class="lines">@@ -430,13 +412,13 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Br:
-    case OpType::BrIf: {
</del><ins>+    case Br:
+    case BrIf: {
</ins><span class="cx">         uint32_t target;
</span><span class="cx">         ExpressionType condition = Context::emptyExpression;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(target), &quot;can't get br / br_if's target&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(target &gt;= m_controlStack.size(), &quot;br / br_if's target &quot;, target, &quot; exceeds control stack size &quot;, m_controlStack.size());
</span><del>-        if (op == OpType::BrIf)
</del><ins>+        if (op == BrIf)
</ins><span class="cx">             WASM_TRY_POP_EXPRESSION_STACK_INTO(condition, &quot;br / br_if condition&quot;);
</span><span class="cx">         else
</span><span class="cx">             m_unreachableBlocks = 1;
</span><span class="lines">@@ -447,7 +429,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::BrTable: {
</del><ins>+    case BrTable: {
</ins><span class="cx">         uint32_t numberOfTargets;
</span><span class="cx">         ExpressionType condition;
</span><span class="cx">         uint32_t defaultTarget;
</span><span class="lines">@@ -472,11 +454,11 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Return: {
</del><ins>+    case Return: {
</ins><span class="cx">         return addReturn();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::End: {
</del><ins>+    case End: {
</ins><span class="cx">         ControlEntry data = m_controlStack.takeLast();
</span><span class="cx">         // FIXME: This is a little weird in that it will modify the expressionStack for the result of the block.
</span><span class="cx">         // That's a little too effectful for me but I don't have a better API right now.
</span><span class="lines">@@ -486,26 +468,26 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Unreachable: {
</del><ins>+    case Unreachable: {
</ins><span class="cx">         WASM_TRY_ADD_TO_CONTEXT(addUnreachable());
</span><span class="cx">         m_unreachableBlocks = 1;
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Drop: {
</del><ins>+    case Drop: {
</ins><span class="cx">         WASM_PARSER_FAIL_IF(!m_expressionStack.size(), &quot;can't drop on empty stack&quot;);
</span><span class="cx">         m_expressionStack.takeLast();
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Nop: {
</del><ins>+    case Nop: {
</ins><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::GrowMemory:
</del><ins>+    case GrowMemory:
</ins><span class="cx">         return fail(&quot;not yet implemented: grow_memory&quot;); // FIXME: Not yet implemented.
</span><span class="cx"> 
</span><del>-    case OpType::CurrentMemory:
</del><ins>+    case CurrentMemory:
</ins><span class="cx">         return fail(&quot;not yet implemented: current_memory&quot;); // FIXME: Not yet implemented.
</span><span class="cx"> 
</span><span class="cx">     }
</span><span class="lines">@@ -513,12 +495,14 @@
</span><span class="cx">     ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// FIXME: We should try to use the same decoder function for both unreachable and reachable code. https://bugs.webkit.org/show_bug.cgi?id=165965
</ins><span class="cx"> template&lt;typename Context&gt;
</span><span class="cx"> auto FunctionParser&lt;Context&gt;::parseUnreachableExpression(OpType op) -&gt; PartialResult
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_unreachableBlocks);
</span><ins>+#define CREATE_CASE(name, id, b3op, inc) case OpType::name:
</ins><span class="cx">     switch (op) {
</span><del>-    case OpType::Else: {
</del><ins>+    case Else: {
</ins><span class="cx">         if (m_unreachableBlocks &gt; 1)
</span><span class="cx">             return { };
</span><span class="cx"> 
</span><span class="lines">@@ -529,7 +513,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::End: {
</del><ins>+    case End: {
</ins><span class="cx">         if (m_unreachableBlocks == 1) {
</span><span class="cx">             ControlEntry data = m_controlStack.takeLast();
</span><span class="cx">             WASM_TRY_ADD_TO_CONTEXT(addEndToUnreachable(data));
</span><span class="lines">@@ -539,38 +523,72 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    case OpType::Loop:
-    case OpType::If:
-    case OpType::Block: {
</del><ins>+    case Loop:
+    case If:
+    case Block: {
</ins><span class="cx">         m_unreachableBlocks++;
</span><ins>+        int8_t unused;
+        WASM_PARSER_FAIL_IF(!parseInt7(unused), &quot;can't get inline type for &quot;, op, &quot; in unreachable context&quot;);
</ins><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case BrTable: {
+        uint32_t numberOfTargets;
+        uint32_t unused;
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(numberOfTargets), &quot;can't get the number of targets for br_table in unreachable context&quot;);
+        WASM_PARSER_FAIL_IF(numberOfTargets == std::numeric_limits&lt;uint32_t&gt;::max(), &quot;br_table's number of targets is too big &quot;, numberOfTargets);
+
+        for (uint32_t i = 0; i &lt; numberOfTargets; ++i)
+            WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get &quot;, i, &quot;th target for br_table in unreachable context&quot;);
+
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get default target for br_table in unreachable context&quot;);
+        return { };
+    }
+
+
</ins><span class="cx">     // two immediate cases
</span><del>-    case OpType::Br:
-    case OpType::BrIf: {
</del><ins>+    FOR_EACH_WASM_MEMORY_LOAD_OP(CREATE_CASE)
+    FOR_EACH_WASM_MEMORY_STORE_OP(CREATE_CASE)
+    case Br:
+    case BrIf:
+    case CallIndirect: {
</ins><span class="cx">         uint32_t unused;
</span><del>-        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get br / br_if in unreachable context&quot;);
-        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get br / br_if in unreachable context&quot;);
</del><ins>+        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get first immediate for &quot;, op, &quot; in unreachable context&quot;);
+        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get second immediate for &quot;, op, &quot; in unreachable context&quot;);
</ins><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // one immediate cases
</span><del>-    case OpType::F32Const:
-    case OpType::I32Const:
-    case OpType::F64Const:
-    case OpType::I64Const:
-    case OpType::SetLocal:
-    case OpType::GetLocal: {
</del><ins>+    case F32Const:
+    case I32Const:
+    case F64Const:
+    case I64Const:
+    case SetLocal:
+    case GetLocal:
+    case TeeLocal:
+    case GetGlobal:
+    case SetGlobal:
+    case Call: {
</ins><span class="cx">         uint32_t unused;
</span><del>-        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get const / local in unreachable context&quot;);
</del><ins>+        WASM_PARSER_FAIL_IF(!parseVarUInt32(unused), &quot;can't get immediate for &quot;, op, &quot; in unreachable context&quot;);
</ins><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    default:
-        break;
</del><ins>+    // no immediate cases
+    FOR_EACH_WASM_BINARY_OP(CREATE_CASE)
+    FOR_EACH_WASM_UNARY_OP(CREATE_CASE)
+    case Unreachable:
+    case Nop:
+    case Return:
+    case Select:
+    case Drop:
+    case GrowMemory:
+    case CurrentMemory: {
+        return { };
</ins><span class="cx">     }
</span><del>-    return { };
</del><ins>+    }
+#undef CREATE_CASE
+    RELEASE_ASSERT_NOT_REACHED();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre>
</div>
</div>

</body>
</html>