LCOV - code coverage report
Current view: top level - js/src/wasm - WasmValidate.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 833 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 45 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  *
       4             :  * Copyright 2016 Mozilla Foundation
       5             :  *
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at
       9             :  *
      10             :  *     http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  */
      18             : 
      19             : #include "wasm/WasmValidate.h"
      20             : 
      21             : #include "mozilla/CheckedInt.h"
      22             : 
      23             : #include "jsprf.h"
      24             : 
      25             : #include "jit/JitOptions.h"
      26             : #include "wasm/WasmBinaryIterator.h"
      27             : 
      28             : using namespace js;
      29             : using namespace js::jit;
      30             : using namespace js::wasm;
      31             : 
      32             : using mozilla::CheckedInt;
      33             : 
      34             : // Decoder implementation.
      35             : 
      36             : bool
      37           0 : Decoder::failf(const char* msg, ...)
      38             : {
      39             :     va_list ap;
      40           0 :     va_start(ap, msg);
      41           0 :     UniqueChars str(JS_vsmprintf(msg, ap));
      42           0 :     va_end(ap);
      43           0 :     if (!str)
      44           0 :         return false;
      45             : 
      46           0 :     return fail(str.get());
      47             : }
      48             : 
      49             : bool
      50           0 : Decoder::fail(size_t errorOffset, const char* msg)
      51             : {
      52           0 :     MOZ_ASSERT(error_);
      53           0 :     UniqueChars strWithOffset(JS_smprintf("at offset %" PRIuSIZE ": %s", errorOffset, msg));
      54           0 :     if (!strWithOffset)
      55           0 :         return false;
      56             : 
      57           0 :     *error_ = Move(strWithOffset);
      58           0 :     return false;
      59             : }
      60             : 
      61             : bool
      62           0 : Decoder::startSection(SectionId id, ModuleEnvironment* env, uint32_t* sectionStart,
      63             :                       uint32_t* sectionSize, const char* sectionName)
      64             : {
      65             :     // Record state at beginning of section to allow rewinding to this point
      66             :     // if, after skipping through several custom sections, we don't find the
      67             :     // section 'id'.
      68           0 :     const uint8_t* const initialCur = cur_;
      69           0 :     const size_t initialCustomSectionsLength = env->customSections.length();
      70             : 
      71             :     // Maintain a pointer to the current section that gets updated as custom
      72             :     // sections are skipped.
      73           0 :     const uint8_t* currentSectionStart = cur_;
      74             : 
      75             :     // Only start a section with 'id', skipping any custom sections before it.
      76             : 
      77             :     uint32_t idValue;
      78           0 :     if (!readVarU32(&idValue))
      79           0 :         goto rewind;
      80             : 
      81           0 :     while (idValue != uint32_t(id)) {
      82           0 :         if (idValue != uint32_t(SectionId::Custom))
      83           0 :             goto rewind;
      84             : 
      85             :         // Rewind to the beginning of the current section since this is what
      86             :         // skipCustomSection() assumes.
      87           0 :         cur_ = currentSectionStart;
      88           0 :         if (!skipCustomSection(env))
      89           0 :             return false;
      90             : 
      91             :         // Having successfully skipped a custom section, consider the next
      92             :         // section.
      93           0 :         currentSectionStart = cur_;
      94           0 :         if (!readVarU32(&idValue))
      95           0 :             goto rewind;
      96             :     }
      97             : 
      98             :     // Found it, now start the section.
      99             : 
     100           0 :     if (!readVarU32(sectionSize) || bytesRemain() < *sectionSize)
     101           0 :         goto fail;
     102             : 
     103           0 :     *sectionStart = cur_ - beg_;
     104           0 :     return true;
     105             : 
     106             :   rewind:
     107           0 :     cur_ = initialCur;
     108           0 :     env->customSections.shrinkTo(initialCustomSectionsLength);
     109           0 :     *sectionStart = NotStarted;
     110           0 :     return true;
     111             : 
     112             :   fail:
     113           0 :     return failf("failed to start %s section", sectionName);
     114             : }
     115             : 
     116             : bool
     117           0 : Decoder::finishSection(uint32_t sectionStart, uint32_t sectionSize, const char* sectionName)
     118             : {
     119           0 :     if (resilientMode_)
     120           0 :         return true;
     121           0 :     if (sectionSize != (cur_ - beg_) - sectionStart)
     122           0 :         return failf("byte size mismatch in %s section", sectionName);
     123           0 :     return true;
     124             : }
     125             : 
     126             : bool
     127           0 : Decoder::startCustomSection(const char* expected, size_t expectedLength, ModuleEnvironment* env,
     128             :                             uint32_t* sectionStart, uint32_t* sectionSize)
     129             : {
     130             :     // Record state at beginning of section to allow rewinding to this point
     131             :     // if, after skipping through several custom sections, we don't find the
     132             :     // section 'id'.
     133           0 :     const uint8_t* const initialCur = cur_;
     134           0 :     const size_t initialCustomSectionsLength = env->customSections.length();
     135             : 
     136             :     while (true) {
     137             :         // Try to start a custom section. If we can't, rewind to the beginning
     138             :         // since we may have skipped several custom sections already looking for
     139             :         // 'expected'.
     140           0 :         if (!startSection(SectionId::Custom, env, sectionStart, sectionSize, "custom"))
     141           0 :             return false;
     142           0 :         if (*sectionStart == NotStarted)
     143           0 :             goto rewind;
     144             : 
     145           0 :         NameInBytecode name;
     146           0 :         if (!readVarU32(&name.length) || name.length > bytesRemain())
     147           0 :             goto fail;
     148             : 
     149           0 :         name.offset = currentOffset();
     150           0 :         uint32_t payloadOffset = name.offset + name.length;
     151           0 :         uint32_t payloadEnd = *sectionStart + *sectionSize;
     152           0 :         if (payloadOffset > payloadEnd)
     153           0 :             goto fail;
     154             : 
     155             :         // Now that we have a valid custom section, record its offsets in the
     156             :         // metadata which can be queried by the user via Module.customSections.
     157             :         // Note: after an entry is appended, it may be popped if this loop or
     158             :         // the loop in startSection needs to rewind.
     159           0 :         if (!env->customSections.emplaceBack(name, payloadOffset, payloadEnd - payloadOffset))
     160           0 :             return false;
     161             : 
     162             :         // If this is the expected custom section, we're done.
     163           0 :         if (!expected || (expectedLength == name.length && !memcmp(cur_, expected, name.length))) {
     164           0 :             cur_ += name.length;
     165           0 :             return true;
     166             :         }
     167             : 
     168             :         // Otherwise, blindly skip the custom section and keep looking.
     169           0 :         finishCustomSection(*sectionStart, *sectionSize);
     170           0 :     }
     171             :     MOZ_CRASH("unreachable");
     172             : 
     173             :   rewind:
     174           0 :     cur_ = initialCur;
     175           0 :     env->customSections.shrinkTo(initialCustomSectionsLength);
     176           0 :     return true;
     177             : 
     178             :   fail:
     179           0 :     return fail("failed to start custom section");
     180             : }
     181             : 
     182             : void
     183           0 : Decoder::finishCustomSection(uint32_t sectionStart, uint32_t sectionSize)
     184             : {
     185           0 :     MOZ_ASSERT(cur_ >= beg_);
     186           0 :     MOZ_ASSERT(cur_ <= end_);
     187           0 :     cur_ = (beg_ + sectionStart) + sectionSize;
     188           0 :     MOZ_ASSERT(cur_ <= end_);
     189           0 :     clearError();
     190           0 : }
     191             : 
     192             : bool
     193           0 : Decoder::skipCustomSection(ModuleEnvironment* env)
     194             : {
     195             :     uint32_t sectionStart, sectionSize;
     196           0 :     if (!startCustomSection(nullptr, 0, env, &sectionStart, &sectionSize))
     197           0 :         return false;
     198           0 :     if (sectionStart == NotStarted)
     199           0 :         return fail("expected custom section");
     200             : 
     201           0 :     finishCustomSection(sectionStart, sectionSize);
     202           0 :     return true;
     203             : }
     204             : 
     205             : bool
     206           0 : Decoder::startNameSubsection(NameType nameType, uint32_t* endOffset)
     207             : {
     208           0 :     const uint8_t* initialPosition = cur_;
     209             : 
     210             :     uint32_t nameTypeValue;
     211           0 :     if (!readVarU32(&nameTypeValue))
     212           0 :         return false;
     213             : 
     214           0 :     if (nameTypeValue != uint8_t(nameType)) {
     215           0 :         cur_ = initialPosition;
     216           0 :         *endOffset = NotStarted;
     217           0 :         return true;
     218             :     }
     219             : 
     220             :     uint32_t payloadLength;
     221           0 :     if (!readVarU32(&payloadLength) || payloadLength > bytesRemain())
     222           0 :         return false;
     223             : 
     224           0 :     *endOffset = (cur_ - beg_) + payloadLength;
     225           0 :     return true;
     226             : }
     227             : 
     228             : bool
     229           0 : Decoder::finishNameSubsection(uint32_t endOffset)
     230             : {
     231           0 :     MOZ_ASSERT(endOffset != NotStarted);
     232           0 :     return endOffset == uint32_t(cur_ - beg_);
     233             : }
     234             : 
     235             : // Misc helpers.
     236             : 
     237             : bool
     238           0 : wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals)
     239             : {
     240           0 :     uint32_t numLocalEntries = 0;
     241           0 :     ValType prev = ValType(TypeCode::Limit);
     242           0 :     for (ValType t : locals) {
     243           0 :         if (t != prev) {
     244           0 :             numLocalEntries++;
     245           0 :             prev = t;
     246             :         }
     247             :     }
     248             : 
     249           0 :     if (!e.writeVarU32(numLocalEntries))
     250           0 :         return false;
     251             : 
     252           0 :     if (numLocalEntries) {
     253           0 :         prev = locals[0];
     254           0 :         uint32_t count = 1;
     255           0 :         for (uint32_t i = 1; i < locals.length(); i++, count++) {
     256           0 :             if (prev != locals[i]) {
     257           0 :                 if (!e.writeVarU32(count))
     258           0 :                     return false;
     259           0 :                 if (!e.writeValType(prev))
     260           0 :                     return false;
     261           0 :                 prev = locals[i];
     262           0 :                 count = 0;
     263             :             }
     264             :         }
     265           0 :         if (!e.writeVarU32(count))
     266           0 :             return false;
     267           0 :         if (!e.writeValType(prev))
     268           0 :             return false;
     269             :     }
     270             : 
     271           0 :     return true;
     272             : }
     273             : 
     274             : static bool
     275           0 : DecodeValType(Decoder& d, ModuleKind kind, ValType* type)
     276             : {
     277             :     uint8_t unchecked;
     278           0 :     if (!d.readValType(&unchecked))
     279           0 :         return false;
     280             : 
     281           0 :     switch (unchecked) {
     282             :       case uint8_t(ValType::I32):
     283             :       case uint8_t(ValType::F32):
     284             :       case uint8_t(ValType::F64):
     285             :       case uint8_t(ValType::I64):
     286           0 :         *type = ValType(unchecked);
     287           0 :         return true;
     288             :       case uint8_t(ValType::I8x16):
     289             :       case uint8_t(ValType::I16x8):
     290             :       case uint8_t(ValType::I32x4):
     291             :       case uint8_t(ValType::F32x4):
     292             :       case uint8_t(ValType::B8x16):
     293             :       case uint8_t(ValType::B16x8):
     294             :       case uint8_t(ValType::B32x4):
     295           0 :         if (kind != ModuleKind::AsmJS)
     296           0 :             return d.fail("bad type");
     297           0 :         *type = ValType(unchecked);
     298           0 :         return true;
     299             :       default:
     300           0 :         break;
     301             :     }
     302           0 :     return d.fail("bad type");
     303             : }
     304             : 
     305             : bool
     306           0 : wasm::DecodeLocalEntries(Decoder& d, ModuleKind kind, ValTypeVector* locals)
     307             : {
     308             :     uint32_t numLocalEntries;
     309           0 :     if (!d.readVarU32(&numLocalEntries))
     310           0 :         return d.fail("failed to read number of local entries");
     311             : 
     312           0 :     for (uint32_t i = 0; i < numLocalEntries; i++) {
     313             :         uint32_t count;
     314           0 :         if (!d.readVarU32(&count))
     315           0 :             return d.fail("failed to read local entry count");
     316             : 
     317           0 :         if (MaxLocals - locals->length() < count)
     318           0 :             return d.fail("too many locals");
     319             : 
     320             :         ValType type;
     321           0 :         if (!DecodeValType(d, kind, &type))
     322           0 :             return false;
     323             : 
     324           0 :         if (!locals->appendN(type, count))
     325           0 :             return false;
     326             :     }
     327             : 
     328           0 :     return true;
     329             : }
     330             : 
     331             : // Function body validation.
     332             : 
     333           0 : struct ValidatingPolicy
     334             : {
     335             :     typedef Nothing Value;
     336             :     typedef Nothing ControlItem;
     337             : };
     338             : 
     339             : typedef OpIter<ValidatingPolicy> ValidatingOpIter;
     340             : 
     341             : static bool
     342           0 : DecodeFunctionBodyExprs(const ModuleEnvironment& env, const Sig& sig, const ValTypeVector& locals,
     343             :                         const uint8_t* bodyEnd, Decoder* d)
     344             : {
     345           0 :     ValidatingOpIter iter(env, *d);
     346             : 
     347           0 :     if (!iter.readFunctionStart(sig.ret()))
     348           0 :         return false;
     349             : 
     350             : #define CHECK(c) if (!(c)) return false; break
     351             : 
     352             :     while (true) {
     353           0 :         OpBytes op;
     354           0 :         if (!iter.readOp(&op))
     355           0 :             return false;
     356             : 
     357             :         Nothing nothing;
     358             : 
     359           0 :         switch (op.b0) {
     360             :           case uint16_t(Op::End): {
     361             :             LabelKind unusedKind;
     362             :             ExprType unusedType;
     363           0 :             if (!iter.readEnd(&unusedKind, &unusedType, &nothing))
     364           0 :                 return false;
     365           0 :             iter.popEnd();
     366           0 :             if (iter.controlStackEmpty())
     367           0 :                 return iter.readFunctionEnd(bodyEnd);
     368           0 :             break;
     369             :           }
     370             :           case uint16_t(Op::Nop):
     371           0 :             CHECK(iter.readNop());
     372             :           case uint16_t(Op::Drop):
     373           0 :             CHECK(iter.readDrop());
     374             :           case uint16_t(Op::Call): {
     375             :             uint32_t unusedIndex;
     376           0 :             ValidatingOpIter::ValueVector unusedArgs;
     377           0 :             CHECK(iter.readCall(&unusedIndex, &unusedArgs));
     378             :           }
     379             :           case uint16_t(Op::CallIndirect): {
     380             :             uint32_t unusedIndex;
     381           0 :             ValidatingOpIter::ValueVector unusedArgs;
     382           0 :             CHECK(iter.readCallIndirect(&unusedIndex, &nothing, &unusedArgs));
     383             :           }
     384             :           case uint16_t(Op::I32Const): {
     385             :             int32_t unused;
     386           0 :             CHECK(iter.readI32Const(&unused));
     387             :           }
     388             :           case uint16_t(Op::I64Const): {
     389             :             int64_t unused;
     390           0 :             CHECK(iter.readI64Const(&unused));
     391             :           }
     392             :           case uint16_t(Op::F32Const): {
     393             :             float unused;
     394           0 :             CHECK(iter.readF32Const(&unused));
     395             :           }
     396             :           case uint16_t(Op::F64Const): {
     397             :             double unused;
     398           0 :             CHECK(iter.readF64Const(&unused));
     399             :           }
     400             :           case uint16_t(Op::GetLocal): {
     401             :             uint32_t unused;
     402           0 :             CHECK(iter.readGetLocal(locals, &unused));
     403             :           }
     404             :           case uint16_t(Op::SetLocal): {
     405             :             uint32_t unused;
     406           0 :             CHECK(iter.readSetLocal(locals, &unused, &nothing));
     407             :           }
     408             :           case uint16_t(Op::TeeLocal): {
     409             :             uint32_t unused;
     410           0 :             CHECK(iter.readTeeLocal(locals, &unused, &nothing));
     411             :           }
     412             :           case uint16_t(Op::GetGlobal): {
     413             :             uint32_t unused;
     414           0 :             CHECK(iter.readGetGlobal(&unused));
     415             :           }
     416             :           case uint16_t(Op::SetGlobal): {
     417             :             uint32_t unused;
     418           0 :             CHECK(iter.readSetGlobal(&unused, &nothing));
     419             :           }
     420             :           case uint16_t(Op::Select): {
     421             :             StackType unused;
     422           0 :             CHECK(iter.readSelect(&unused, &nothing, &nothing, &nothing));
     423             :           }
     424             :           case uint16_t(Op::Block):
     425           0 :             CHECK(iter.readBlock());
     426             :           case uint16_t(Op::Loop):
     427           0 :             CHECK(iter.readLoop());
     428             :           case uint16_t(Op::If):
     429           0 :             CHECK(iter.readIf(&nothing));
     430             :           case uint16_t(Op::Else): {
     431             :             ExprType type;
     432           0 :             CHECK(iter.readElse(&type, &nothing));
     433             :           }
     434             :           case uint16_t(Op::I32Clz):
     435             :           case uint16_t(Op::I32Ctz):
     436             :           case uint16_t(Op::I32Popcnt):
     437           0 :             CHECK(iter.readUnary(ValType::I32, &nothing));
     438             :           case uint16_t(Op::I64Clz):
     439             :           case uint16_t(Op::I64Ctz):
     440             :           case uint16_t(Op::I64Popcnt):
     441           0 :             CHECK(iter.readUnary(ValType::I64, &nothing));
     442             :           case uint16_t(Op::F32Abs):
     443             :           case uint16_t(Op::F32Neg):
     444             :           case uint16_t(Op::F32Ceil):
     445             :           case uint16_t(Op::F32Floor):
     446             :           case uint16_t(Op::F32Sqrt):
     447             :           case uint16_t(Op::F32Trunc):
     448             :           case uint16_t(Op::F32Nearest):
     449           0 :             CHECK(iter.readUnary(ValType::F32, &nothing));
     450             :           case uint16_t(Op::F64Abs):
     451             :           case uint16_t(Op::F64Neg):
     452             :           case uint16_t(Op::F64Ceil):
     453             :           case uint16_t(Op::F64Floor):
     454             :           case uint16_t(Op::F64Sqrt):
     455             :           case uint16_t(Op::F64Trunc):
     456             :           case uint16_t(Op::F64Nearest):
     457           0 :             CHECK(iter.readUnary(ValType::F64, &nothing));
     458             :           case uint16_t(Op::I32Add):
     459             :           case uint16_t(Op::I32Sub):
     460             :           case uint16_t(Op::I32Mul):
     461             :           case uint16_t(Op::I32DivS):
     462             :           case uint16_t(Op::I32DivU):
     463             :           case uint16_t(Op::I32RemS):
     464             :           case uint16_t(Op::I32RemU):
     465             :           case uint16_t(Op::I32And):
     466             :           case uint16_t(Op::I32Or):
     467             :           case uint16_t(Op::I32Xor):
     468             :           case uint16_t(Op::I32Shl):
     469             :           case uint16_t(Op::I32ShrS):
     470             :           case uint16_t(Op::I32ShrU):
     471             :           case uint16_t(Op::I32Rotl):
     472             :           case uint16_t(Op::I32Rotr):
     473           0 :             CHECK(iter.readBinary(ValType::I32, &nothing, &nothing));
     474             :           case uint16_t(Op::I64Add):
     475             :           case uint16_t(Op::I64Sub):
     476             :           case uint16_t(Op::I64Mul):
     477             :           case uint16_t(Op::I64DivS):
     478             :           case uint16_t(Op::I64DivU):
     479             :           case uint16_t(Op::I64RemS):
     480             :           case uint16_t(Op::I64RemU):
     481             :           case uint16_t(Op::I64And):
     482             :           case uint16_t(Op::I64Or):
     483             :           case uint16_t(Op::I64Xor):
     484             :           case uint16_t(Op::I64Shl):
     485             :           case uint16_t(Op::I64ShrS):
     486             :           case uint16_t(Op::I64ShrU):
     487             :           case uint16_t(Op::I64Rotl):
     488             :           case uint16_t(Op::I64Rotr):
     489           0 :             CHECK(iter.readBinary(ValType::I64, &nothing, &nothing));
     490             :           case uint16_t(Op::F32Add):
     491             :           case uint16_t(Op::F32Sub):
     492             :           case uint16_t(Op::F32Mul):
     493             :           case uint16_t(Op::F32Div):
     494             :           case uint16_t(Op::F32Min):
     495             :           case uint16_t(Op::F32Max):
     496             :           case uint16_t(Op::F32CopySign):
     497           0 :             CHECK(iter.readBinary(ValType::F32, &nothing, &nothing));
     498             :           case uint16_t(Op::F64Add):
     499             :           case uint16_t(Op::F64Sub):
     500             :           case uint16_t(Op::F64Mul):
     501             :           case uint16_t(Op::F64Div):
     502             :           case uint16_t(Op::F64Min):
     503             :           case uint16_t(Op::F64Max):
     504             :           case uint16_t(Op::F64CopySign):
     505           0 :             CHECK(iter.readBinary(ValType::F64, &nothing, &nothing));
     506             :           case uint16_t(Op::I32Eq):
     507             :           case uint16_t(Op::I32Ne):
     508             :           case uint16_t(Op::I32LtS):
     509             :           case uint16_t(Op::I32LtU):
     510             :           case uint16_t(Op::I32LeS):
     511             :           case uint16_t(Op::I32LeU):
     512             :           case uint16_t(Op::I32GtS):
     513             :           case uint16_t(Op::I32GtU):
     514             :           case uint16_t(Op::I32GeS):
     515             :           case uint16_t(Op::I32GeU):
     516           0 :             CHECK(iter.readComparison(ValType::I32, &nothing, &nothing));
     517             :           case uint16_t(Op::I64Eq):
     518             :           case uint16_t(Op::I64Ne):
     519             :           case uint16_t(Op::I64LtS):
     520             :           case uint16_t(Op::I64LtU):
     521             :           case uint16_t(Op::I64LeS):
     522             :           case uint16_t(Op::I64LeU):
     523             :           case uint16_t(Op::I64GtS):
     524             :           case uint16_t(Op::I64GtU):
     525             :           case uint16_t(Op::I64GeS):
     526             :           case uint16_t(Op::I64GeU):
     527           0 :             CHECK(iter.readComparison(ValType::I64, &nothing, &nothing));
     528             :           case uint16_t(Op::F32Eq):
     529             :           case uint16_t(Op::F32Ne):
     530             :           case uint16_t(Op::F32Lt):
     531             :           case uint16_t(Op::F32Le):
     532             :           case uint16_t(Op::F32Gt):
     533             :           case uint16_t(Op::F32Ge):
     534           0 :             CHECK(iter.readComparison(ValType::F32, &nothing, &nothing));
     535             :           case uint16_t(Op::F64Eq):
     536             :           case uint16_t(Op::F64Ne):
     537             :           case uint16_t(Op::F64Lt):
     538             :           case uint16_t(Op::F64Le):
     539             :           case uint16_t(Op::F64Gt):
     540             :           case uint16_t(Op::F64Ge):
     541           0 :             CHECK(iter.readComparison(ValType::F64, &nothing, &nothing));
     542             :           case uint16_t(Op::I32Eqz):
     543           0 :             CHECK(iter.readConversion(ValType::I32, ValType::I32, &nothing));
     544             :           case uint16_t(Op::I64Eqz):
     545             :           case uint16_t(Op::I32WrapI64):
     546           0 :             CHECK(iter.readConversion(ValType::I64, ValType::I32, &nothing));
     547             :           case uint16_t(Op::I32TruncSF32):
     548             :           case uint16_t(Op::I32TruncUF32):
     549             :           case uint16_t(Op::I32ReinterpretF32):
     550           0 :             CHECK(iter.readConversion(ValType::F32, ValType::I32, &nothing));
     551             :           case uint16_t(Op::I32TruncSF64):
     552             :           case uint16_t(Op::I32TruncUF64):
     553           0 :             CHECK(iter.readConversion(ValType::F64, ValType::I32, &nothing));
     554             :           case uint16_t(Op::I64ExtendSI32):
     555             :           case uint16_t(Op::I64ExtendUI32):
     556           0 :             CHECK(iter.readConversion(ValType::I32, ValType::I64, &nothing));
     557             :           case uint16_t(Op::I64TruncSF32):
     558             :           case uint16_t(Op::I64TruncUF32):
     559           0 :             CHECK(iter.readConversion(ValType::F32, ValType::I64, &nothing));
     560             :           case uint16_t(Op::I64TruncSF64):
     561             :           case uint16_t(Op::I64TruncUF64):
     562             :           case uint16_t(Op::I64ReinterpretF64):
     563           0 :             CHECK(iter.readConversion(ValType::F64, ValType::I64, &nothing));
     564             :           case uint16_t(Op::F32ConvertSI32):
     565             :           case uint16_t(Op::F32ConvertUI32):
     566             :           case uint16_t(Op::F32ReinterpretI32):
     567           0 :             CHECK(iter.readConversion(ValType::I32, ValType::F32, &nothing));
     568             :           case uint16_t(Op::F32ConvertSI64):
     569             :           case uint16_t(Op::F32ConvertUI64):
     570           0 :             CHECK(iter.readConversion(ValType::I64, ValType::F32, &nothing));
     571             :           case uint16_t(Op::F32DemoteF64):
     572           0 :             CHECK(iter.readConversion(ValType::F64, ValType::F32, &nothing));
     573             :           case uint16_t(Op::F64ConvertSI32):
     574             :           case uint16_t(Op::F64ConvertUI32):
     575           0 :             CHECK(iter.readConversion(ValType::I32, ValType::F64, &nothing));
     576             :           case uint16_t(Op::F64ConvertSI64):
     577             :           case uint16_t(Op::F64ConvertUI64):
     578             :           case uint16_t(Op::F64ReinterpretI64):
     579           0 :             CHECK(iter.readConversion(ValType::I64, ValType::F64, &nothing));
     580             :           case uint16_t(Op::F64PromoteF32):
     581           0 :             CHECK(iter.readConversion(ValType::F32, ValType::F64, &nothing));
     582             :           case uint16_t(Op::I32Load8S):
     583             :           case uint16_t(Op::I32Load8U): {
     584           0 :             LinearMemoryAddress<Nothing> addr;
     585           0 :             CHECK(iter.readLoad(ValType::I32, 1, &addr));
     586             :           }
     587             :           case uint16_t(Op::I32Load16S):
     588             :           case uint16_t(Op::I32Load16U): {
     589           0 :             LinearMemoryAddress<Nothing> addr;
     590           0 :             CHECK(iter.readLoad(ValType::I32, 2, &addr));
     591             :           }
     592             :           case uint16_t(Op::I32Load): {
     593           0 :             LinearMemoryAddress<Nothing> addr;
     594           0 :             CHECK(iter.readLoad(ValType::I32, 4, &addr));
     595             :           }
     596             :           case uint16_t(Op::I64Load8S):
     597             :           case uint16_t(Op::I64Load8U): {
     598           0 :             LinearMemoryAddress<Nothing> addr;
     599           0 :             CHECK(iter.readLoad(ValType::I64, 1, &addr));
     600             :           }
     601             :           case uint16_t(Op::I64Load16S):
     602             :           case uint16_t(Op::I64Load16U): {
     603           0 :             LinearMemoryAddress<Nothing> addr;
     604           0 :             CHECK(iter.readLoad(ValType::I64, 2, &addr));
     605             :           }
     606             :           case uint16_t(Op::I64Load32S):
     607             :           case uint16_t(Op::I64Load32U): {
     608           0 :             LinearMemoryAddress<Nothing> addr;
     609           0 :             CHECK(iter.readLoad(ValType::I64, 4, &addr));
     610             :           }
     611             :           case uint16_t(Op::I64Load): {
     612           0 :             LinearMemoryAddress<Nothing> addr;
     613           0 :             CHECK(iter.readLoad(ValType::I64, 8, &addr));
     614             :           }
     615             :           case uint16_t(Op::F32Load): {
     616           0 :             LinearMemoryAddress<Nothing> addr;
     617           0 :             CHECK(iter.readLoad(ValType::F32, 4, &addr));
     618             :           }
     619             :           case uint16_t(Op::F64Load): {
     620           0 :             LinearMemoryAddress<Nothing> addr;
     621           0 :             CHECK(iter.readLoad(ValType::F64, 8, &addr));
     622             :           }
     623             :           case uint16_t(Op::I32Store8): {
     624           0 :             LinearMemoryAddress<Nothing> addr;
     625           0 :             CHECK(iter.readStore(ValType::I32, 1, &addr, &nothing));
     626             :           }
     627             :           case uint16_t(Op::I32Store16): {
     628           0 :             LinearMemoryAddress<Nothing> addr;
     629           0 :             CHECK(iter.readStore(ValType::I32, 2, &addr, &nothing));
     630             :           }
     631             :           case uint16_t(Op::I32Store): {
     632           0 :             LinearMemoryAddress<Nothing> addr;
     633           0 :             CHECK(iter.readStore(ValType::I32, 4, &addr, &nothing));
     634             :           }
     635             :           case uint16_t(Op::I64Store8): {
     636           0 :             LinearMemoryAddress<Nothing> addr;
     637           0 :             CHECK(iter.readStore(ValType::I64, 1, &addr, &nothing));
     638             :           }
     639             :           case uint16_t(Op::I64Store16): {
     640           0 :             LinearMemoryAddress<Nothing> addr;
     641           0 :             CHECK(iter.readStore(ValType::I64, 2, &addr, &nothing));
     642             :           }
     643             :           case uint16_t(Op::I64Store32): {
     644           0 :             LinearMemoryAddress<Nothing> addr;
     645           0 :             CHECK(iter.readStore(ValType::I64, 4, &addr, &nothing));
     646             :           }
     647             :           case uint16_t(Op::I64Store): {
     648           0 :             LinearMemoryAddress<Nothing> addr;
     649           0 :             CHECK(iter.readStore(ValType::I64, 8, &addr, &nothing));
     650             :           }
     651             :           case uint16_t(Op::F32Store): {
     652           0 :             LinearMemoryAddress<Nothing> addr;
     653           0 :             CHECK(iter.readStore(ValType::F32, 4, &addr, &nothing));
     654             :           }
     655             :           case uint16_t(Op::F64Store): {
     656           0 :             LinearMemoryAddress<Nothing> addr;
     657           0 :             CHECK(iter.readStore(ValType::F64, 8, &addr, &nothing));
     658             :           }
     659             :           case uint16_t(Op::GrowMemory):
     660           0 :             CHECK(iter.readGrowMemory(&nothing));
     661             :           case uint16_t(Op::CurrentMemory):
     662           0 :             CHECK(iter.readCurrentMemory());
     663             :           case uint16_t(Op::Br): {
     664             :             uint32_t unusedDepth;
     665             :             ExprType unusedType;
     666           0 :             CHECK(iter.readBr(&unusedDepth, &unusedType, &nothing));
     667             :           }
     668             :           case uint16_t(Op::BrIf): {
     669             :             uint32_t unusedDepth;
     670             :             ExprType unusedType;
     671           0 :             CHECK(iter.readBrIf(&unusedDepth, &unusedType, &nothing, &nothing));
     672             :           }
     673             :           case uint16_t(Op::BrTable): {
     674           0 :             Uint32Vector unusedDepths;
     675             :             uint32_t unusedDefault;
     676             :             ExprType unusedType;
     677           0 :             CHECK(iter.readBrTable(&unusedDepths, &unusedDefault, &unusedType, &nothing, &nothing));
     678             :           }
     679             :           case uint16_t(Op::Return):
     680           0 :             CHECK(iter.readReturn(&nothing));
     681             :           case uint16_t(Op::Unreachable):
     682           0 :             CHECK(iter.readUnreachable());
     683             :           default:
     684           0 :             return iter.unrecognizedOpcode(&op);
     685             :         }
     686           0 :     }
     687             : 
     688             :     MOZ_CRASH("unreachable");
     689             : 
     690             : #undef CHECK
     691             : }
     692             : 
     693             : bool
     694           0 : wasm::ValidateFunctionBody(const ModuleEnvironment& env, uint32_t funcIndex, uint32_t bodySize,
     695             :                            Decoder& d)
     696             : {
     697           0 :     const Sig& sig = *env.funcSigs[funcIndex];
     698             : 
     699           0 :     ValTypeVector locals;
     700           0 :     if (!locals.appendAll(sig.args()))
     701           0 :         return false;
     702             : 
     703           0 :     const uint8_t* bodyBegin = d.currentPosition();
     704             : 
     705           0 :     if (!DecodeLocalEntries(d, ModuleKind::Wasm, &locals))
     706           0 :         return false;
     707             : 
     708           0 :     if (!DecodeFunctionBodyExprs(env, sig, locals, bodyBegin + bodySize, &d))
     709           0 :         return false;
     710             : 
     711           0 :     return true;
     712             : }
     713             : 
     714             : // Section macros.
     715             : 
     716             : static bool
     717           0 : DecodePreamble(Decoder& d)
     718             : {
     719           0 :     if (d.bytesRemain() > MaxModuleBytes)
     720           0 :         return d.fail("module too big");
     721             : 
     722             :     uint32_t u32;
     723           0 :     if (!d.readFixedU32(&u32) || u32 != MagicNumber)
     724           0 :         return d.fail("failed to match magic number");
     725             : 
     726           0 :     if (!d.readFixedU32(&u32) || u32 != EncodingVersion) {
     727           0 :         return d.failf("binary version 0x%" PRIx32 " does not match expected version 0x%" PRIx32,
     728           0 :                        u32, EncodingVersion);
     729             :     }
     730             : 
     731           0 :     return true;
     732             : }
     733             : 
     734             : static bool
     735           0 : DecodeTypeSection(Decoder& d, ModuleEnvironment* env)
     736             : {
     737             :     uint32_t sectionStart, sectionSize;
     738           0 :     if (!d.startSection(SectionId::Type, env, &sectionStart, &sectionSize, "type"))
     739           0 :         return false;
     740           0 :     if (sectionStart == Decoder::NotStarted)
     741           0 :         return true;
     742             : 
     743             :     uint32_t numSigs;
     744           0 :     if (!d.readVarU32(&numSigs))
     745           0 :         return d.fail("expected number of signatures");
     746             : 
     747           0 :     if (numSigs > MaxTypes)
     748           0 :         return d.fail("too many signatures");
     749             : 
     750           0 :     if (!env->sigs.resize(numSigs))
     751           0 :         return false;
     752             : 
     753           0 :     for (uint32_t sigIndex = 0; sigIndex < numSigs; sigIndex++) {
     754             :         uint32_t form;
     755           0 :         if (!d.readVarU32(&form) || form != uint32_t(TypeCode::Func))
     756           0 :             return d.fail("expected function form");
     757             : 
     758             :         uint32_t numArgs;
     759           0 :         if (!d.readVarU32(&numArgs))
     760           0 :             return d.fail("bad number of function args");
     761             : 
     762           0 :         if (numArgs > MaxParams)
     763           0 :             return d.fail("too many arguments in signature");
     764             : 
     765           0 :         ValTypeVector args;
     766           0 :         if (!args.resize(numArgs))
     767           0 :             return false;
     768             : 
     769           0 :         for (uint32_t i = 0; i < numArgs; i++) {
     770           0 :             if (!DecodeValType(d, ModuleKind::Wasm, &args[i]))
     771           0 :                 return false;
     772             :         }
     773             : 
     774             :         uint32_t numRets;
     775           0 :         if (!d.readVarU32(&numRets))
     776           0 :             return d.fail("bad number of function returns");
     777             : 
     778           0 :         if (numRets > 1)
     779           0 :             return d.fail("too many returns in signature");
     780             : 
     781           0 :         ExprType result = ExprType::Void;
     782             : 
     783           0 :         if (numRets == 1) {
     784             :             ValType type;
     785           0 :             if (!DecodeValType(d, ModuleKind::Wasm, &type))
     786           0 :                 return false;
     787             : 
     788           0 :             result = ToExprType(type);
     789             :         }
     790             : 
     791           0 :         env->sigs[sigIndex] = Sig(Move(args), result);
     792             :     }
     793             : 
     794           0 :     if (!d.finishSection(sectionStart, sectionSize, "type"))
     795           0 :         return false;
     796             : 
     797           0 :     return true;
     798             : }
     799             : 
     800             : static UniqueChars
     801           0 : DecodeName(Decoder& d)
     802             : {
     803             :     uint32_t numBytes;
     804           0 :     if (!d.readVarU32(&numBytes))
     805           0 :         return nullptr;
     806             : 
     807           0 :     if (numBytes > MaxStringBytes)
     808           0 :         return nullptr;
     809             : 
     810             :     const uint8_t* bytes;
     811           0 :     if (!d.readBytes(numBytes, &bytes))
     812           0 :         return nullptr;
     813             : 
     814           0 :     UniqueChars name(js_pod_malloc<char>(numBytes + 1));
     815           0 :     if (!name)
     816           0 :         return nullptr;
     817             : 
     818           0 :     memcpy(name.get(), bytes, numBytes);
     819           0 :     name[numBytes] = '\0';
     820             : 
     821           0 :     return name;
     822             : }
     823             : 
     824             : static bool
     825           0 : DecodeSignatureIndex(Decoder& d, const SigWithIdVector& sigs, uint32_t* sigIndex)
     826             : {
     827           0 :     if (!d.readVarU32(sigIndex))
     828           0 :         return d.fail("expected signature index");
     829             : 
     830           0 :     if (*sigIndex >= sigs.length())
     831           0 :         return d.fail("signature index out of range");
     832             : 
     833           0 :     return true;
     834             : }
     835             : 
     836             : static bool
     837           0 : DecodeLimits(Decoder& d, Limits* limits)
     838             : {
     839             :     uint32_t flags;
     840           0 :     if (!d.readVarU32(&flags))
     841           0 :         return d.fail("expected flags");
     842             : 
     843           0 :     if (flags & ~uint32_t(0x1))
     844           0 :         return d.failf("unexpected bits set in flags: %" PRIu32, (flags & ~uint32_t(0x1)));
     845             : 
     846           0 :     if (!d.readVarU32(&limits->initial))
     847           0 :         return d.fail("expected initial length");
     848             : 
     849           0 :     if (flags & 0x1) {
     850             :         uint32_t maximum;
     851           0 :         if (!d.readVarU32(&maximum))
     852           0 :             return d.fail("expected maximum length");
     853             : 
     854           0 :         if (limits->initial > maximum) {
     855           0 :             return d.failf("memory size minimum must not be greater than maximum; "
     856             :                            "maximum length %" PRIu32 " is less than initial length %" PRIu32,
     857           0 :                            maximum, limits->initial);
     858             :         }
     859             : 
     860           0 :         limits->maximum.emplace(maximum);
     861             :     }
     862             : 
     863           0 :     return true;
     864             : }
     865             : 
     866             : static bool
     867           0 : DecodeTableLimits(Decoder& d, TableDescVector* tables)
     868             : {
     869             :     uint32_t elementType;
     870           0 :     if (!d.readVarU32(&elementType))
     871           0 :         return d.fail("expected table element type");
     872             : 
     873           0 :     if (elementType != uint32_t(TypeCode::AnyFunc))
     874           0 :         return d.fail("expected 'anyfunc' element type");
     875             : 
     876           0 :     Limits limits;
     877           0 :     if (!DecodeLimits(d, &limits))
     878           0 :         return false;
     879             : 
     880           0 :     if (limits.initial > MaxTableInitialLength)
     881           0 :         return d.fail("too many table elements");
     882             : 
     883           0 :     if (tables->length())
     884           0 :         return d.fail("already have default table");
     885             : 
     886           0 :     return tables->emplaceBack(TableKind::AnyFunction, limits);
     887             : }
     888             : 
     889             : static bool
     890           0 : GlobalIsJSCompatible(Decoder& d, ValType type, bool isMutable)
     891             : {
     892           0 :     switch (type) {
     893             :       case ValType::I32:
     894             :       case ValType::F32:
     895             :       case ValType::F64:
     896           0 :         break;
     897             :       case ValType::I64:
     898           0 :         if (!jit::JitOptions.wasmTestMode)
     899           0 :             return d.fail("can't import/export an Int64 global to JS");
     900           0 :         break;
     901             :       default:
     902           0 :         return d.fail("unexpected variable type in global import/export");
     903             :     }
     904             : 
     905           0 :     if (isMutable)
     906           0 :         return d.fail("can't import/export mutable globals in the MVP");
     907             : 
     908           0 :     return true;
     909             : }
     910             : 
     911             : static bool
     912           0 : DecodeGlobalType(Decoder& d, ValType* type, bool* isMutable)
     913             : {
     914           0 :     if (!DecodeValType(d, ModuleKind::Wasm, type))
     915           0 :         return false;
     916             : 
     917             :     uint32_t flags;
     918           0 :     if (!d.readVarU32(&flags))
     919           0 :         return d.fail("expected global flags");
     920             : 
     921           0 :     if (flags & ~uint32_t(GlobalTypeImmediate::AllowedMask))
     922           0 :         return d.fail("unexpected bits set in global flags");
     923             : 
     924           0 :     *isMutable = flags & uint32_t(GlobalTypeImmediate::IsMutable);
     925           0 :     return true;
     926             : }
     927             : 
     928             : static bool
     929           0 : DecodeMemoryLimits(Decoder& d, ModuleEnvironment* env)
     930             : {
     931           0 :     if (env->usesMemory())
     932           0 :         return d.fail("already have default memory");
     933             : 
     934           0 :     Limits memory;
     935           0 :     if (!DecodeLimits(d, &memory))
     936           0 :         return false;
     937             : 
     938           0 :     if (memory.initial > MaxMemoryInitialPages)
     939           0 :         return d.fail("initial memory size too big");
     940             : 
     941           0 :     CheckedInt<uint32_t> initialBytes = memory.initial;
     942           0 :     initialBytes *= PageSize;
     943           0 :     MOZ_ASSERT(initialBytes.isValid());
     944           0 :     memory.initial = initialBytes.value();
     945             : 
     946           0 :     if (memory.maximum) {
     947           0 :         if (*memory.maximum > MaxMemoryMaximumPages)
     948           0 :             return d.fail("maximum memory size too big");
     949             : 
     950           0 :         CheckedInt<uint32_t> maximumBytes = *memory.maximum;
     951           0 :         maximumBytes *= PageSize;
     952             : 
     953             :         // Clamp the maximum memory value to UINT32_MAX; it's not semantically
     954             :         // visible since growing will fail for values greater than INT32_MAX.
     955           0 :         memory.maximum = Some(maximumBytes.isValid() ? maximumBytes.value() : UINT32_MAX);
     956             :     }
     957             : 
     958           0 :     env->memoryUsage = MemoryUsage::Unshared;
     959           0 :     env->minMemoryLength = memory.initial;
     960           0 :     env->maxMemoryLength = memory.maximum;
     961           0 :     return true;
     962             : }
     963             : 
     964             : static bool
     965           0 : DecodeImport(Decoder& d, ModuleEnvironment* env)
     966             : {
     967           0 :     UniqueChars moduleName = DecodeName(d);
     968           0 :     if (!moduleName)
     969           0 :         return d.fail("expected valid import module name");
     970             : 
     971           0 :     UniqueChars funcName = DecodeName(d);
     972           0 :     if (!funcName)
     973           0 :         return d.fail("expected valid import func name");
     974             : 
     975             :     uint32_t rawImportKind;
     976           0 :     if (!d.readVarU32(&rawImportKind))
     977           0 :         return d.fail("failed to read import kind");
     978             : 
     979           0 :     DefinitionKind importKind = DefinitionKind(rawImportKind);
     980             : 
     981           0 :     switch (importKind) {
     982             :       case DefinitionKind::Function: {
     983             :         uint32_t sigIndex;
     984           0 :         if (!DecodeSignatureIndex(d, env->sigs, &sigIndex))
     985           0 :             return false;
     986           0 :         if (!env->funcSigs.append(&env->sigs[sigIndex]))
     987           0 :             return false;
     988           0 :         if (env->funcSigs.length() > MaxFuncs)
     989           0 :             return d.fail("too many functions");
     990           0 :         break;
     991             :       }
     992             :       case DefinitionKind::Table: {
     993           0 :         if (!DecodeTableLimits(d, &env->tables))
     994           0 :             return false;
     995           0 :         env->tables.back().external = true;
     996           0 :         break;
     997             :       }
     998             :       case DefinitionKind::Memory: {
     999           0 :         if (!DecodeMemoryLimits(d, env))
    1000           0 :             return false;
    1001           0 :         break;
    1002             :       }
    1003             :       case DefinitionKind::Global: {
    1004             :         ValType type;
    1005             :         bool isMutable;
    1006           0 :         if (!DecodeGlobalType(d, &type, &isMutable))
    1007           0 :             return false;
    1008           0 :         if (!GlobalIsJSCompatible(d, type, isMutable))
    1009           0 :             return false;
    1010           0 :         if (!env->globals.append(GlobalDesc(type, isMutable, env->globals.length())))
    1011           0 :             return false;
    1012           0 :         if (env->globals.length() > MaxGlobals)
    1013           0 :             return d.fail("too many globals");
    1014           0 :         break;
    1015             :       }
    1016             :       default:
    1017           0 :         return d.fail("unsupported import kind");
    1018             :     }
    1019             : 
    1020           0 :     return env->imports.emplaceBack(Move(moduleName), Move(funcName), importKind);
    1021             : }
    1022             : 
    1023             : static bool
    1024           0 : DecodeImportSection(Decoder& d, ModuleEnvironment* env)
    1025             : {
    1026             :     uint32_t sectionStart, sectionSize;
    1027           0 :     if (!d.startSection(SectionId::Import, env, &sectionStart, &sectionSize, "import"))
    1028           0 :         return false;
    1029           0 :     if (sectionStart == Decoder::NotStarted)
    1030           0 :         return true;
    1031             : 
    1032             :     uint32_t numImports;
    1033           0 :     if (!d.readVarU32(&numImports))
    1034           0 :         return d.fail("failed to read number of imports");
    1035             : 
    1036           0 :     if (numImports > MaxImports)
    1037           0 :         return d.fail("too many imports");
    1038             : 
    1039           0 :     for (uint32_t i = 0; i < numImports; i++) {
    1040           0 :         if (!DecodeImport(d, env))
    1041           0 :             return false;
    1042             :     }
    1043             : 
    1044           0 :     if (!d.finishSection(sectionStart, sectionSize, "import"))
    1045           0 :         return false;
    1046             : 
    1047             :     // The global data offsets will be filled in by ModuleGenerator::init.
    1048           0 :     if (!env->funcImportGlobalDataOffsets.resize(env->funcSigs.length()))
    1049           0 :         return false;
    1050             : 
    1051           0 :     return true;
    1052             : }
    1053             : 
    1054             : static bool
    1055           0 : DecodeFunctionSection(Decoder& d, ModuleEnvironment* env)
    1056             : {
    1057             :     uint32_t sectionStart, sectionSize;
    1058           0 :     if (!d.startSection(SectionId::Function, env, &sectionStart, &sectionSize, "function"))
    1059           0 :         return false;
    1060           0 :     if (sectionStart == Decoder::NotStarted)
    1061           0 :         return true;
    1062             : 
    1063             :     uint32_t numDefs;
    1064           0 :     if (!d.readVarU32(&numDefs))
    1065           0 :         return d.fail("expected number of function definitions");
    1066             : 
    1067           0 :     CheckedInt<uint32_t> numFuncs = env->funcSigs.length();
    1068           0 :     numFuncs += numDefs;
    1069           0 :     if (!numFuncs.isValid() || numFuncs.value() > MaxFuncs)
    1070           0 :         return d.fail("too many functions");
    1071             : 
    1072           0 :     if (!env->funcSigs.reserve(numFuncs.value()))
    1073           0 :         return false;
    1074             : 
    1075           0 :     for (uint32_t i = 0; i < numDefs; i++) {
    1076             :         uint32_t sigIndex;
    1077           0 :         if (!DecodeSignatureIndex(d, env->sigs, &sigIndex))
    1078           0 :             return false;
    1079           0 :         env->funcSigs.infallibleAppend(&env->sigs[sigIndex]);
    1080             :     }
    1081             : 
    1082           0 :     if (!d.finishSection(sectionStart, sectionSize, "function"))
    1083           0 :         return false;
    1084             : 
    1085           0 :     return true;
    1086             : }
    1087             : 
    1088             : static bool
    1089           0 : DecodeTableSection(Decoder& d, ModuleEnvironment* env)
    1090             : {
    1091             :     uint32_t sectionStart, sectionSize;
    1092           0 :     if (!d.startSection(SectionId::Table, env, &sectionStart, &sectionSize, "table"))
    1093           0 :         return false;
    1094           0 :     if (sectionStart == Decoder::NotStarted)
    1095           0 :         return true;
    1096             : 
    1097             :     uint32_t numTables;
    1098           0 :     if (!d.readVarU32(&numTables))
    1099           0 :         return d.fail("failed to read number of tables");
    1100             : 
    1101           0 :     if (numTables > 1)
    1102           0 :         return d.fail("the number of tables must be at most one");
    1103             : 
    1104           0 :     for (uint32_t i = 0; i < numTables; ++i) {
    1105           0 :         if (!DecodeTableLimits(d, &env->tables))
    1106           0 :             return false;
    1107             :     }
    1108             : 
    1109           0 :     if (!d.finishSection(sectionStart, sectionSize, "table"))
    1110           0 :         return false;
    1111             : 
    1112           0 :     return true;
    1113             : }
    1114             : 
    1115             : static bool
    1116           0 : DecodeMemorySection(Decoder& d, ModuleEnvironment* env)
    1117             : {
    1118             :     uint32_t sectionStart, sectionSize;
    1119           0 :     if (!d.startSection(SectionId::Memory, env, &sectionStart, &sectionSize, "memory"))
    1120           0 :         return false;
    1121           0 :     if (sectionStart == Decoder::NotStarted)
    1122           0 :         return true;
    1123             : 
    1124             :     uint32_t numMemories;
    1125           0 :     if (!d.readVarU32(&numMemories))
    1126           0 :         return d.fail("failed to read number of memories");
    1127             : 
    1128           0 :     if (numMemories > 1)
    1129           0 :         return d.fail("the number of memories must be at most one");
    1130             : 
    1131           0 :     for (uint32_t i = 0; i < numMemories; ++i) {
    1132           0 :         if (!DecodeMemoryLimits(d, env))
    1133           0 :             return false;
    1134             :     }
    1135             : 
    1136           0 :     if (!d.finishSection(sectionStart, sectionSize, "memory"))
    1137           0 :         return false;
    1138             : 
    1139           0 :     return true;
    1140             : }
    1141             : 
    1142             : static bool
    1143           0 : DecodeInitializerExpression(Decoder& d, const GlobalDescVector& globals, ValType expected,
    1144             :                             InitExpr* init)
    1145             : {
    1146           0 :     OpBytes op;
    1147           0 :     if (!d.readOp(&op))
    1148           0 :         return d.fail("failed to read initializer type");
    1149             : 
    1150           0 :     switch (op.b0) {
    1151             :       case uint16_t(Op::I32Const): {
    1152             :         int32_t i32;
    1153           0 :         if (!d.readVarS32(&i32))
    1154           0 :             return d.fail("failed to read initializer i32 expression");
    1155           0 :         *init = InitExpr(Val(uint32_t(i32)));
    1156           0 :         break;
    1157             :       }
    1158             :       case uint16_t(Op::I64Const): {
    1159             :         int64_t i64;
    1160           0 :         if (!d.readVarS64(&i64))
    1161           0 :             return d.fail("failed to read initializer i64 expression");
    1162           0 :         *init = InitExpr(Val(uint64_t(i64)));
    1163           0 :         break;
    1164             :       }
    1165             :       case uint16_t(Op::F32Const): {
    1166             :         float f32;
    1167           0 :         if (!d.readFixedF32(&f32))
    1168           0 :             return d.fail("failed to read initializer f32 expression");
    1169           0 :         *init = InitExpr(Val(f32));
    1170           0 :         break;
    1171             :       }
    1172             :       case uint16_t(Op::F64Const): {
    1173             :         double f64;
    1174           0 :         if (!d.readFixedF64(&f64))
    1175           0 :             return d.fail("failed to read initializer f64 expression");
    1176           0 :         *init = InitExpr(Val(f64));
    1177           0 :         break;
    1178             :       }
    1179             :       case uint16_t(Op::GetGlobal): {
    1180             :         uint32_t i;
    1181           0 :         if (!d.readVarU32(&i))
    1182           0 :             return d.fail("failed to read get_global index in initializer expression");
    1183           0 :         if (i >= globals.length())
    1184           0 :             return d.fail("global index out of range in initializer expression");
    1185           0 :         if (!globals[i].isImport() || globals[i].isMutable())
    1186           0 :             return d.fail("initializer expression must reference a global immutable import");
    1187           0 :         *init = InitExpr(i, globals[i].type());
    1188           0 :         break;
    1189             :       }
    1190             :       default: {
    1191           0 :         return d.fail("unexpected initializer expression");
    1192             :       }
    1193             :     }
    1194             : 
    1195           0 :     if (expected != init->type())
    1196           0 :         return d.fail("type mismatch: initializer type and expected type don't match");
    1197             : 
    1198           0 :     OpBytes end;
    1199           0 :     if (!d.readOp(&end) || end.b0 != uint16_t(Op::End))
    1200           0 :         return d.fail("failed to read end of initializer expression");
    1201             : 
    1202           0 :     return true;
    1203             : }
    1204             : 
    1205             : static bool
    1206           0 : DecodeGlobalSection(Decoder& d, ModuleEnvironment* env)
    1207             : {
    1208             :     uint32_t sectionStart, sectionSize;
    1209           0 :     if (!d.startSection(SectionId::Global, env, &sectionStart, &sectionSize, "global"))
    1210           0 :         return false;
    1211           0 :     if (sectionStart == Decoder::NotStarted)
    1212           0 :         return true;
    1213             : 
    1214             :     uint32_t numDefs;
    1215           0 :     if (!d.readVarU32(&numDefs))
    1216           0 :         return d.fail("expected number of globals");
    1217             : 
    1218           0 :     CheckedInt<uint32_t> numGlobals = env->globals.length();
    1219           0 :     numGlobals += numDefs;
    1220           0 :     if (!numGlobals.isValid() || numGlobals.value() > MaxGlobals)
    1221           0 :         return d.fail("too many globals");
    1222             : 
    1223           0 :     if (!env->globals.reserve(numGlobals.value()))
    1224           0 :         return false;
    1225             : 
    1226           0 :     for (uint32_t i = 0; i < numDefs; i++) {
    1227             :         ValType type;
    1228             :         bool isMutable;
    1229           0 :         if (!DecodeGlobalType(d, &type, &isMutable))
    1230           0 :             return false;
    1231             : 
    1232           0 :         InitExpr initializer;
    1233           0 :         if (!DecodeInitializerExpression(d, env->globals, type, &initializer))
    1234           0 :             return false;
    1235             : 
    1236           0 :         env->globals.infallibleAppend(GlobalDesc(initializer, isMutable));
    1237             :     }
    1238             : 
    1239           0 :     if (!d.finishSection(sectionStart, sectionSize, "global"))
    1240           0 :         return false;
    1241             : 
    1242           0 :     return true;
    1243             : }
    1244             : 
    1245             : typedef HashSet<const char*, CStringHasher, SystemAllocPolicy> CStringSet;
    1246             : 
    1247             : static UniqueChars
    1248           0 : DecodeExportName(Decoder& d, CStringSet* dupSet)
    1249             : {
    1250           0 :     UniqueChars exportName = DecodeName(d);
    1251           0 :     if (!exportName) {
    1252           0 :         d.fail("expected valid export name");
    1253           0 :         return nullptr;
    1254             :     }
    1255             : 
    1256           0 :     CStringSet::AddPtr p = dupSet->lookupForAdd(exportName.get());
    1257           0 :     if (p) {
    1258           0 :         d.fail("duplicate export");
    1259           0 :         return nullptr;
    1260             :     }
    1261             : 
    1262           0 :     if (!dupSet->add(p, exportName.get()))
    1263           0 :         return nullptr;
    1264             : 
    1265           0 :     return Move(exportName);
    1266             : }
    1267             : 
    1268             : static bool
    1269           0 : DecodeExport(Decoder& d, ModuleEnvironment* env, CStringSet* dupSet)
    1270             : {
    1271           0 :     UniqueChars fieldName = DecodeExportName(d, dupSet);
    1272           0 :     if (!fieldName)
    1273           0 :         return false;
    1274             : 
    1275             :     uint32_t exportKind;
    1276           0 :     if (!d.readVarU32(&exportKind))
    1277           0 :         return d.fail("failed to read export kind");
    1278             : 
    1279           0 :     switch (DefinitionKind(exportKind)) {
    1280             :       case DefinitionKind::Function: {
    1281             :         uint32_t funcIndex;
    1282           0 :         if (!d.readVarU32(&funcIndex))
    1283           0 :             return d.fail("expected function index");
    1284             : 
    1285           0 :         if (funcIndex >= env->numFuncs())
    1286           0 :             return d.fail("exported function index out of bounds");
    1287             : 
    1288           0 :         return env->exports.emplaceBack(Move(fieldName), funcIndex, DefinitionKind::Function);
    1289             :       }
    1290             :       case DefinitionKind::Table: {
    1291             :         uint32_t tableIndex;
    1292           0 :         if (!d.readVarU32(&tableIndex))
    1293           0 :             return d.fail("expected table index");
    1294             : 
    1295           0 :         if (tableIndex >= env->tables.length())
    1296           0 :             return d.fail("exported table index out of bounds");
    1297             : 
    1298           0 :         MOZ_ASSERT(env->tables.length() == 1);
    1299           0 :         env->tables[0].external = true;
    1300             : 
    1301           0 :         return env->exports.emplaceBack(Move(fieldName), DefinitionKind::Table);
    1302             :       }
    1303             :       case DefinitionKind::Memory: {
    1304             :         uint32_t memoryIndex;
    1305           0 :         if (!d.readVarU32(&memoryIndex))
    1306           0 :             return d.fail("expected memory index");
    1307             : 
    1308           0 :         if (memoryIndex > 0 || !env->usesMemory())
    1309           0 :             return d.fail("exported memory index out of bounds");
    1310             : 
    1311           0 :         return env->exports.emplaceBack(Move(fieldName), DefinitionKind::Memory);
    1312             :       }
    1313             :       case DefinitionKind::Global: {
    1314             :         uint32_t globalIndex;
    1315           0 :         if (!d.readVarU32(&globalIndex))
    1316           0 :             return d.fail("expected global index");
    1317             : 
    1318           0 :         if (globalIndex >= env->globals.length())
    1319           0 :             return d.fail("exported global index out of bounds");
    1320             : 
    1321           0 :         const GlobalDesc& global = env->globals[globalIndex];
    1322           0 :         if (!GlobalIsJSCompatible(d, global.type(), global.isMutable()))
    1323           0 :             return false;
    1324             : 
    1325           0 :         return env->exports.emplaceBack(Move(fieldName), globalIndex, DefinitionKind::Global);
    1326             :       }
    1327             :       default:
    1328           0 :         return d.fail("unexpected export kind");
    1329             :     }
    1330             : 
    1331             :     MOZ_CRASH("unreachable");
    1332             : }
    1333             : 
    1334             : static bool
    1335           0 : DecodeExportSection(Decoder& d, ModuleEnvironment* env)
    1336             : {
    1337             :     uint32_t sectionStart, sectionSize;
    1338           0 :     if (!d.startSection(SectionId::Export, env, &sectionStart, &sectionSize, "export"))
    1339           0 :         return false;
    1340           0 :     if (sectionStart == Decoder::NotStarted)
    1341           0 :         return true;
    1342             : 
    1343           0 :     CStringSet dupSet;
    1344           0 :     if (!dupSet.init())
    1345           0 :         return false;
    1346             : 
    1347             :     uint32_t numExports;
    1348           0 :     if (!d.readVarU32(&numExports))
    1349           0 :         return d.fail("failed to read number of exports");
    1350             : 
    1351           0 :     if (numExports > MaxExports)
    1352           0 :         return d.fail("too many exports");
    1353             : 
    1354           0 :     for (uint32_t i = 0; i < numExports; i++) {
    1355           0 :         if (!DecodeExport(d, env, &dupSet))
    1356           0 :             return false;
    1357             :     }
    1358             : 
    1359           0 :     if (!d.finishSection(sectionStart, sectionSize, "export"))
    1360           0 :         return false;
    1361             : 
    1362           0 :     return true;
    1363             : }
    1364             : 
    1365             : static bool
    1366           0 : DecodeStartSection(Decoder& d, ModuleEnvironment* env)
    1367             : {
    1368             :     uint32_t sectionStart, sectionSize;
    1369           0 :     if (!d.startSection(SectionId::Start, env, &sectionStart, &sectionSize, "start"))
    1370           0 :         return false;
    1371           0 :     if (sectionStart == Decoder::NotStarted)
    1372           0 :         return true;
    1373             : 
    1374             :     uint32_t funcIndex;
    1375           0 :     if (!d.readVarU32(&funcIndex))
    1376           0 :         return d.fail("failed to read start func index");
    1377             : 
    1378           0 :     if (funcIndex >= env->numFuncs())
    1379           0 :         return d.fail("unknown start function");
    1380             : 
    1381           0 :     const Sig& sig = *env->funcSigs[funcIndex];
    1382           0 :     if (!IsVoid(sig.ret()))
    1383           0 :         return d.fail("start function must not return anything");
    1384             : 
    1385           0 :     if (sig.args().length())
    1386           0 :         return d.fail("start function must be nullary");
    1387             : 
    1388           0 :     env->startFuncIndex = Some(funcIndex);
    1389             : 
    1390           0 :     if (!d.finishSection(sectionStart, sectionSize, "start"))
    1391           0 :         return false;
    1392             : 
    1393           0 :     return true;
    1394             : }
    1395             : 
    1396             : static bool
    1397           0 : DecodeElemSection(Decoder& d, ModuleEnvironment* env)
    1398             : {
    1399             :     uint32_t sectionStart, sectionSize;
    1400           0 :     if (!d.startSection(SectionId::Elem, env, &sectionStart, &sectionSize, "elem"))
    1401           0 :         return false;
    1402           0 :     if (sectionStart == Decoder::NotStarted)
    1403           0 :         return true;
    1404             : 
    1405             :     uint32_t numSegments;
    1406           0 :     if (!d.readVarU32(&numSegments))
    1407           0 :         return d.fail("failed to read number of elem segments");
    1408             : 
    1409           0 :     if (numSegments > MaxElemSegments)
    1410           0 :         return d.fail("too many elem segments");
    1411             : 
    1412           0 :     for (uint32_t i = 0; i < numSegments; i++) {
    1413             :         uint32_t tableIndex;
    1414           0 :         if (!d.readVarU32(&tableIndex))
    1415           0 :             return d.fail("expected table index");
    1416             : 
    1417           0 :         MOZ_ASSERT(env->tables.length() <= 1);
    1418           0 :         if (tableIndex >= env->tables.length())
    1419           0 :             return d.fail("table index out of range");
    1420             : 
    1421           0 :         InitExpr offset;
    1422           0 :         if (!DecodeInitializerExpression(d, env->globals, ValType::I32, &offset))
    1423           0 :             return false;
    1424             : 
    1425             :         uint32_t numElems;
    1426           0 :         if (!d.readVarU32(&numElems))
    1427           0 :             return d.fail("expected segment size");
    1428             : 
    1429           0 :         if (numElems > MaxTableInitialLength)
    1430           0 :             return d.fail("too many table elements");
    1431             : 
    1432           0 :         Uint32Vector elemFuncIndices;
    1433           0 :         if (!elemFuncIndices.resize(numElems))
    1434           0 :             return false;
    1435             : 
    1436           0 :         for (uint32_t i = 0; i < numElems; i++) {
    1437           0 :             if (!d.readVarU32(&elemFuncIndices[i]))
    1438           0 :                 return d.fail("failed to read element function index");
    1439           0 :             if (elemFuncIndices[i] >= env->numFuncs())
    1440           0 :                 return d.fail("table element out of range");
    1441             :         }
    1442             : 
    1443           0 :         if (!env->elemSegments.emplaceBack(0, offset, Move(elemFuncIndices)))
    1444           0 :             return false;
    1445             : 
    1446           0 :         env->tables[env->elemSegments.back().tableIndex].external = true;
    1447             :     }
    1448             : 
    1449           0 :     if (!d.finishSection(sectionStart, sectionSize, "elem"))
    1450           0 :         return false;
    1451             : 
    1452           0 :     return true;
    1453             : }
    1454             : 
    1455             : bool
    1456           0 : wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env)
    1457             : {
    1458           0 :     if (!DecodePreamble(d))
    1459           0 :         return false;
    1460             : 
    1461           0 :     if (!DecodeTypeSection(d, env))
    1462           0 :         return false;
    1463             : 
    1464           0 :     if (!DecodeImportSection(d, env))
    1465           0 :         return false;
    1466             : 
    1467           0 :     if (!DecodeFunctionSection(d, env))
    1468           0 :         return false;
    1469             : 
    1470           0 :     if (!DecodeTableSection(d, env))
    1471           0 :         return false;
    1472             : 
    1473           0 :     if (!DecodeMemorySection(d, env))
    1474           0 :         return false;
    1475             : 
    1476           0 :     if (!DecodeGlobalSection(d, env))
    1477           0 :         return false;
    1478             : 
    1479           0 :     if (!DecodeExportSection(d, env))
    1480           0 :         return false;
    1481             : 
    1482           0 :     if (!DecodeStartSection(d, env))
    1483           0 :         return false;
    1484             : 
    1485           0 :     if (!DecodeElemSection(d, env))
    1486           0 :         return false;
    1487             : 
    1488           0 :     return true;
    1489             : }
    1490             : 
    1491             : static bool
    1492           0 : DecodeFunctionBody(Decoder& d, const ModuleEnvironment& env, uint32_t funcIndex)
    1493             : {
    1494             :     uint32_t bodySize;
    1495           0 :     if (!d.readVarU32(&bodySize))
    1496           0 :         return d.fail("expected number of function body bytes");
    1497             : 
    1498           0 :     if (bodySize > MaxFunctionBytes)
    1499           0 :         return d.fail("function body too big");
    1500             : 
    1501           0 :     if (d.bytesRemain() < bodySize)
    1502           0 :         return d.fail("function body length too big");
    1503             : 
    1504           0 :     if (!ValidateFunctionBody(env, funcIndex, bodySize, d))
    1505           0 :         return false;
    1506             : 
    1507           0 :     return true;
    1508             : }
    1509             : 
    1510             : static bool
    1511           0 : DecodeCodeSection(Decoder& d, ModuleEnvironment* env)
    1512             : {
    1513             :     uint32_t sectionStart, sectionSize;
    1514           0 :     if (!d.startSection(SectionId::Code, env, &sectionStart, &sectionSize, "code"))
    1515           0 :         return false;
    1516             : 
    1517           0 :     if (sectionStart == Decoder::NotStarted) {
    1518           0 :         if (env->numFuncDefs() != 0)
    1519           0 :             return d.fail("expected function bodies");
    1520           0 :         return true;
    1521             :     }
    1522             : 
    1523             :     uint32_t numFuncDefs;
    1524           0 :     if (!d.readVarU32(&numFuncDefs))
    1525           0 :         return d.fail("expected function body count");
    1526             : 
    1527           0 :     if (numFuncDefs != env->numFuncDefs())
    1528           0 :         return d.fail("function body count does not match function signature count");
    1529             : 
    1530           0 :     for (uint32_t funcDefIndex = 0; funcDefIndex < numFuncDefs; funcDefIndex++) {
    1531           0 :         if (!DecodeFunctionBody(d, *env, env->numFuncImports() + funcDefIndex))
    1532           0 :             return false;
    1533             :     }
    1534             : 
    1535           0 :     if (!d.finishSection(sectionStart, sectionSize, "code"))
    1536           0 :         return false;
    1537             : 
    1538           0 :     return true;
    1539             : }
    1540             : 
    1541             : static bool
    1542           0 : DecodeDataSection(Decoder& d, ModuleEnvironment* env)
    1543             : {
    1544             :     uint32_t sectionStart, sectionSize;
    1545           0 :     if (!d.startSection(SectionId::Data, env, &sectionStart, &sectionSize, "data"))
    1546           0 :         return false;
    1547           0 :     if (sectionStart == Decoder::NotStarted)
    1548           0 :         return true;
    1549             : 
    1550             :     uint32_t numSegments;
    1551           0 :     if (!d.readVarU32(&numSegments))
    1552           0 :         return d.fail("failed to read number of data segments");
    1553             : 
    1554           0 :     if (numSegments > MaxDataSegments)
    1555           0 :         return d.fail("too many data segments");
    1556             : 
    1557           0 :     for (uint32_t i = 0; i < numSegments; i++) {
    1558             :         uint32_t linearMemoryIndex;
    1559           0 :         if (!d.readVarU32(&linearMemoryIndex))
    1560           0 :             return d.fail("expected linear memory index");
    1561             : 
    1562           0 :         if (linearMemoryIndex != 0)
    1563           0 :             return d.fail("linear memory index must currently be 0");
    1564             : 
    1565           0 :         if (!env->usesMemory())
    1566           0 :             return d.fail("data segment requires a memory section");
    1567             : 
    1568           0 :         DataSegment seg;
    1569           0 :         if (!DecodeInitializerExpression(d, env->globals, ValType::I32, &seg.offset))
    1570           0 :             return false;
    1571             : 
    1572           0 :         if (!d.readVarU32(&seg.length))
    1573           0 :             return d.fail("expected segment size");
    1574             : 
    1575           0 :         if (seg.length > MaxMemoryInitialPages * PageSize)
    1576           0 :             return d.fail("segment size too big");
    1577             : 
    1578           0 :         seg.bytecodeOffset = d.currentOffset();
    1579             : 
    1580           0 :         if (!d.readBytes(seg.length))
    1581           0 :             return d.fail("data segment shorter than declared");
    1582             : 
    1583           0 :         if (!env->dataSegments.append(seg))
    1584           0 :             return false;
    1585             :     }
    1586             : 
    1587           0 :     if (!d.finishSection(sectionStart, sectionSize, "data"))
    1588           0 :         return false;
    1589             : 
    1590           0 :     return true;
    1591             : }
    1592             : 
    1593             : static bool
    1594           0 : DecodeModuleNameSubsection(Decoder& d, ModuleEnvironment* env)
    1595             : {
    1596             :     uint32_t endOffset;
    1597           0 :     if (!d.startNameSubsection(NameType::Module, &endOffset))
    1598           0 :         return false;
    1599           0 :     if (endOffset == Decoder::NotStarted)
    1600           0 :         return true;
    1601             : 
    1602             :     // Don't use NameInBytecode for module name; instead store a copy of the
    1603             :     // string. This way supplying a module name doesn't need to save the whole
    1604             :     // bytecode. While function names are likely to be stripped in practice,
    1605             :     // module names aren't necessarily.
    1606             : 
    1607             :     uint32_t nameLength;
    1608           0 :     if (!d.readVarU32(&nameLength))
    1609           0 :         return false;
    1610             : 
    1611             :     const uint8_t* bytes;
    1612           0 :     if (!d.readBytes(nameLength, &bytes))
    1613           0 :         return false;
    1614             : 
    1615             :     // Do nothing with module name for now; a future patch will incorporate the
    1616             :     // module name into the callstack format.
    1617             : 
    1618           0 :     return d.finishNameSubsection(endOffset);
    1619             : }
    1620             : 
    1621             : static bool
    1622           0 : DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env)
    1623             : {
    1624             :     uint32_t endOffset;
    1625           0 :     if (!d.startNameSubsection(NameType::Function, &endOffset))
    1626           0 :         return false;
    1627           0 :     if (endOffset == Decoder::NotStarted)
    1628           0 :         return true;
    1629             : 
    1630           0 :     uint32_t nameCount = 0;
    1631           0 :     if (!d.readVarU32(&nameCount) || nameCount > MaxFuncs)
    1632           0 :         return false;
    1633             : 
    1634           0 :     NameInBytecodeVector funcNames;
    1635             : 
    1636           0 :     for (uint32_t i = 0; i < nameCount; ++i) {
    1637           0 :         uint32_t funcIndex = 0;
    1638           0 :         if (!d.readVarU32(&funcIndex))
    1639           0 :             return false;
    1640             : 
    1641             :         // Names must refer to real functions and be given in ascending order.
    1642           0 :         if (funcIndex >= env->numFuncs() || funcIndex < funcNames.length())
    1643           0 :             return false;
    1644             : 
    1645           0 :         if (!funcNames.resize(funcIndex + 1))
    1646           0 :             return false;
    1647             : 
    1648           0 :         uint32_t nameLength = 0;
    1649           0 :         if (!d.readVarU32(&nameLength) || nameLength > MaxStringLength)
    1650           0 :             return false;
    1651             : 
    1652           0 :         NameInBytecode func;
    1653           0 :         func.offset = d.currentOffset();
    1654           0 :         func.length = nameLength;
    1655           0 :         funcNames[funcIndex] = func;
    1656             : 
    1657           0 :         if (!d.readBytes(nameLength))
    1658           0 :             return false;
    1659             :     }
    1660             : 
    1661           0 :     if (!d.finishNameSubsection(endOffset))
    1662           0 :         return false;
    1663             : 
    1664             :     // To encourage fully valid function names subsections; only save names if
    1665             :     // the entire subsection decoded correctly.
    1666           0 :     env->funcNames = Move(funcNames);
    1667           0 :     return true;
    1668             : }
    1669             : 
    1670             : static bool
    1671           0 : DecodeNameSection(Decoder& d, ModuleEnvironment* env)
    1672             : {
    1673             :     uint32_t sectionStart, sectionSize;
    1674           0 :     if (!d.startCustomSection(NameSectionName, env, &sectionStart, &sectionSize))
    1675           0 :         return false;
    1676           0 :     if (sectionStart == Decoder::NotStarted)
    1677           0 :         return true;
    1678             : 
    1679             :     // Once started, custom sections do not report validation errors.
    1680             : 
    1681           0 :     if (!DecodeModuleNameSubsection(d, env))
    1682           0 :         goto finish;
    1683             : 
    1684           0 :     if (!DecodeFunctionNameSubsection(d, env))
    1685           0 :         goto finish;
    1686             : 
    1687             :     // The names we care about have already been extracted into 'env' so don't
    1688             :     // bother decoding the rest of the name section. finishCustomSection() will
    1689             :     // skip to the end of the name section (as it would for any other error).
    1690             : 
    1691             :   finish:
    1692           0 :     d.finishCustomSection(sectionStart, sectionSize);
    1693           0 :     return true;
    1694             : }
    1695             : 
    1696             : bool
    1697           0 : wasm::DecodeModuleTail(Decoder& d, ModuleEnvironment* env)
    1698             : {
    1699           0 :     if (!DecodeDataSection(d, env))
    1700           0 :         return false;
    1701             : 
    1702           0 :     if (!DecodeNameSection(d, env))
    1703           0 :         return false;
    1704             : 
    1705           0 :     while (!d.done()) {
    1706           0 :         if (!d.skipCustomSection(env)) {
    1707           0 :             if (d.resilientMode()) {
    1708           0 :                 d.clearError();
    1709           0 :                 return true;
    1710             :             }
    1711           0 :             return false;
    1712             :         }
    1713             :     }
    1714             : 
    1715           0 :     return true;
    1716             : }
    1717             : 
    1718             : // Validate algorithm.
    1719             : 
    1720             : bool
    1721           0 : wasm::Validate(const ShareableBytes& bytecode, UniqueChars* error)
    1722             : {
    1723           0 :     Decoder d(bytecode.bytes, error);
    1724             : 
    1725           0 :     ModuleEnvironment env;
    1726           0 :     if (!DecodeModuleEnvironment(d, &env))
    1727           0 :         return false;
    1728             : 
    1729           0 :     if (!DecodeCodeSection(d, &env))
    1730           0 :         return false;
    1731             : 
    1732           0 :     if (!DecodeModuleTail(d, &env))
    1733           0 :         return false;
    1734             : 
    1735           0 :     MOZ_ASSERT(!*error, "unreported error in decoding");
    1736           0 :     return true;
    1737             : }

Generated by: LCOV version 1.13