1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
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 #include "mozilla/Utf8.h"
23 
24 #include "jit/JitOptions.h"
25 #include "js/Printf.h"
26 #include "js/String.h"  // JS::MaxStringLength
27 #include "vm/JSContext.h"
28 #include "vm/Realm.h"
29 #include "wasm/WasmOpIter.h"
30 
31 using namespace js;
32 using namespace js::jit;
33 using namespace js::wasm;
34 
35 using mozilla::AsChars;
36 using mozilla::CheckedInt;
37 using mozilla::CheckedInt32;
38 using mozilla::IsUtf8;
39 using mozilla::Span;
40 
41 // Misc helpers.
42 
EncodeLocalEntries(Encoder & e,const ValTypeVector & locals)43 bool wasm::EncodeLocalEntries(Encoder& e, const ValTypeVector& locals) {
44   if (locals.length() > MaxLocals) {
45     return false;
46   }
47 
48   uint32_t numLocalEntries = 0;
49   if (locals.length()) {
50     ValType prev = locals[0];
51     numLocalEntries++;
52     for (ValType t : locals) {
53       if (t != prev) {
54         numLocalEntries++;
55         prev = t;
56       }
57     }
58   }
59 
60   if (!e.writeVarU32(numLocalEntries)) {
61     return false;
62   }
63 
64   if (numLocalEntries) {
65     ValType prev = locals[0];
66     uint32_t count = 1;
67     for (uint32_t i = 1; i < locals.length(); i++, count++) {
68       if (prev != locals[i]) {
69         if (!e.writeVarU32(count)) {
70           return false;
71         }
72         if (!e.writeValType(prev)) {
73           return false;
74         }
75         prev = locals[i];
76         count = 0;
77       }
78     }
79     if (!e.writeVarU32(count)) {
80       return false;
81     }
82     if (!e.writeValType(prev)) {
83       return false;
84     }
85   }
86 
87   return true;
88 }
89 
DecodeLocalEntries(Decoder & d,const TypeContext & types,const FeatureArgs & features,ValTypeVector * locals)90 bool wasm::DecodeLocalEntries(Decoder& d, const TypeContext& types,
91                               const FeatureArgs& features,
92                               ValTypeVector* locals) {
93   uint32_t numLocalEntries;
94   if (!d.readVarU32(&numLocalEntries)) {
95     return d.fail("failed to read number of local entries");
96   }
97 
98   for (uint32_t i = 0; i < numLocalEntries; i++) {
99     uint32_t count;
100     if (!d.readVarU32(&count)) {
101       return d.fail("failed to read local entry count");
102     }
103 
104     if (MaxLocals - locals->length() < count) {
105       return d.fail("too many locals");
106     }
107 
108     ValType type;
109     if (!d.readValType(types, features, &type)) {
110       return false;
111     }
112 
113     if (!type.isDefaultable()) {
114       return d.fail("cannot have a non-defaultable local");
115     }
116 
117     if (!locals->appendN(type, count)) {
118       return false;
119     }
120   }
121 
122   return true;
123 }
124 
DecodeValidatedLocalEntries(Decoder & d,ValTypeVector * locals)125 bool wasm::DecodeValidatedLocalEntries(Decoder& d, ValTypeVector* locals) {
126   uint32_t numLocalEntries;
127   MOZ_ALWAYS_TRUE(d.readVarU32(&numLocalEntries));
128 
129   for (uint32_t i = 0; i < numLocalEntries; i++) {
130     uint32_t count = d.uncheckedReadVarU32();
131     MOZ_ASSERT(MaxLocals - locals->length() >= count);
132     if (!locals->appendN(d.uncheckedReadValType(), count)) {
133       return false;
134     }
135   }
136 
137   return true;
138 }
139 
CheckIsSubtypeOf(Decoder & d,const ModuleEnvironment & env,size_t opcodeOffset,ValType actual,ValType expected,TypeCache * cache)140 bool wasm::CheckIsSubtypeOf(Decoder& d, const ModuleEnvironment& env,
141                             size_t opcodeOffset, ValType actual,
142                             ValType expected, TypeCache* cache) {
143   switch (env.types.isSubtypeOf(actual, expected, cache)) {
144     case TypeResult::OOM:
145       return false;
146     case TypeResult::True:
147       return true;
148     case TypeResult::False: {
149       UniqueChars actualText = ToString(actual);
150       if (!actualText) {
151         return false;
152       }
153 
154       UniqueChars expectedText = ToString(expected);
155       if (!expectedText) {
156         return false;
157       }
158 
159       UniqueChars error(
160           JS_smprintf("type mismatch: expression has type %s but expected %s",
161                       actualText.get(), expectedText.get()));
162       if (!error) {
163         return false;
164       }
165 
166       return d.fail(opcodeOffset, error.get());
167     }
168     default:
169       MOZ_CRASH();
170   }
171 }
172 
173 // Function body validation.
174 
DecodeFunctionBodyExprs(const ModuleEnvironment & env,uint32_t funcIndex,const ValTypeVector & locals,const uint8_t * bodyEnd,Decoder * d)175 static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
176                                     uint32_t funcIndex,
177                                     const ValTypeVector& locals,
178                                     const uint8_t* bodyEnd, Decoder* d) {
179   ValidatingOpIter iter(env, *d);
180 
181   if (!iter.startFunction(funcIndex)) {
182     return false;
183   }
184 
185 #define CHECK(c)          \
186   if (!(c)) return false; \
187   break
188 
189   while (true) {
190     OpBytes op;
191     if (!iter.readOp(&op)) {
192       return false;
193     }
194 
195     Nothing nothing;
196     NothingVector nothings{};
197     ResultType unusedType;
198 
199     switch (op.b0) {
200       case uint16_t(Op::End): {
201         LabelKind unusedKind;
202         if (!iter.readEnd(&unusedKind, &unusedType, &nothings, &nothings)) {
203           return false;
204         }
205         iter.popEnd();
206         if (iter.controlStackEmpty()) {
207           return iter.endFunction(bodyEnd);
208         }
209         break;
210       }
211       case uint16_t(Op::Nop):
212         CHECK(iter.readNop());
213       case uint16_t(Op::Drop):
214         CHECK(iter.readDrop());
215       case uint16_t(Op::Call): {
216         uint32_t unusedIndex;
217         NothingVector unusedArgs{};
218         CHECK(iter.readCall(&unusedIndex, &unusedArgs));
219       }
220       case uint16_t(Op::CallIndirect): {
221         uint32_t unusedIndex, unusedIndex2;
222         NothingVector unusedArgs{};
223         CHECK(iter.readCallIndirect(&unusedIndex, &unusedIndex2, &nothing,
224                                     &unusedArgs));
225       }
226       case uint16_t(Op::I32Const): {
227         int32_t unused;
228         CHECK(iter.readI32Const(&unused));
229       }
230       case uint16_t(Op::I64Const): {
231         int64_t unused;
232         CHECK(iter.readI64Const(&unused));
233       }
234       case uint16_t(Op::F32Const): {
235         float unused;
236         CHECK(iter.readF32Const(&unused));
237       }
238       case uint16_t(Op::F64Const): {
239         double unused;
240         CHECK(iter.readF64Const(&unused));
241       }
242       case uint16_t(Op::GetLocal): {
243         uint32_t unused;
244         CHECK(iter.readGetLocal(locals, &unused));
245       }
246       case uint16_t(Op::SetLocal): {
247         uint32_t unused;
248         CHECK(iter.readSetLocal(locals, &unused, &nothing));
249       }
250       case uint16_t(Op::TeeLocal): {
251         uint32_t unused;
252         CHECK(iter.readTeeLocal(locals, &unused, &nothing));
253       }
254       case uint16_t(Op::GetGlobal): {
255         uint32_t unused;
256         CHECK(iter.readGetGlobal(&unused));
257       }
258       case uint16_t(Op::SetGlobal): {
259         uint32_t unused;
260         CHECK(iter.readSetGlobal(&unused, &nothing));
261       }
262       case uint16_t(Op::TableGet): {
263         uint32_t unusedTableIndex;
264         CHECK(iter.readTableGet(&unusedTableIndex, &nothing));
265       }
266       case uint16_t(Op::TableSet): {
267         uint32_t unusedTableIndex;
268         CHECK(iter.readTableSet(&unusedTableIndex, &nothing, &nothing));
269       }
270       case uint16_t(Op::SelectNumeric): {
271         StackType unused;
272         CHECK(iter.readSelect(/*typed*/ false, &unused, &nothing, &nothing,
273                               &nothing));
274       }
275       case uint16_t(Op::SelectTyped): {
276         StackType unused;
277         CHECK(iter.readSelect(/*typed*/ true, &unused, &nothing, &nothing,
278                               &nothing));
279       }
280       case uint16_t(Op::Block):
281         CHECK(iter.readBlock(&unusedType));
282       case uint16_t(Op::Loop):
283         CHECK(iter.readLoop(&unusedType));
284       case uint16_t(Op::If):
285         CHECK(iter.readIf(&unusedType, &nothing));
286       case uint16_t(Op::Else):
287         CHECK(iter.readElse(&unusedType, &unusedType, &nothings));
288       case uint16_t(Op::I32Clz):
289       case uint16_t(Op::I32Ctz):
290       case uint16_t(Op::I32Popcnt):
291         CHECK(iter.readUnary(ValType::I32, &nothing));
292       case uint16_t(Op::I64Clz):
293       case uint16_t(Op::I64Ctz):
294       case uint16_t(Op::I64Popcnt):
295         CHECK(iter.readUnary(ValType::I64, &nothing));
296       case uint16_t(Op::F32Abs):
297       case uint16_t(Op::F32Neg):
298       case uint16_t(Op::F32Ceil):
299       case uint16_t(Op::F32Floor):
300       case uint16_t(Op::F32Sqrt):
301       case uint16_t(Op::F32Trunc):
302       case uint16_t(Op::F32Nearest):
303         CHECK(iter.readUnary(ValType::F32, &nothing));
304       case uint16_t(Op::F64Abs):
305       case uint16_t(Op::F64Neg):
306       case uint16_t(Op::F64Ceil):
307       case uint16_t(Op::F64Floor):
308       case uint16_t(Op::F64Sqrt):
309       case uint16_t(Op::F64Trunc):
310       case uint16_t(Op::F64Nearest):
311         CHECK(iter.readUnary(ValType::F64, &nothing));
312       case uint16_t(Op::I32Add):
313       case uint16_t(Op::I32Sub):
314       case uint16_t(Op::I32Mul):
315       case uint16_t(Op::I32DivS):
316       case uint16_t(Op::I32DivU):
317       case uint16_t(Op::I32RemS):
318       case uint16_t(Op::I32RemU):
319       case uint16_t(Op::I32And):
320       case uint16_t(Op::I32Or):
321       case uint16_t(Op::I32Xor):
322       case uint16_t(Op::I32Shl):
323       case uint16_t(Op::I32ShrS):
324       case uint16_t(Op::I32ShrU):
325       case uint16_t(Op::I32Rotl):
326       case uint16_t(Op::I32Rotr):
327         CHECK(iter.readBinary(ValType::I32, &nothing, &nothing));
328       case uint16_t(Op::I64Add):
329       case uint16_t(Op::I64Sub):
330       case uint16_t(Op::I64Mul):
331       case uint16_t(Op::I64DivS):
332       case uint16_t(Op::I64DivU):
333       case uint16_t(Op::I64RemS):
334       case uint16_t(Op::I64RemU):
335       case uint16_t(Op::I64And):
336       case uint16_t(Op::I64Or):
337       case uint16_t(Op::I64Xor):
338       case uint16_t(Op::I64Shl):
339       case uint16_t(Op::I64ShrS):
340       case uint16_t(Op::I64ShrU):
341       case uint16_t(Op::I64Rotl):
342       case uint16_t(Op::I64Rotr):
343         CHECK(iter.readBinary(ValType::I64, &nothing, &nothing));
344       case uint16_t(Op::F32Add):
345       case uint16_t(Op::F32Sub):
346       case uint16_t(Op::F32Mul):
347       case uint16_t(Op::F32Div):
348       case uint16_t(Op::F32Min):
349       case uint16_t(Op::F32Max):
350       case uint16_t(Op::F32CopySign):
351         CHECK(iter.readBinary(ValType::F32, &nothing, &nothing));
352       case uint16_t(Op::F64Add):
353       case uint16_t(Op::F64Sub):
354       case uint16_t(Op::F64Mul):
355       case uint16_t(Op::F64Div):
356       case uint16_t(Op::F64Min):
357       case uint16_t(Op::F64Max):
358       case uint16_t(Op::F64CopySign):
359         CHECK(iter.readBinary(ValType::F64, &nothing, &nothing));
360       case uint16_t(Op::I32Eq):
361       case uint16_t(Op::I32Ne):
362       case uint16_t(Op::I32LtS):
363       case uint16_t(Op::I32LtU):
364       case uint16_t(Op::I32LeS):
365       case uint16_t(Op::I32LeU):
366       case uint16_t(Op::I32GtS):
367       case uint16_t(Op::I32GtU):
368       case uint16_t(Op::I32GeS):
369       case uint16_t(Op::I32GeU):
370         CHECK(iter.readComparison(ValType::I32, &nothing, &nothing));
371       case uint16_t(Op::I64Eq):
372       case uint16_t(Op::I64Ne):
373       case uint16_t(Op::I64LtS):
374       case uint16_t(Op::I64LtU):
375       case uint16_t(Op::I64LeS):
376       case uint16_t(Op::I64LeU):
377       case uint16_t(Op::I64GtS):
378       case uint16_t(Op::I64GtU):
379       case uint16_t(Op::I64GeS):
380       case uint16_t(Op::I64GeU):
381         CHECK(iter.readComparison(ValType::I64, &nothing, &nothing));
382       case uint16_t(Op::F32Eq):
383       case uint16_t(Op::F32Ne):
384       case uint16_t(Op::F32Lt):
385       case uint16_t(Op::F32Le):
386       case uint16_t(Op::F32Gt):
387       case uint16_t(Op::F32Ge):
388         CHECK(iter.readComparison(ValType::F32, &nothing, &nothing));
389       case uint16_t(Op::F64Eq):
390       case uint16_t(Op::F64Ne):
391       case uint16_t(Op::F64Lt):
392       case uint16_t(Op::F64Le):
393       case uint16_t(Op::F64Gt):
394       case uint16_t(Op::F64Ge):
395         CHECK(iter.readComparison(ValType::F64, &nothing, &nothing));
396       case uint16_t(Op::I32Eqz):
397         CHECK(iter.readConversion(ValType::I32, ValType::I32, &nothing));
398       case uint16_t(Op::I64Eqz):
399       case uint16_t(Op::I32WrapI64):
400         CHECK(iter.readConversion(ValType::I64, ValType::I32, &nothing));
401       case uint16_t(Op::I32TruncSF32):
402       case uint16_t(Op::I32TruncUF32):
403       case uint16_t(Op::I32ReinterpretF32):
404         CHECK(iter.readConversion(ValType::F32, ValType::I32, &nothing));
405       case uint16_t(Op::I32TruncSF64):
406       case uint16_t(Op::I32TruncUF64):
407         CHECK(iter.readConversion(ValType::F64, ValType::I32, &nothing));
408       case uint16_t(Op::I64ExtendSI32):
409       case uint16_t(Op::I64ExtendUI32):
410         CHECK(iter.readConversion(ValType::I32, ValType::I64, &nothing));
411       case uint16_t(Op::I64TruncSF32):
412       case uint16_t(Op::I64TruncUF32):
413         CHECK(iter.readConversion(ValType::F32, ValType::I64, &nothing));
414       case uint16_t(Op::I64TruncSF64):
415       case uint16_t(Op::I64TruncUF64):
416       case uint16_t(Op::I64ReinterpretF64):
417         CHECK(iter.readConversion(ValType::F64, ValType::I64, &nothing));
418       case uint16_t(Op::F32ConvertSI32):
419       case uint16_t(Op::F32ConvertUI32):
420       case uint16_t(Op::F32ReinterpretI32):
421         CHECK(iter.readConversion(ValType::I32, ValType::F32, &nothing));
422       case uint16_t(Op::F32ConvertSI64):
423       case uint16_t(Op::F32ConvertUI64):
424         CHECK(iter.readConversion(ValType::I64, ValType::F32, &nothing));
425       case uint16_t(Op::F32DemoteF64):
426         CHECK(iter.readConversion(ValType::F64, ValType::F32, &nothing));
427       case uint16_t(Op::F64ConvertSI32):
428       case uint16_t(Op::F64ConvertUI32):
429         CHECK(iter.readConversion(ValType::I32, ValType::F64, &nothing));
430       case uint16_t(Op::F64ConvertSI64):
431       case uint16_t(Op::F64ConvertUI64):
432       case uint16_t(Op::F64ReinterpretI64):
433         CHECK(iter.readConversion(ValType::I64, ValType::F64, &nothing));
434       case uint16_t(Op::F64PromoteF32):
435         CHECK(iter.readConversion(ValType::F32, ValType::F64, &nothing));
436       case uint16_t(Op::I32Extend8S):
437       case uint16_t(Op::I32Extend16S):
438         CHECK(iter.readConversion(ValType::I32, ValType::I32, &nothing));
439       case uint16_t(Op::I64Extend8S):
440       case uint16_t(Op::I64Extend16S):
441       case uint16_t(Op::I64Extend32S):
442         CHECK(iter.readConversion(ValType::I64, ValType::I64, &nothing));
443       case uint16_t(Op::I32Load8S):
444       case uint16_t(Op::I32Load8U): {
445         LinearMemoryAddress<Nothing> addr;
446         CHECK(iter.readLoad(ValType::I32, 1, &addr));
447       }
448       case uint16_t(Op::I32Load16S):
449       case uint16_t(Op::I32Load16U): {
450         LinearMemoryAddress<Nothing> addr;
451         CHECK(iter.readLoad(ValType::I32, 2, &addr));
452       }
453       case uint16_t(Op::I32Load): {
454         LinearMemoryAddress<Nothing> addr;
455         CHECK(iter.readLoad(ValType::I32, 4, &addr));
456       }
457       case uint16_t(Op::I64Load8S):
458       case uint16_t(Op::I64Load8U): {
459         LinearMemoryAddress<Nothing> addr;
460         CHECK(iter.readLoad(ValType::I64, 1, &addr));
461       }
462       case uint16_t(Op::I64Load16S):
463       case uint16_t(Op::I64Load16U): {
464         LinearMemoryAddress<Nothing> addr;
465         CHECK(iter.readLoad(ValType::I64, 2, &addr));
466       }
467       case uint16_t(Op::I64Load32S):
468       case uint16_t(Op::I64Load32U): {
469         LinearMemoryAddress<Nothing> addr;
470         CHECK(iter.readLoad(ValType::I64, 4, &addr));
471       }
472       case uint16_t(Op::I64Load): {
473         LinearMemoryAddress<Nothing> addr;
474         CHECK(iter.readLoad(ValType::I64, 8, &addr));
475       }
476       case uint16_t(Op::F32Load): {
477         LinearMemoryAddress<Nothing> addr;
478         CHECK(iter.readLoad(ValType::F32, 4, &addr));
479       }
480       case uint16_t(Op::F64Load): {
481         LinearMemoryAddress<Nothing> addr;
482         CHECK(iter.readLoad(ValType::F64, 8, &addr));
483       }
484       case uint16_t(Op::I32Store8): {
485         LinearMemoryAddress<Nothing> addr;
486         CHECK(iter.readStore(ValType::I32, 1, &addr, &nothing));
487       }
488       case uint16_t(Op::I32Store16): {
489         LinearMemoryAddress<Nothing> addr;
490         CHECK(iter.readStore(ValType::I32, 2, &addr, &nothing));
491       }
492       case uint16_t(Op::I32Store): {
493         LinearMemoryAddress<Nothing> addr;
494         CHECK(iter.readStore(ValType::I32, 4, &addr, &nothing));
495       }
496       case uint16_t(Op::I64Store8): {
497         LinearMemoryAddress<Nothing> addr;
498         CHECK(iter.readStore(ValType::I64, 1, &addr, &nothing));
499       }
500       case uint16_t(Op::I64Store16): {
501         LinearMemoryAddress<Nothing> addr;
502         CHECK(iter.readStore(ValType::I64, 2, &addr, &nothing));
503       }
504       case uint16_t(Op::I64Store32): {
505         LinearMemoryAddress<Nothing> addr;
506         CHECK(iter.readStore(ValType::I64, 4, &addr, &nothing));
507       }
508       case uint16_t(Op::I64Store): {
509         LinearMemoryAddress<Nothing> addr;
510         CHECK(iter.readStore(ValType::I64, 8, &addr, &nothing));
511       }
512       case uint16_t(Op::F32Store): {
513         LinearMemoryAddress<Nothing> addr;
514         CHECK(iter.readStore(ValType::F32, 4, &addr, &nothing));
515       }
516       case uint16_t(Op::F64Store): {
517         LinearMemoryAddress<Nothing> addr;
518         CHECK(iter.readStore(ValType::F64, 8, &addr, &nothing));
519       }
520       case uint16_t(Op::MemoryGrow):
521         CHECK(iter.readMemoryGrow(&nothing));
522       case uint16_t(Op::MemorySize):
523         CHECK(iter.readMemorySize());
524       case uint16_t(Op::Br): {
525         uint32_t unusedDepth;
526         CHECK(iter.readBr(&unusedDepth, &unusedType, &nothings));
527       }
528       case uint16_t(Op::BrIf): {
529         uint32_t unusedDepth;
530         CHECK(iter.readBrIf(&unusedDepth, &unusedType, &nothings, &nothing));
531       }
532       case uint16_t(Op::BrTable): {
533         Uint32Vector unusedDepths;
534         uint32_t unusedDefault;
535         CHECK(iter.readBrTable(&unusedDepths, &unusedDefault, &unusedType,
536                                &nothings, &nothing));
537       }
538       case uint16_t(Op::Return):
539         CHECK(iter.readReturn(&nothings));
540       case uint16_t(Op::Unreachable):
541         CHECK(iter.readUnreachable());
542 #ifdef ENABLE_WASM_GC
543       case uint16_t(Op::GcPrefix): {
544         if (!env.gcEnabled()) {
545           return iter.unrecognizedOpcode(&op);
546         }
547         switch (op.b1) {
548           case uint32_t(GcOp::StructNewWithRtt): {
549             uint32_t unusedUint;
550             NothingVector unusedArgs{};
551             CHECK(
552                 iter.readStructNewWithRtt(&unusedUint, &nothing, &unusedArgs));
553           }
554           case uint32_t(GcOp::StructNewDefaultWithRtt): {
555             uint32_t unusedUint;
556             CHECK(iter.readStructNewDefaultWithRtt(&unusedUint, &nothing));
557           }
558           case uint32_t(GcOp::StructGet): {
559             uint32_t unusedUint1, unusedUint2;
560             CHECK(iter.readStructGet(&unusedUint1, &unusedUint2,
561                                      FieldExtension::None, &nothing));
562           }
563           case uint32_t(GcOp::StructGetS): {
564             uint32_t unusedUint1, unusedUint2;
565             CHECK(iter.readStructGet(&unusedUint1, &unusedUint2,
566                                      FieldExtension::Signed, &nothing));
567           }
568           case uint32_t(GcOp::StructGetU): {
569             uint32_t unusedUint1, unusedUint2;
570             CHECK(iter.readStructGet(&unusedUint1, &unusedUint2,
571                                      FieldExtension::Unsigned, &nothing));
572           }
573           case uint32_t(GcOp::StructSet): {
574             uint32_t unusedUint1, unusedUint2;
575             CHECK(iter.readStructSet(&unusedUint1, &unusedUint2, &nothing,
576                                      &nothing));
577           }
578           case uint32_t(GcOp::ArrayNewWithRtt): {
579             uint32_t unusedUint;
580             CHECK(iter.readArrayNewWithRtt(&unusedUint, &nothing, &nothing,
581                                            &nothing));
582           }
583           case uint32_t(GcOp::ArrayNewDefaultWithRtt): {
584             uint32_t unusedUint;
585             CHECK(iter.readArrayNewDefaultWithRtt(&unusedUint, &nothing,
586                                                   &nothing));
587           }
588           case uint32_t(GcOp::ArrayGet): {
589             uint32_t unusedUint1;
590             CHECK(iter.readArrayGet(&unusedUint1, FieldExtension::None,
591                                     &nothing, &nothing));
592           }
593           case uint32_t(GcOp::ArrayGetS): {
594             uint32_t unusedUint1;
595             CHECK(iter.readArrayGet(&unusedUint1, FieldExtension::Signed,
596                                     &nothing, &nothing));
597           }
598           case uint32_t(GcOp::ArrayGetU): {
599             uint32_t unusedUint1;
600             CHECK(iter.readArrayGet(&unusedUint1, FieldExtension::Unsigned,
601                                     &nothing, &nothing));
602           }
603           case uint32_t(GcOp::ArraySet): {
604             uint32_t unusedUint1;
605             CHECK(
606                 iter.readArraySet(&unusedUint1, &nothing, &nothing, &nothing));
607           }
608           case uint32_t(GcOp::ArrayLen): {
609             uint32_t unusedUint1;
610             CHECK(iter.readArrayLen(&unusedUint1, &nothing));
611           }
612           case uint16_t(GcOp::RttCanon): {
613             ValType unusedTy;
614             CHECK(iter.readRttCanon(&unusedTy));
615           }
616           case uint16_t(GcOp::RttSub): {
617             CHECK(iter.readRttSub(&nothing));
618           }
619           case uint16_t(GcOp::RefTest): {
620             uint32_t unusedRttTypeIndex;
621             uint32_t unusedRttDepth;
622             CHECK(iter.readRefTest(&nothing, &unusedRttTypeIndex,
623                                    &unusedRttDepth, &nothing));
624           }
625           case uint16_t(GcOp::RefCast): {
626             uint32_t unusedRttTypeIndex;
627             uint32_t unusedRttDepth;
628             CHECK(iter.readRefCast(&nothing, &unusedRttTypeIndex,
629                                    &unusedRttDepth, &nothing));
630           }
631           case uint16_t(GcOp::BrOnCast): {
632             uint32_t unusedRelativeDepth;
633             uint32_t unusedRttTypeIndex;
634             uint32_t unusedRttDepth;
635             CHECK(iter.readBrOnCast(&unusedRelativeDepth, &nothing,
636                                     &unusedRttTypeIndex, &unusedRttDepth,
637                                     &unusedType, &nothings));
638           }
639           default:
640             return iter.unrecognizedOpcode(&op);
641         }
642         break;
643       }
644 #endif
645 
646 #ifdef ENABLE_WASM_SIMD
647       case uint16_t(Op::SimdPrefix): {
648         if (!env.v128Enabled()) {
649           return iter.unrecognizedOpcode(&op);
650         }
651         uint32_t noIndex;
652         switch (op.b1) {
653           case uint32_t(SimdOp::I8x16ExtractLaneS):
654           case uint32_t(SimdOp::I8x16ExtractLaneU):
655             CHECK(iter.readExtractLane(ValType::I32, 16, &noIndex, &nothing));
656           case uint32_t(SimdOp::I16x8ExtractLaneS):
657           case uint32_t(SimdOp::I16x8ExtractLaneU):
658             CHECK(iter.readExtractLane(ValType::I32, 8, &noIndex, &nothing));
659           case uint32_t(SimdOp::I32x4ExtractLane):
660             CHECK(iter.readExtractLane(ValType::I32, 4, &noIndex, &nothing));
661           case uint32_t(SimdOp::I64x2ExtractLane):
662             CHECK(iter.readExtractLane(ValType::I64, 2, &noIndex, &nothing));
663           case uint32_t(SimdOp::F32x4ExtractLane):
664             CHECK(iter.readExtractLane(ValType::F32, 4, &noIndex, &nothing));
665           case uint32_t(SimdOp::F64x2ExtractLane):
666             CHECK(iter.readExtractLane(ValType::F64, 2, &noIndex, &nothing));
667 
668           case uint32_t(SimdOp::I8x16Splat):
669           case uint32_t(SimdOp::I16x8Splat):
670           case uint32_t(SimdOp::I32x4Splat):
671             CHECK(iter.readConversion(ValType::I32, ValType::V128, &nothing));
672           case uint32_t(SimdOp::I64x2Splat):
673             CHECK(iter.readConversion(ValType::I64, ValType::V128, &nothing));
674           case uint32_t(SimdOp::F32x4Splat):
675             CHECK(iter.readConversion(ValType::F32, ValType::V128, &nothing));
676           case uint32_t(SimdOp::F64x2Splat):
677             CHECK(iter.readConversion(ValType::F64, ValType::V128, &nothing));
678 
679           case uint32_t(SimdOp::V128AnyTrue):
680           case uint32_t(SimdOp::I8x16AllTrue):
681           case uint32_t(SimdOp::I16x8AllTrue):
682           case uint32_t(SimdOp::I32x4AllTrue):
683           case uint32_t(SimdOp::I64x2AllTrue):
684           case uint32_t(SimdOp::I8x16Bitmask):
685           case uint32_t(SimdOp::I16x8Bitmask):
686           case uint32_t(SimdOp::I32x4Bitmask):
687           case uint32_t(SimdOp::I64x2Bitmask):
688             CHECK(iter.readConversion(ValType::V128, ValType::I32, &nothing));
689 
690           case uint32_t(SimdOp::I8x16ReplaceLane):
691             CHECK(iter.readReplaceLane(ValType::I32, 16, &noIndex, &nothing,
692                                        &nothing));
693           case uint32_t(SimdOp::I16x8ReplaceLane):
694             CHECK(iter.readReplaceLane(ValType::I32, 8, &noIndex, &nothing,
695                                        &nothing));
696           case uint32_t(SimdOp::I32x4ReplaceLane):
697             CHECK(iter.readReplaceLane(ValType::I32, 4, &noIndex, &nothing,
698                                        &nothing));
699           case uint32_t(SimdOp::I64x2ReplaceLane):
700             CHECK(iter.readReplaceLane(ValType::I64, 2, &noIndex, &nothing,
701                                        &nothing));
702           case uint32_t(SimdOp::F32x4ReplaceLane):
703             CHECK(iter.readReplaceLane(ValType::F32, 4, &noIndex, &nothing,
704                                        &nothing));
705           case uint32_t(SimdOp::F64x2ReplaceLane):
706             CHECK(iter.readReplaceLane(ValType::F64, 2, &noIndex, &nothing,
707                                        &nothing));
708 
709           case uint32_t(SimdOp::I8x16Eq):
710           case uint32_t(SimdOp::I8x16Ne):
711           case uint32_t(SimdOp::I8x16LtS):
712           case uint32_t(SimdOp::I8x16LtU):
713           case uint32_t(SimdOp::I8x16GtS):
714           case uint32_t(SimdOp::I8x16GtU):
715           case uint32_t(SimdOp::I8x16LeS):
716           case uint32_t(SimdOp::I8x16LeU):
717           case uint32_t(SimdOp::I8x16GeS):
718           case uint32_t(SimdOp::I8x16GeU):
719           case uint32_t(SimdOp::I16x8Eq):
720           case uint32_t(SimdOp::I16x8Ne):
721           case uint32_t(SimdOp::I16x8LtS):
722           case uint32_t(SimdOp::I16x8LtU):
723           case uint32_t(SimdOp::I16x8GtS):
724           case uint32_t(SimdOp::I16x8GtU):
725           case uint32_t(SimdOp::I16x8LeS):
726           case uint32_t(SimdOp::I16x8LeU):
727           case uint32_t(SimdOp::I16x8GeS):
728           case uint32_t(SimdOp::I16x8GeU):
729           case uint32_t(SimdOp::I32x4Eq):
730           case uint32_t(SimdOp::I32x4Ne):
731           case uint32_t(SimdOp::I32x4LtS):
732           case uint32_t(SimdOp::I32x4LtU):
733           case uint32_t(SimdOp::I32x4GtS):
734           case uint32_t(SimdOp::I32x4GtU):
735           case uint32_t(SimdOp::I32x4LeS):
736           case uint32_t(SimdOp::I32x4LeU):
737           case uint32_t(SimdOp::I32x4GeS):
738           case uint32_t(SimdOp::I32x4GeU):
739           case uint32_t(SimdOp::I64x2Eq):
740           case uint32_t(SimdOp::I64x2Ne):
741           case uint32_t(SimdOp::I64x2LtS):
742           case uint32_t(SimdOp::I64x2GtS):
743           case uint32_t(SimdOp::I64x2LeS):
744           case uint32_t(SimdOp::I64x2GeS):
745           case uint32_t(SimdOp::F32x4Eq):
746           case uint32_t(SimdOp::F32x4Ne):
747           case uint32_t(SimdOp::F32x4Lt):
748           case uint32_t(SimdOp::F32x4Gt):
749           case uint32_t(SimdOp::F32x4Le):
750           case uint32_t(SimdOp::F32x4Ge):
751           case uint32_t(SimdOp::F64x2Eq):
752           case uint32_t(SimdOp::F64x2Ne):
753           case uint32_t(SimdOp::F64x2Lt):
754           case uint32_t(SimdOp::F64x2Gt):
755           case uint32_t(SimdOp::F64x2Le):
756           case uint32_t(SimdOp::F64x2Ge):
757           case uint32_t(SimdOp::V128And):
758           case uint32_t(SimdOp::V128Or):
759           case uint32_t(SimdOp::V128Xor):
760           case uint32_t(SimdOp::V128AndNot):
761           case uint32_t(SimdOp::I8x16AvgrU):
762           case uint32_t(SimdOp::I16x8AvgrU):
763           case uint32_t(SimdOp::I8x16Add):
764           case uint32_t(SimdOp::I8x16AddSaturateS):
765           case uint32_t(SimdOp::I8x16AddSaturateU):
766           case uint32_t(SimdOp::I8x16Sub):
767           case uint32_t(SimdOp::I8x16SubSaturateS):
768           case uint32_t(SimdOp::I8x16SubSaturateU):
769           case uint32_t(SimdOp::I8x16MinS):
770           case uint32_t(SimdOp::I8x16MinU):
771           case uint32_t(SimdOp::I8x16MaxS):
772           case uint32_t(SimdOp::I8x16MaxU):
773           case uint32_t(SimdOp::I16x8Add):
774           case uint32_t(SimdOp::I16x8AddSaturateS):
775           case uint32_t(SimdOp::I16x8AddSaturateU):
776           case uint32_t(SimdOp::I16x8Sub):
777           case uint32_t(SimdOp::I16x8SubSaturateS):
778           case uint32_t(SimdOp::I16x8SubSaturateU):
779           case uint32_t(SimdOp::I16x8Mul):
780           case uint32_t(SimdOp::I16x8MinS):
781           case uint32_t(SimdOp::I16x8MinU):
782           case uint32_t(SimdOp::I16x8MaxS):
783           case uint32_t(SimdOp::I16x8MaxU):
784           case uint32_t(SimdOp::I32x4Add):
785           case uint32_t(SimdOp::I32x4Sub):
786           case uint32_t(SimdOp::I32x4Mul):
787           case uint32_t(SimdOp::I32x4MinS):
788           case uint32_t(SimdOp::I32x4MinU):
789           case uint32_t(SimdOp::I32x4MaxS):
790           case uint32_t(SimdOp::I32x4MaxU):
791           case uint32_t(SimdOp::I64x2Add):
792           case uint32_t(SimdOp::I64x2Sub):
793           case uint32_t(SimdOp::I64x2Mul):
794           case uint32_t(SimdOp::F32x4Add):
795           case uint32_t(SimdOp::F32x4Sub):
796           case uint32_t(SimdOp::F32x4Mul):
797           case uint32_t(SimdOp::F32x4Div):
798           case uint32_t(SimdOp::F32x4Min):
799           case uint32_t(SimdOp::F32x4Max):
800           case uint32_t(SimdOp::F64x2Add):
801           case uint32_t(SimdOp::F64x2Sub):
802           case uint32_t(SimdOp::F64x2Mul):
803           case uint32_t(SimdOp::F64x2Div):
804           case uint32_t(SimdOp::F64x2Min):
805           case uint32_t(SimdOp::F64x2Max):
806           case uint32_t(SimdOp::I8x16NarrowSI16x8):
807           case uint32_t(SimdOp::I8x16NarrowUI16x8):
808           case uint32_t(SimdOp::I16x8NarrowSI32x4):
809           case uint32_t(SimdOp::I16x8NarrowUI32x4):
810           case uint32_t(SimdOp::V8x16Swizzle):
811           case uint32_t(SimdOp::F32x4PMax):
812           case uint32_t(SimdOp::F32x4PMin):
813           case uint32_t(SimdOp::F64x2PMax):
814           case uint32_t(SimdOp::F64x2PMin):
815           case uint32_t(SimdOp::I32x4DotSI16x8):
816           case uint32_t(SimdOp::I16x8ExtMulLowSI8x16):
817           case uint32_t(SimdOp::I16x8ExtMulHighSI8x16):
818           case uint32_t(SimdOp::I16x8ExtMulLowUI8x16):
819           case uint32_t(SimdOp::I16x8ExtMulHighUI8x16):
820           case uint32_t(SimdOp::I32x4ExtMulLowSI16x8):
821           case uint32_t(SimdOp::I32x4ExtMulHighSI16x8):
822           case uint32_t(SimdOp::I32x4ExtMulLowUI16x8):
823           case uint32_t(SimdOp::I32x4ExtMulHighUI16x8):
824           case uint32_t(SimdOp::I64x2ExtMulLowSI32x4):
825           case uint32_t(SimdOp::I64x2ExtMulHighSI32x4):
826           case uint32_t(SimdOp::I64x2ExtMulLowUI32x4):
827           case uint32_t(SimdOp::I64x2ExtMulHighUI32x4):
828           case uint32_t(SimdOp::I16x8Q15MulrSatS):
829             CHECK(iter.readBinary(ValType::V128, &nothing, &nothing));
830 
831           case uint32_t(SimdOp::I8x16Neg):
832           case uint32_t(SimdOp::I16x8Neg):
833           case uint32_t(SimdOp::I16x8WidenLowSI8x16):
834           case uint32_t(SimdOp::I16x8WidenHighSI8x16):
835           case uint32_t(SimdOp::I16x8WidenLowUI8x16):
836           case uint32_t(SimdOp::I16x8WidenHighUI8x16):
837           case uint32_t(SimdOp::I32x4Neg):
838           case uint32_t(SimdOp::I32x4WidenLowSI16x8):
839           case uint32_t(SimdOp::I32x4WidenHighSI16x8):
840           case uint32_t(SimdOp::I32x4WidenLowUI16x8):
841           case uint32_t(SimdOp::I32x4WidenHighUI16x8):
842           case uint32_t(SimdOp::I32x4TruncSSatF32x4):
843           case uint32_t(SimdOp::I32x4TruncUSatF32x4):
844           case uint32_t(SimdOp::I64x2Neg):
845           case uint32_t(SimdOp::I64x2WidenLowSI32x4):
846           case uint32_t(SimdOp::I64x2WidenHighSI32x4):
847           case uint32_t(SimdOp::I64x2WidenLowUI32x4):
848           case uint32_t(SimdOp::I64x2WidenHighUI32x4):
849           case uint32_t(SimdOp::F32x4Abs):
850           case uint32_t(SimdOp::F32x4Neg):
851           case uint32_t(SimdOp::F32x4Sqrt):
852           case uint32_t(SimdOp::F32x4ConvertSI32x4):
853           case uint32_t(SimdOp::F32x4ConvertUI32x4):
854           case uint32_t(SimdOp::F64x2Abs):
855           case uint32_t(SimdOp::F64x2Neg):
856           case uint32_t(SimdOp::F64x2Sqrt):
857           case uint32_t(SimdOp::V128Not):
858           case uint32_t(SimdOp::I8x16Popcnt):
859           case uint32_t(SimdOp::I8x16Abs):
860           case uint32_t(SimdOp::I16x8Abs):
861           case uint32_t(SimdOp::I32x4Abs):
862           case uint32_t(SimdOp::I64x2Abs):
863           case uint32_t(SimdOp::F32x4Ceil):
864           case uint32_t(SimdOp::F32x4Floor):
865           case uint32_t(SimdOp::F32x4Trunc):
866           case uint32_t(SimdOp::F32x4Nearest):
867           case uint32_t(SimdOp::F64x2Ceil):
868           case uint32_t(SimdOp::F64x2Floor):
869           case uint32_t(SimdOp::F64x2Trunc):
870           case uint32_t(SimdOp::F64x2Nearest):
871           case uint32_t(SimdOp::F32x4DemoteF64x2Zero):
872           case uint32_t(SimdOp::F64x2PromoteLowF32x4):
873           case uint32_t(SimdOp::F64x2ConvertLowI32x4S):
874           case uint32_t(SimdOp::F64x2ConvertLowI32x4U):
875           case uint32_t(SimdOp::I32x4TruncSatF64x2SZero):
876           case uint32_t(SimdOp::I32x4TruncSatF64x2UZero):
877           case uint32_t(SimdOp::I16x8ExtAddPairwiseI8x16S):
878           case uint32_t(SimdOp::I16x8ExtAddPairwiseI8x16U):
879           case uint32_t(SimdOp::I32x4ExtAddPairwiseI16x8S):
880           case uint32_t(SimdOp::I32x4ExtAddPairwiseI16x8U):
881             CHECK(iter.readUnary(ValType::V128, &nothing));
882 
883           case uint32_t(SimdOp::I8x16Shl):
884           case uint32_t(SimdOp::I8x16ShrS):
885           case uint32_t(SimdOp::I8x16ShrU):
886           case uint32_t(SimdOp::I16x8Shl):
887           case uint32_t(SimdOp::I16x8ShrS):
888           case uint32_t(SimdOp::I16x8ShrU):
889           case uint32_t(SimdOp::I32x4Shl):
890           case uint32_t(SimdOp::I32x4ShrS):
891           case uint32_t(SimdOp::I32x4ShrU):
892           case uint32_t(SimdOp::I64x2Shl):
893           case uint32_t(SimdOp::I64x2ShrS):
894           case uint32_t(SimdOp::I64x2ShrU):
895             CHECK(iter.readVectorShift(&nothing, &nothing));
896 
897           case uint32_t(SimdOp::V128Bitselect):
898             CHECK(iter.readVectorSelect(&nothing, &nothing, &nothing));
899 
900           case uint32_t(SimdOp::V8x16Shuffle): {
901             V128 mask;
902             CHECK(iter.readVectorShuffle(&nothing, &nothing, &mask));
903           }
904 
905           case uint32_t(SimdOp::V128Const): {
906             V128 noVector;
907             CHECK(iter.readV128Const(&noVector));
908           }
909 
910           case uint32_t(SimdOp::V128Load): {
911             LinearMemoryAddress<Nothing> addr;
912             CHECK(iter.readLoad(ValType::V128, 16, &addr));
913           }
914 
915           case uint32_t(SimdOp::V8x16LoadSplat): {
916             LinearMemoryAddress<Nothing> addr;
917             CHECK(iter.readLoadSplat(1, &addr));
918           }
919 
920           case uint32_t(SimdOp::V16x8LoadSplat): {
921             LinearMemoryAddress<Nothing> addr;
922             CHECK(iter.readLoadSplat(2, &addr));
923           }
924 
925           case uint32_t(SimdOp::V32x4LoadSplat): {
926             LinearMemoryAddress<Nothing> addr;
927             CHECK(iter.readLoadSplat(4, &addr));
928           }
929 
930           case uint32_t(SimdOp::V64x2LoadSplat): {
931             LinearMemoryAddress<Nothing> addr;
932             CHECK(iter.readLoadSplat(8, &addr));
933           }
934 
935           case uint32_t(SimdOp::I16x8LoadS8x8):
936           case uint32_t(SimdOp::I16x8LoadU8x8): {
937             LinearMemoryAddress<Nothing> addr;
938             CHECK(iter.readLoadExtend(&addr));
939           }
940 
941           case uint32_t(SimdOp::I32x4LoadS16x4):
942           case uint32_t(SimdOp::I32x4LoadU16x4): {
943             LinearMemoryAddress<Nothing> addr;
944             CHECK(iter.readLoadExtend(&addr));
945           }
946 
947           case uint32_t(SimdOp::I64x2LoadS32x2):
948           case uint32_t(SimdOp::I64x2LoadU32x2): {
949             LinearMemoryAddress<Nothing> addr;
950             CHECK(iter.readLoadExtend(&addr));
951           }
952 
953           case uint32_t(SimdOp::V128Store): {
954             LinearMemoryAddress<Nothing> addr;
955             CHECK(iter.readStore(ValType::V128, 16, &addr, &nothing));
956           }
957 
958           case uint32_t(SimdOp::V128Load32Zero): {
959             LinearMemoryAddress<Nothing> addr;
960             CHECK(iter.readLoadSplat(4, &addr));
961           }
962 
963           case uint32_t(SimdOp::V128Load64Zero): {
964             LinearMemoryAddress<Nothing> addr;
965             CHECK(iter.readLoadSplat(8, &addr));
966           }
967 
968           case uint32_t(SimdOp::V128Load8Lane): {
969             LinearMemoryAddress<Nothing> addr;
970             CHECK(iter.readLoadLane(1, &addr, &noIndex, &nothing));
971           }
972 
973           case uint32_t(SimdOp::V128Load16Lane): {
974             LinearMemoryAddress<Nothing> addr;
975             CHECK(iter.readLoadLane(2, &addr, &noIndex, &nothing));
976           }
977 
978           case uint32_t(SimdOp::V128Load32Lane): {
979             LinearMemoryAddress<Nothing> addr;
980             CHECK(iter.readLoadLane(4, &addr, &noIndex, &nothing));
981           }
982 
983           case uint32_t(SimdOp::V128Load64Lane): {
984             LinearMemoryAddress<Nothing> addr;
985             CHECK(iter.readLoadLane(8, &addr, &noIndex, &nothing));
986           }
987 
988           case uint32_t(SimdOp::V128Store8Lane): {
989             LinearMemoryAddress<Nothing> addr;
990             CHECK(iter.readStoreLane(1, &addr, &noIndex, &nothing));
991           }
992 
993           case uint32_t(SimdOp::V128Store16Lane): {
994             LinearMemoryAddress<Nothing> addr;
995             CHECK(iter.readStoreLane(2, &addr, &noIndex, &nothing));
996           }
997 
998           case uint32_t(SimdOp::V128Store32Lane): {
999             LinearMemoryAddress<Nothing> addr;
1000             CHECK(iter.readStoreLane(4, &addr, &noIndex, &nothing));
1001           }
1002 
1003           case uint32_t(SimdOp::V128Store64Lane): {
1004             LinearMemoryAddress<Nothing> addr;
1005             CHECK(iter.readStoreLane(8, &addr, &noIndex, &nothing));
1006           }
1007 
1008           default:
1009             return iter.unrecognizedOpcode(&op);
1010         }
1011         break;
1012       }
1013 #endif  // ENABLE_WASM_SIMD
1014 
1015       case uint16_t(Op::MiscPrefix): {
1016         switch (op.b1) {
1017           case uint32_t(MiscOp::I32TruncSSatF32):
1018           case uint32_t(MiscOp::I32TruncUSatF32):
1019             CHECK(iter.readConversion(ValType::F32, ValType::I32, &nothing));
1020           case uint32_t(MiscOp::I32TruncSSatF64):
1021           case uint32_t(MiscOp::I32TruncUSatF64):
1022             CHECK(iter.readConversion(ValType::F64, ValType::I32, &nothing));
1023           case uint32_t(MiscOp::I64TruncSSatF32):
1024           case uint32_t(MiscOp::I64TruncUSatF32):
1025             CHECK(iter.readConversion(ValType::F32, ValType::I64, &nothing));
1026           case uint32_t(MiscOp::I64TruncSSatF64):
1027           case uint32_t(MiscOp::I64TruncUSatF64):
1028             CHECK(iter.readConversion(ValType::F64, ValType::I64, &nothing));
1029           case uint32_t(MiscOp::MemCopy): {
1030             uint32_t unusedDestMemIndex;
1031             uint32_t unusedSrcMemIndex;
1032             CHECK(iter.readMemOrTableCopy(/*isMem=*/true, &unusedDestMemIndex,
1033                                           &nothing, &unusedSrcMemIndex,
1034                                           &nothing, &nothing));
1035           }
1036           case uint32_t(MiscOp::DataDrop): {
1037             uint32_t unusedSegIndex;
1038             CHECK(iter.readDataOrElemDrop(/*isData=*/true, &unusedSegIndex));
1039           }
1040           case uint32_t(MiscOp::MemFill):
1041             CHECK(iter.readMemFill(&nothing, &nothing, &nothing));
1042           case uint32_t(MiscOp::MemInit): {
1043             uint32_t unusedSegIndex;
1044             uint32_t unusedTableIndex;
1045             CHECK(iter.readMemOrTableInit(/*isMem=*/true, &unusedSegIndex,
1046                                           &unusedTableIndex, &nothing, &nothing,
1047                                           &nothing));
1048           }
1049           case uint32_t(MiscOp::TableCopy): {
1050             uint32_t unusedDestTableIndex;
1051             uint32_t unusedSrcTableIndex;
1052             CHECK(iter.readMemOrTableCopy(
1053                 /*isMem=*/false, &unusedDestTableIndex, &nothing,
1054                 &unusedSrcTableIndex, &nothing, &nothing));
1055           }
1056           case uint32_t(MiscOp::ElemDrop): {
1057             uint32_t unusedSegIndex;
1058             CHECK(iter.readDataOrElemDrop(/*isData=*/false, &unusedSegIndex));
1059           }
1060           case uint32_t(MiscOp::TableInit): {
1061             uint32_t unusedSegIndex;
1062             uint32_t unusedTableIndex;
1063             CHECK(iter.readMemOrTableInit(/*isMem=*/false, &unusedSegIndex,
1064                                           &unusedTableIndex, &nothing, &nothing,
1065                                           &nothing));
1066           }
1067           case uint32_t(MiscOp::TableFill): {
1068             uint32_t unusedTableIndex;
1069             CHECK(iter.readTableFill(&unusedTableIndex, &nothing, &nothing,
1070                                      &nothing));
1071           }
1072           case uint32_t(MiscOp::TableGrow): {
1073             uint32_t unusedTableIndex;
1074             CHECK(iter.readTableGrow(&unusedTableIndex, &nothing, &nothing));
1075           }
1076           case uint32_t(MiscOp::TableSize): {
1077             uint32_t unusedTableIndex;
1078             CHECK(iter.readTableSize(&unusedTableIndex));
1079           }
1080           default:
1081             return iter.unrecognizedOpcode(&op);
1082         }
1083         break;
1084       }
1085 #ifdef ENABLE_WASM_FUNCTION_REFERENCES
1086       case uint16_t(Op::RefAsNonNull): {
1087         if (!env.functionReferencesEnabled()) {
1088           return iter.unrecognizedOpcode(&op);
1089         }
1090         CHECK(iter.readRefAsNonNull(&nothing));
1091       }
1092       case uint16_t(Op::BrOnNull): {
1093         if (!env.functionReferencesEnabled()) {
1094           return iter.unrecognizedOpcode(&op);
1095         }
1096         uint32_t unusedDepth;
1097         CHECK(
1098             iter.readBrOnNull(&unusedDepth, &unusedType, &nothings, &nothing));
1099       }
1100 #endif
1101 #ifdef ENABLE_WASM_GC
1102       case uint16_t(Op::RefEq): {
1103         if (!env.gcEnabled()) {
1104           return iter.unrecognizedOpcode(&op);
1105         }
1106         CHECK(iter.readComparison(RefType::eq(), &nothing, &nothing));
1107       }
1108 #endif
1109       case uint16_t(Op::RefFunc): {
1110         uint32_t unusedIndex;
1111         CHECK(iter.readRefFunc(&unusedIndex));
1112       }
1113       case uint16_t(Op::RefNull): {
1114         RefType type;
1115         CHECK(iter.readRefNull(&type));
1116       }
1117       case uint16_t(Op::RefIsNull): {
1118         Nothing nothing;
1119         CHECK(iter.readRefIsNull(&nothing));
1120       }
1121 #ifdef ENABLE_WASM_EXCEPTIONS
1122       case uint16_t(Op::Try):
1123         if (!env.exceptionsEnabled()) {
1124           return iter.unrecognizedOpcode(&op);
1125         }
1126         CHECK(iter.readTry(&unusedType));
1127       case uint16_t(Op::Catch): {
1128         if (!env.exceptionsEnabled()) {
1129           return iter.unrecognizedOpcode(&op);
1130         }
1131         LabelKind unusedKind;
1132         uint32_t unusedIndex;
1133         CHECK(iter.readCatch(&unusedKind, &unusedIndex, &unusedType,
1134                              &unusedType, &nothings));
1135       }
1136       case uint16_t(Op::CatchAll): {
1137         if (!env.exceptionsEnabled()) {
1138           return iter.unrecognizedOpcode(&op);
1139         }
1140         LabelKind unusedKind;
1141         CHECK(iter.readCatchAll(&unusedKind, &unusedType, &unusedType,
1142                                 &nothings));
1143       }
1144       case uint16_t(Op::Delegate): {
1145         if (!env.exceptionsEnabled()) {
1146           return iter.unrecognizedOpcode(&op);
1147         }
1148         uint32_t unusedDepth;
1149         if (!iter.readDelegate(&unusedDepth, &unusedType, &nothings)) {
1150           return false;
1151         }
1152         iter.popDelegate();
1153         break;
1154       }
1155       case uint16_t(Op::Throw): {
1156         if (!env.exceptionsEnabled()) {
1157           return iter.unrecognizedOpcode(&op);
1158         }
1159         uint32_t unusedIndex;
1160         CHECK(iter.readThrow(&unusedIndex, &nothings));
1161       }
1162       case uint16_t(Op::Rethrow): {
1163         if (!env.exceptionsEnabled()) {
1164           return iter.unrecognizedOpcode(&op);
1165         }
1166         uint32_t unusedDepth;
1167         CHECK(iter.readRethrow(&unusedDepth));
1168       }
1169 #endif
1170       case uint16_t(Op::ThreadPrefix): {
1171         // Though thread ops can be used on nonshared memories, we make them
1172         // unavailable if shared memory has been disabled in the prefs, for
1173         // maximum predictability and safety and consistency with JS.
1174         if (env.sharedMemoryEnabled() == Shareable::False) {
1175           return iter.unrecognizedOpcode(&op);
1176         }
1177         switch (op.b1) {
1178           case uint32_t(ThreadOp::Wake): {
1179             LinearMemoryAddress<Nothing> addr;
1180             CHECK(iter.readWake(&addr, &nothing));
1181           }
1182           case uint32_t(ThreadOp::I32Wait): {
1183             LinearMemoryAddress<Nothing> addr;
1184             CHECK(iter.readWait(&addr, ValType::I32, 4, &nothing, &nothing));
1185           }
1186           case uint32_t(ThreadOp::I64Wait): {
1187             LinearMemoryAddress<Nothing> addr;
1188             CHECK(iter.readWait(&addr, ValType::I64, 8, &nothing, &nothing));
1189           }
1190           case uint32_t(ThreadOp::Fence): {
1191             CHECK(iter.readFence());
1192           }
1193           case uint32_t(ThreadOp::I32AtomicLoad): {
1194             LinearMemoryAddress<Nothing> addr;
1195             CHECK(iter.readAtomicLoad(&addr, ValType::I32, 4));
1196           }
1197           case uint32_t(ThreadOp::I64AtomicLoad): {
1198             LinearMemoryAddress<Nothing> addr;
1199             CHECK(iter.readAtomicLoad(&addr, ValType::I64, 8));
1200           }
1201           case uint32_t(ThreadOp::I32AtomicLoad8U): {
1202             LinearMemoryAddress<Nothing> addr;
1203             CHECK(iter.readAtomicLoad(&addr, ValType::I32, 1));
1204           }
1205           case uint32_t(ThreadOp::I32AtomicLoad16U): {
1206             LinearMemoryAddress<Nothing> addr;
1207             CHECK(iter.readAtomicLoad(&addr, ValType::I32, 2));
1208           }
1209           case uint32_t(ThreadOp::I64AtomicLoad8U): {
1210             LinearMemoryAddress<Nothing> addr;
1211             CHECK(iter.readAtomicLoad(&addr, ValType::I64, 1));
1212           }
1213           case uint32_t(ThreadOp::I64AtomicLoad16U): {
1214             LinearMemoryAddress<Nothing> addr;
1215             CHECK(iter.readAtomicLoad(&addr, ValType::I64, 2));
1216           }
1217           case uint32_t(ThreadOp::I64AtomicLoad32U): {
1218             LinearMemoryAddress<Nothing> addr;
1219             CHECK(iter.readAtomicLoad(&addr, ValType::I64, 4));
1220           }
1221           case uint32_t(ThreadOp::I32AtomicStore): {
1222             LinearMemoryAddress<Nothing> addr;
1223             CHECK(iter.readAtomicStore(&addr, ValType::I32, 4, &nothing));
1224           }
1225           case uint32_t(ThreadOp::I64AtomicStore): {
1226             LinearMemoryAddress<Nothing> addr;
1227             CHECK(iter.readAtomicStore(&addr, ValType::I64, 8, &nothing));
1228           }
1229           case uint32_t(ThreadOp::I32AtomicStore8U): {
1230             LinearMemoryAddress<Nothing> addr;
1231             CHECK(iter.readAtomicStore(&addr, ValType::I32, 1, &nothing));
1232           }
1233           case uint32_t(ThreadOp::I32AtomicStore16U): {
1234             LinearMemoryAddress<Nothing> addr;
1235             CHECK(iter.readAtomicStore(&addr, ValType::I32, 2, &nothing));
1236           }
1237           case uint32_t(ThreadOp::I64AtomicStore8U): {
1238             LinearMemoryAddress<Nothing> addr;
1239             CHECK(iter.readAtomicStore(&addr, ValType::I64, 1, &nothing));
1240           }
1241           case uint32_t(ThreadOp::I64AtomicStore16U): {
1242             LinearMemoryAddress<Nothing> addr;
1243             CHECK(iter.readAtomicStore(&addr, ValType::I64, 2, &nothing));
1244           }
1245           case uint32_t(ThreadOp::I64AtomicStore32U): {
1246             LinearMemoryAddress<Nothing> addr;
1247             CHECK(iter.readAtomicStore(&addr, ValType::I64, 4, &nothing));
1248           }
1249           case uint32_t(ThreadOp::I32AtomicAdd):
1250           case uint32_t(ThreadOp::I32AtomicSub):
1251           case uint32_t(ThreadOp::I32AtomicAnd):
1252           case uint32_t(ThreadOp::I32AtomicOr):
1253           case uint32_t(ThreadOp::I32AtomicXor):
1254           case uint32_t(ThreadOp::I32AtomicXchg): {
1255             LinearMemoryAddress<Nothing> addr;
1256             CHECK(iter.readAtomicRMW(&addr, ValType::I32, 4, &nothing));
1257           }
1258           case uint32_t(ThreadOp::I64AtomicAdd):
1259           case uint32_t(ThreadOp::I64AtomicSub):
1260           case uint32_t(ThreadOp::I64AtomicAnd):
1261           case uint32_t(ThreadOp::I64AtomicOr):
1262           case uint32_t(ThreadOp::I64AtomicXor):
1263           case uint32_t(ThreadOp::I64AtomicXchg): {
1264             LinearMemoryAddress<Nothing> addr;
1265             CHECK(iter.readAtomicRMW(&addr, ValType::I64, 8, &nothing));
1266           }
1267           case uint32_t(ThreadOp::I32AtomicAdd8U):
1268           case uint32_t(ThreadOp::I32AtomicSub8U):
1269           case uint32_t(ThreadOp::I32AtomicAnd8U):
1270           case uint32_t(ThreadOp::I32AtomicOr8U):
1271           case uint32_t(ThreadOp::I32AtomicXor8U):
1272           case uint32_t(ThreadOp::I32AtomicXchg8U): {
1273             LinearMemoryAddress<Nothing> addr;
1274             CHECK(iter.readAtomicRMW(&addr, ValType::I32, 1, &nothing));
1275           }
1276           case uint32_t(ThreadOp::I32AtomicAdd16U):
1277           case uint32_t(ThreadOp::I32AtomicSub16U):
1278           case uint32_t(ThreadOp::I32AtomicAnd16U):
1279           case uint32_t(ThreadOp::I32AtomicOr16U):
1280           case uint32_t(ThreadOp::I32AtomicXor16U):
1281           case uint32_t(ThreadOp::I32AtomicXchg16U): {
1282             LinearMemoryAddress<Nothing> addr;
1283             CHECK(iter.readAtomicRMW(&addr, ValType::I32, 2, &nothing));
1284           }
1285           case uint32_t(ThreadOp::I64AtomicAdd8U):
1286           case uint32_t(ThreadOp::I64AtomicSub8U):
1287           case uint32_t(ThreadOp::I64AtomicAnd8U):
1288           case uint32_t(ThreadOp::I64AtomicOr8U):
1289           case uint32_t(ThreadOp::I64AtomicXor8U):
1290           case uint32_t(ThreadOp::I64AtomicXchg8U): {
1291             LinearMemoryAddress<Nothing> addr;
1292             CHECK(iter.readAtomicRMW(&addr, ValType::I64, 1, &nothing));
1293           }
1294           case uint32_t(ThreadOp::I64AtomicAdd16U):
1295           case uint32_t(ThreadOp::I64AtomicSub16U):
1296           case uint32_t(ThreadOp::I64AtomicAnd16U):
1297           case uint32_t(ThreadOp::I64AtomicOr16U):
1298           case uint32_t(ThreadOp::I64AtomicXor16U):
1299           case uint32_t(ThreadOp::I64AtomicXchg16U): {
1300             LinearMemoryAddress<Nothing> addr;
1301             CHECK(iter.readAtomicRMW(&addr, ValType::I64, 2, &nothing));
1302           }
1303           case uint32_t(ThreadOp::I64AtomicAdd32U):
1304           case uint32_t(ThreadOp::I64AtomicSub32U):
1305           case uint32_t(ThreadOp::I64AtomicAnd32U):
1306           case uint32_t(ThreadOp::I64AtomicOr32U):
1307           case uint32_t(ThreadOp::I64AtomicXor32U):
1308           case uint32_t(ThreadOp::I64AtomicXchg32U): {
1309             LinearMemoryAddress<Nothing> addr;
1310             CHECK(iter.readAtomicRMW(&addr, ValType::I64, 4, &nothing));
1311           }
1312           case uint32_t(ThreadOp::I32AtomicCmpXchg): {
1313             LinearMemoryAddress<Nothing> addr;
1314             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 4, &nothing,
1315                                          &nothing));
1316           }
1317           case uint32_t(ThreadOp::I64AtomicCmpXchg): {
1318             LinearMemoryAddress<Nothing> addr;
1319             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 8, &nothing,
1320                                          &nothing));
1321           }
1322           case uint32_t(ThreadOp::I32AtomicCmpXchg8U): {
1323             LinearMemoryAddress<Nothing> addr;
1324             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 1, &nothing,
1325                                          &nothing));
1326           }
1327           case uint32_t(ThreadOp::I32AtomicCmpXchg16U): {
1328             LinearMemoryAddress<Nothing> addr;
1329             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I32, 2, &nothing,
1330                                          &nothing));
1331           }
1332           case uint32_t(ThreadOp::I64AtomicCmpXchg8U): {
1333             LinearMemoryAddress<Nothing> addr;
1334             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 1, &nothing,
1335                                          &nothing));
1336           }
1337           case uint32_t(ThreadOp::I64AtomicCmpXchg16U): {
1338             LinearMemoryAddress<Nothing> addr;
1339             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 2, &nothing,
1340                                          &nothing));
1341           }
1342           case uint32_t(ThreadOp::I64AtomicCmpXchg32U): {
1343             LinearMemoryAddress<Nothing> addr;
1344             CHECK(iter.readAtomicCmpXchg(&addr, ValType::I64, 4, &nothing,
1345                                          &nothing));
1346           }
1347           default:
1348             return iter.unrecognizedOpcode(&op);
1349         }
1350         break;
1351       }
1352       case uint16_t(Op::MozPrefix):
1353         return iter.unrecognizedOpcode(&op);
1354       default:
1355         return iter.unrecognizedOpcode(&op);
1356     }
1357   }
1358 
1359   MOZ_CRASH("unreachable");
1360 
1361 #undef CHECK
1362 }
1363 
ValidateFunctionBody(const ModuleEnvironment & env,uint32_t funcIndex,uint32_t bodySize,Decoder & d)1364 bool wasm::ValidateFunctionBody(const ModuleEnvironment& env,
1365                                 uint32_t funcIndex, uint32_t bodySize,
1366                                 Decoder& d) {
1367   ValTypeVector locals;
1368   if (!locals.appendAll(env.funcs[funcIndex].type->args())) {
1369     return false;
1370   }
1371 
1372   const uint8_t* bodyBegin = d.currentPosition();
1373 
1374   if (!DecodeLocalEntries(d, env.types, env.features, &locals)) {
1375     return false;
1376   }
1377 
1378   if (!DecodeFunctionBodyExprs(env, funcIndex, locals, bodyBegin + bodySize,
1379                                &d)) {
1380     return false;
1381   }
1382 
1383   return true;
1384 }
1385 
1386 // Section macros.
1387 
DecodePreamble(Decoder & d)1388 static bool DecodePreamble(Decoder& d) {
1389   if (d.bytesRemain() > MaxModuleBytes) {
1390     return d.fail("module too big");
1391   }
1392 
1393   uint32_t u32;
1394   if (!d.readFixedU32(&u32) || u32 != MagicNumber) {
1395     return d.fail("failed to match magic number");
1396   }
1397 
1398   if (!d.readFixedU32(&u32) || u32 != EncodingVersion) {
1399     return d.failf("binary version 0x%" PRIx32
1400                    " does not match expected version 0x%" PRIx32,
1401                    u32, EncodingVersion);
1402   }
1403 
1404   return true;
1405 }
1406 
1407 enum class TypeState { None, Gc, ForwardGc, Func };
1408 
1409 using TypeStateVector = Vector<TypeState, 0, SystemAllocPolicy>;
1410 
1411 template <class T>
ValidateTypeState(Decoder & d,TypeStateVector * typeState,T type)1412 static bool ValidateTypeState(Decoder& d, TypeStateVector* typeState, T type) {
1413   if (!type.isTypeIndex()) {
1414     return true;
1415   }
1416 
1417   uint32_t refTypeIndex = type.refType().typeIndex();
1418   switch ((*typeState)[refTypeIndex]) {
1419     case TypeState::None:
1420       (*typeState)[refTypeIndex] = TypeState::ForwardGc;
1421       break;
1422     case TypeState::Gc:
1423     case TypeState::ForwardGc:
1424       break;
1425     case TypeState::Func:
1426       return d.fail("ref does not reference a gc type");
1427   }
1428   return true;
1429 }
1430 
1431 #ifdef WASM_PRIVATE_REFTYPES
FuncTypeIsJSCompatible(Decoder & d,const FuncType & ft)1432 static bool FuncTypeIsJSCompatible(Decoder& d, const FuncType& ft) {
1433   if (ft.exposesTypeIndex()) {
1434     return d.fail("cannot expose indexed reference type");
1435   }
1436   return true;
1437 }
1438 #endif
1439 
DecodeTypeVector(Decoder & d,ModuleEnvironment * env,TypeStateVector * typeState,uint32_t count,ValTypeVector * types)1440 static bool DecodeTypeVector(Decoder& d, ModuleEnvironment* env,
1441                              TypeStateVector* typeState, uint32_t count,
1442                              ValTypeVector* types) {
1443   if (!types->resize(count)) {
1444     return false;
1445   }
1446 
1447   for (uint32_t i = 0; i < count; i++) {
1448     if (!d.readValType(env->types.length(), env->features, &(*types)[i])) {
1449       return false;
1450     }
1451     if (!ValidateTypeState(d, typeState, (*types)[i])) {
1452       return false;
1453     }
1454   }
1455   return true;
1456 }
1457 
DecodeFuncType(Decoder & d,ModuleEnvironment * env,TypeStateVector * typeState,uint32_t typeIndex)1458 static bool DecodeFuncType(Decoder& d, ModuleEnvironment* env,
1459                            TypeStateVector* typeState, uint32_t typeIndex) {
1460   uint32_t numArgs;
1461   if (!d.readVarU32(&numArgs)) {
1462     return d.fail("bad number of function args");
1463   }
1464   if (numArgs > MaxParams) {
1465     return d.fail("too many arguments in signature");
1466   }
1467   ValTypeVector args;
1468   if (!DecodeTypeVector(d, env, typeState, numArgs, &args)) {
1469     return false;
1470   }
1471 
1472   uint32_t numResults;
1473   if (!d.readVarU32(&numResults)) {
1474     return d.fail("bad number of function returns");
1475   }
1476   if (numResults > MaxResults) {
1477     return d.fail("too many returns in signature");
1478   }
1479   ValTypeVector results;
1480   if (!DecodeTypeVector(d, env, typeState, numResults, &results)) {
1481     return false;
1482   }
1483 
1484   if ((*typeState)[typeIndex] != TypeState::None) {
1485     return d.fail("function type entry referenced as gc");
1486   }
1487 
1488   env->types[typeIndex] =
1489       TypeDef(FuncType(std::move(args), std::move(results)));
1490   (*typeState)[typeIndex] = TypeState::Func;
1491 
1492   return true;
1493 }
1494 
DecodeStructType(Decoder & d,ModuleEnvironment * env,TypeStateVector * typeState,uint32_t typeIndex)1495 static bool DecodeStructType(Decoder& d, ModuleEnvironment* env,
1496                              TypeStateVector* typeState, uint32_t typeIndex) {
1497   if (!env->gcEnabled()) {
1498     return d.fail("Structure types not enabled");
1499   }
1500 
1501   if ((*typeState)[typeIndex] != TypeState::None &&
1502       (*typeState)[typeIndex] != TypeState::ForwardGc) {
1503     return d.fail("gc type entry referenced as function");
1504   }
1505 
1506   uint32_t numFields;
1507   if (!d.readVarU32(&numFields)) {
1508     return d.fail("Bad number of fields");
1509   }
1510 
1511   if (numFields > MaxStructFields) {
1512     return d.fail("too many fields in struct");
1513   }
1514 
1515   StructFieldVector fields;
1516   if (!fields.resize(numFields)) {
1517     return false;
1518   }
1519 
1520   for (uint32_t i = 0; i < numFields; i++) {
1521     if (!d.readPackedType(env->types.length(), env->features,
1522                           &fields[i].type)) {
1523       return false;
1524     }
1525 
1526     uint8_t flags;
1527     if (!d.readFixedU8(&flags)) {
1528       return d.fail("expected flag");
1529     }
1530     if ((flags & ~uint8_t(FieldFlags::AllowedMask)) != 0) {
1531       return d.fail("garbage flag bits");
1532     }
1533     fields[i].isMutable = flags & uint8_t(FieldFlags::Mutable);
1534 
1535     if (!ValidateTypeState(d, typeState, fields[i].type)) {
1536       return false;
1537     }
1538   }
1539 
1540   StructType structType = StructType(std::move(fields));
1541 
1542   if (!structType.computeLayout()) {
1543     return d.fail("Struct type too large");
1544   }
1545 
1546   env->types[typeIndex] = TypeDef(std::move(structType));
1547   (*typeState)[typeIndex] = TypeState::Gc;
1548 
1549   return true;
1550 }
1551 
DecodeArrayType(Decoder & d,ModuleEnvironment * env,TypeStateVector * typeState,uint32_t typeIndex)1552 static bool DecodeArrayType(Decoder& d, ModuleEnvironment* env,
1553                             TypeStateVector* typeState, uint32_t typeIndex) {
1554   if (!env->gcEnabled()) {
1555     return d.fail("gc types not enabled");
1556   }
1557 
1558   if ((*typeState)[typeIndex] != TypeState::None &&
1559       (*typeState)[typeIndex] != TypeState::ForwardGc) {
1560     return d.fail("gc type entry referenced as function");
1561   }
1562 
1563   FieldType elementType;
1564   if (!d.readFieldType(env->types.length(), env->features, &elementType)) {
1565     return false;
1566   }
1567 
1568   uint8_t flags;
1569   if (!d.readFixedU8(&flags)) {
1570     return d.fail("expected flag");
1571   }
1572   if ((flags & ~uint8_t(FieldFlags::AllowedMask)) != 0) {
1573     return d.fail("garbage flag bits");
1574   }
1575   bool isMutable = flags & uint8_t(FieldFlags::Mutable);
1576 
1577   if (!ValidateTypeState(d, typeState, elementType)) {
1578     return false;
1579   }
1580 
1581   env->types[typeIndex] = TypeDef(ArrayType(elementType, isMutable));
1582   (*typeState)[typeIndex] = TypeState::Gc;
1583 
1584   return true;
1585 }
1586 
DecodeTypeSection(Decoder & d,ModuleEnvironment * env)1587 static bool DecodeTypeSection(Decoder& d, ModuleEnvironment* env) {
1588   MaybeSectionRange range;
1589   if (!d.startSection(SectionId::Type, env, &range, "type")) {
1590     return false;
1591   }
1592   if (!range) {
1593     return true;
1594   }
1595 
1596   uint32_t numTypes;
1597   if (!d.readVarU32(&numTypes)) {
1598     return d.fail("expected number of types");
1599   }
1600 
1601   if (numTypes > MaxTypes) {
1602     return d.fail("too many types");
1603   }
1604 
1605   if (!env->types.resize(numTypes) || !env->typeIds.resize(numTypes)) {
1606     return false;
1607   }
1608 
1609   TypeStateVector typeState;
1610   if (!typeState.appendN(TypeState::None, numTypes)) {
1611     return false;
1612   }
1613 
1614   for (uint32_t typeIndex = 0; typeIndex < numTypes; typeIndex++) {
1615     uint8_t form;
1616     if (!d.readFixedU8(&form)) {
1617       return d.fail("expected type form");
1618     }
1619 
1620     switch (form) {
1621       case uint8_t(TypeCode::Func):
1622         if (!DecodeFuncType(d, env, &typeState, typeIndex)) {
1623           return false;
1624         }
1625         break;
1626       case uint8_t(TypeCode::Struct):
1627         if (!DecodeStructType(d, env, &typeState, typeIndex)) {
1628           return false;
1629         }
1630         break;
1631       case uint8_t(TypeCode::Array):
1632         if (!DecodeArrayType(d, env, &typeState, typeIndex)) {
1633           return false;
1634         }
1635         break;
1636       default:
1637         return d.fail("expected type form");
1638     }
1639   }
1640 
1641   return d.finishSection(*range, "type");
1642 }
1643 
DecodeName(Decoder & d)1644 static UniqueChars DecodeName(Decoder& d) {
1645   uint32_t numBytes;
1646   if (!d.readVarU32(&numBytes)) {
1647     return nullptr;
1648   }
1649 
1650   if (numBytes > MaxStringBytes) {
1651     return nullptr;
1652   }
1653 
1654   const uint8_t* bytes;
1655   if (!d.readBytes(numBytes, &bytes)) {
1656     return nullptr;
1657   }
1658 
1659   if (!IsUtf8(AsChars(Span(bytes, numBytes)))) {
1660     return nullptr;
1661   }
1662 
1663   UniqueChars name(js_pod_malloc<char>(numBytes + 1));
1664   if (!name) {
1665     return nullptr;
1666   }
1667 
1668   memcpy(name.get(), bytes, numBytes);
1669   name[numBytes] = '\0';
1670 
1671   return name;
1672 }
1673 
DecodeFuncTypeIndex(Decoder & d,const TypeContext & types,uint32_t * funcTypeIndex)1674 static bool DecodeFuncTypeIndex(Decoder& d, const TypeContext& types,
1675                                 uint32_t* funcTypeIndex) {
1676   if (!d.readVarU32(funcTypeIndex)) {
1677     return d.fail("expected signature index");
1678   }
1679 
1680   if (*funcTypeIndex >= types.length()) {
1681     return d.fail("signature index out of range");
1682   }
1683 
1684   const TypeDef& def = types[*funcTypeIndex];
1685 
1686   if (!def.isFuncType()) {
1687     return d.fail("signature index references non-signature");
1688   }
1689 
1690   return true;
1691 }
1692 
DecodeLimits(Decoder & d,Limits * limits,Shareable allowShared=Shareable::False)1693 static bool DecodeLimits(Decoder& d, Limits* limits,
1694                          Shareable allowShared = Shareable::False) {
1695   uint8_t flags;
1696   if (!d.readFixedU8(&flags)) {
1697     return d.fail("expected flags");
1698   }
1699 
1700   uint8_t mask = allowShared == Shareable::True
1701                      ? uint8_t(MemoryMasks::AllowShared)
1702                      : uint8_t(MemoryMasks::AllowUnshared);
1703 
1704   if (flags & ~uint8_t(mask)) {
1705     return d.failf("unexpected bits set in flags: %" PRIu32,
1706                    uint32_t(flags & ~uint8_t(mask)));
1707   }
1708 
1709   uint32_t initial;
1710   if (!d.readVarU32(&initial)) {
1711     return d.fail("expected initial length");
1712   }
1713   limits->initial = initial;
1714 
1715   if (flags & uint8_t(MemoryTableFlags::HasMaximum)) {
1716     uint32_t maximum;
1717     if (!d.readVarU32(&maximum)) {
1718       return d.fail("expected maximum length");
1719     }
1720 
1721     if (limits->initial > maximum) {
1722       return d.failf(
1723           "memory size minimum must not be greater than maximum; "
1724           "maximum length %" PRIu32 " is less than initial length %" PRIu64,
1725           maximum, limits->initial);
1726     }
1727 
1728     limits->maximum.emplace(uint64_t(maximum));
1729   }
1730 
1731   limits->shared = Shareable::False;
1732 
1733   if (allowShared == Shareable::True) {
1734     if ((flags & uint8_t(MemoryTableFlags::IsShared)) &&
1735         !(flags & uint8_t(MemoryTableFlags::HasMaximum))) {
1736       return d.fail("maximum length required for shared memory");
1737     }
1738 
1739     limits->shared = (flags & uint8_t(MemoryTableFlags::IsShared))
1740                          ? Shareable::True
1741                          : Shareable::False;
1742   }
1743 
1744   return true;
1745 }
1746 
DecodeTableTypeAndLimits(Decoder & d,const FeatureArgs & features,const TypeContext & types,TableDescVector * tables)1747 static bool DecodeTableTypeAndLimits(Decoder& d, const FeatureArgs& features,
1748                                      const TypeContext& types,
1749                                      TableDescVector* tables) {
1750   RefType tableElemType;
1751   if (!d.readRefType(types, features, &tableElemType)) {
1752     return false;
1753   }
1754   if (!tableElemType.isNullable()) {
1755     return d.fail("non-nullable references not supported in tables");
1756   }
1757 
1758   Limits limits;
1759   if (!DecodeLimits(d, &limits)) {
1760     return false;
1761   }
1762 
1763   // If there's a maximum, check it is in range.  The check to exclude
1764   // initial > maximum is carried out by the DecodeLimits call above, so
1765   // we don't repeat it here.
1766   if (limits.initial > MaxTableLimitField ||
1767       ((limits.maximum.isSome() &&
1768         limits.maximum.value() > MaxTableLimitField))) {
1769     return d.fail("too many table elements");
1770   }
1771 
1772   if (tables->length() >= MaxTables) {
1773     return d.fail("too many tables");
1774   }
1775 
1776   // The rest of the runtime expects table limits to be within a 32-bit range.
1777   static_assert(MaxTableLimitField <= UINT32_MAX, "invariant");
1778   uint32_t initialLength = uint32_t(limits.initial);
1779   Maybe<uint32_t> maximumLength;
1780   if (limits.maximum) {
1781     maximumLength = Some(uint32_t(*limits.maximum));
1782   }
1783 
1784   return tables->emplaceBack(tableElemType, initialLength, maximumLength,
1785                              /* isAsmJS */ false);
1786 }
1787 
GlobalIsJSCompatible(Decoder & d,ValType type)1788 static bool GlobalIsJSCompatible(Decoder& d, ValType type) {
1789   switch (type.kind()) {
1790     case ValType::I32:
1791     case ValType::F32:
1792     case ValType::F64:
1793     case ValType::I64:
1794     case ValType::V128:
1795       break;
1796     case ValType::Ref:
1797       switch (type.refTypeKind()) {
1798         case RefType::Func:
1799         case RefType::Extern:
1800         case RefType::Eq:
1801           break;
1802         case RefType::TypeIndex:
1803 #ifdef WASM_PRIVATE_REFTYPES
1804           return d.fail("cannot expose indexed reference type");
1805 #else
1806           break;
1807 #endif
1808         default:
1809           return d.fail("unexpected variable type in global import/export");
1810       }
1811       break;
1812     default:
1813       return d.fail("unexpected variable type in global import/export");
1814   }
1815 
1816   return true;
1817 }
1818 
DecodeGlobalType(Decoder & d,const TypeContext & types,const FeatureArgs & features,ValType * type,bool * isMutable)1819 static bool DecodeGlobalType(Decoder& d, const TypeContext& types,
1820                              const FeatureArgs& features, ValType* type,
1821                              bool* isMutable) {
1822   if (!d.readValType(types, features, type)) {
1823     return d.fail("expected global type");
1824   }
1825 
1826   if (type->isReference() && !type->isNullable()) {
1827     return d.fail("non-nullable references not supported in globals");
1828   }
1829 
1830   uint8_t flags;
1831   if (!d.readFixedU8(&flags)) {
1832     return d.fail("expected global flags");
1833   }
1834 
1835   if (flags & ~uint8_t(GlobalTypeImmediate::AllowedMask)) {
1836     return d.fail("unexpected bits set in global flags");
1837   }
1838 
1839   *isMutable = flags & uint8_t(GlobalTypeImmediate::IsMutable);
1840   return true;
1841 }
1842 
DecodeMemoryLimits(Decoder & d,ModuleEnvironment * env)1843 static bool DecodeMemoryLimits(Decoder& d, ModuleEnvironment* env) {
1844   if (env->usesMemory()) {
1845     return d.fail("already have default memory");
1846   }
1847 
1848   Limits limits;
1849   if (!DecodeLimits(d, &limits, Shareable::True)) {
1850     return false;
1851   }
1852 
1853   if (limits.initial > MaxMemory32LimitField) {
1854     return d.fail("initial memory size too big");
1855   }
1856 
1857   if (limits.maximum && *limits.maximum > MaxMemory32LimitField) {
1858     return d.fail("maximum memory size too big");
1859   }
1860 
1861   if (limits.shared == Shareable::True &&
1862       env->sharedMemoryEnabled() == Shareable::False) {
1863     return d.fail("shared memory is disabled");
1864   }
1865 
1866   env->memory = Some(MemoryDesc(MemoryKind::Memory32, limits));
1867   return true;
1868 }
1869 
1870 #ifdef ENABLE_WASM_EXCEPTIONS
EventIsJSCompatible(Decoder & d,const ValTypeVector & type)1871 static bool EventIsJSCompatible(Decoder& d, const ValTypeVector& type) {
1872   for (auto t : type) {
1873     if (t.isTypeIndex()) {
1874       return d.fail("cannot expose indexed reference type");
1875     }
1876   }
1877 
1878   return true;
1879 }
1880 
DecodeEvent(Decoder & d,ModuleEnvironment * env,EventKind * eventKind,uint32_t * funcTypeIndex)1881 static bool DecodeEvent(Decoder& d, ModuleEnvironment* env,
1882                         EventKind* eventKind, uint32_t* funcTypeIndex) {
1883   uint32_t eventCode;
1884   if (!d.readVarU32(&eventCode)) {
1885     return d.fail("expected event kind");
1886   }
1887 
1888   if (EventKind(eventCode) != EventKind::Exception) {
1889     return d.fail("illegal event kind");
1890   }
1891   *eventKind = EventKind(eventCode);
1892 
1893   if (!d.readVarU32(funcTypeIndex)) {
1894     return d.fail("expected function index in event");
1895   }
1896   if (*funcTypeIndex >= env->numTypes()) {
1897     return d.fail("function type index in event out of bounds");
1898   }
1899   if (!env->types[*funcTypeIndex].isFuncType()) {
1900     return d.fail("function type index must index a function type");
1901   }
1902   if (env->types[*funcTypeIndex].funcType().results().length() != 0) {
1903     return d.fail("exception function types must not return anything");
1904   }
1905   return true;
1906 }
1907 #endif
1908 
1909 struct CStringPair {
1910   const char* first;
1911   const char* second;
1912 
CStringPairCStringPair1913   CStringPair(const char* first, const char* second)
1914       : first(first), second(second) {}
1915 
1916   using Key = CStringPair;
1917   using Lookup = CStringPair;
1918 
hashCStringPair1919   static mozilla::HashNumber hash(const Lookup& l) {
1920     return mozilla::AddToHash(mozilla::HashString(l.first),
1921                               mozilla::HashString(l.second));
1922   }
matchCStringPair1923   static bool match(const Key& k, const Lookup& l) {
1924     return !strcmp(k.first, l.first) && !strcmp(k.second, l.second);
1925   }
1926 };
1927 
1928 using CStringPairSet = HashSet<CStringPair, CStringPair, SystemAllocPolicy>;
1929 
DecodeImport(Decoder & d,ModuleEnvironment * env,CStringPairSet * dupSet)1930 static bool DecodeImport(Decoder& d, ModuleEnvironment* env,
1931                          CStringPairSet* dupSet) {
1932   UniqueChars moduleName = DecodeName(d);
1933   if (!moduleName) {
1934     return d.fail("expected valid import module name");
1935   }
1936 
1937   UniqueChars funcName = DecodeName(d);
1938   if (!funcName) {
1939     return d.fail("expected valid import func name");
1940   }
1941 
1942   // It is valid to store raw pointers in dupSet because moduleName and funcName
1943   // become owned by env->imports on all non-error paths, outliving dupSet.
1944   CStringPair pair(moduleName.get(), funcName.get());
1945   CStringPairSet::AddPtr p = dupSet->lookupForAdd(pair);
1946   if (p) {
1947     env->usesDuplicateImports = true;
1948   } else if (!dupSet->add(p, pair)) {
1949     return false;
1950   }
1951 
1952   uint8_t rawImportKind;
1953   if (!d.readFixedU8(&rawImportKind)) {
1954     return d.fail("failed to read import kind");
1955   }
1956 
1957   DefinitionKind importKind = DefinitionKind(rawImportKind);
1958 
1959   switch (importKind) {
1960     case DefinitionKind::Function: {
1961       uint32_t funcTypeIndex;
1962       if (!DecodeFuncTypeIndex(d, env->types, &funcTypeIndex)) {
1963         return false;
1964       }
1965 #ifdef WASM_PRIVATE_REFTYPES
1966       if (!FuncTypeIsJSCompatible(d, env->types.funcType(funcTypeIndex))) {
1967         return false;
1968       }
1969 #endif
1970       if (!env->funcs.append(FuncDesc(&env->types.funcType(funcTypeIndex),
1971                                       &env->typeIds[funcTypeIndex],
1972                                       funcTypeIndex))) {
1973         return false;
1974       }
1975       if (env->funcs.length() > MaxFuncs) {
1976         return d.fail("too many functions");
1977       }
1978       break;
1979     }
1980     case DefinitionKind::Table: {
1981       if (!DecodeTableTypeAndLimits(d, env->features, env->types,
1982                                     &env->tables)) {
1983         return false;
1984       }
1985       env->tables.back().importedOrExported = true;
1986       break;
1987     }
1988     case DefinitionKind::Memory: {
1989       if (!DecodeMemoryLimits(d, env)) {
1990         return false;
1991       }
1992       break;
1993     }
1994     case DefinitionKind::Global: {
1995       ValType type;
1996       bool isMutable;
1997       if (!DecodeGlobalType(d, env->types, env->features, &type, &isMutable)) {
1998         return false;
1999       }
2000       if (!GlobalIsJSCompatible(d, type)) {
2001         return false;
2002       }
2003       if (!env->globals.append(
2004               GlobalDesc(type, isMutable, env->globals.length()))) {
2005         return false;
2006       }
2007       if (env->globals.length() > MaxGlobals) {
2008         return d.fail("too many globals");
2009       }
2010       break;
2011     }
2012 #ifdef ENABLE_WASM_EXCEPTIONS
2013     case DefinitionKind::Event: {
2014       EventKind eventKind;
2015       uint32_t funcTypeIndex;
2016       if (!DecodeEvent(d, env, &eventKind, &funcTypeIndex)) {
2017         return false;
2018       }
2019       const ValTypeVector& args = env->types[funcTypeIndex].funcType().args();
2020 #  ifdef WASM_PRIVATE_REFTYPES
2021       if (!EventIsJSCompatible(d, args)) {
2022         return false;
2023       }
2024 #  endif
2025       ValTypeVector eventArgs;
2026       if (!eventArgs.appendAll(args)) {
2027         return false;
2028       }
2029       if (!env->events.emplaceBack(eventKind, std::move(eventArgs))) {
2030         return false;
2031       }
2032       if (env->events.length() > MaxEvents) {
2033         return d.fail("too many events");
2034       }
2035       break;
2036     }
2037 #endif
2038     default:
2039       return d.fail("unsupported import kind");
2040   }
2041 
2042   return env->imports.emplaceBack(std::move(moduleName), std::move(funcName),
2043                                   importKind);
2044 }
2045 
DecodeImportSection(Decoder & d,ModuleEnvironment * env)2046 static bool DecodeImportSection(Decoder& d, ModuleEnvironment* env) {
2047   MaybeSectionRange range;
2048   if (!d.startSection(SectionId::Import, env, &range, "import")) {
2049     return false;
2050   }
2051   if (!range) {
2052     return true;
2053   }
2054 
2055   uint32_t numImports;
2056   if (!d.readVarU32(&numImports)) {
2057     return d.fail("failed to read number of imports");
2058   }
2059 
2060   if (numImports > MaxImports) {
2061     return d.fail("too many imports");
2062   }
2063 
2064   CStringPairSet dupSet;
2065   for (uint32_t i = 0; i < numImports; i++) {
2066     if (!DecodeImport(d, env, &dupSet)) {
2067       return false;
2068     }
2069   }
2070 
2071   if (!d.finishSection(*range, "import")) {
2072     return false;
2073   }
2074 
2075   // The global data offsets will be filled in by ModuleGenerator::init.
2076   if (!env->funcImportGlobalDataOffsets.resize(env->funcs.length())) {
2077     return false;
2078   }
2079 
2080   return true;
2081 }
2082 
DecodeFunctionSection(Decoder & d,ModuleEnvironment * env)2083 static bool DecodeFunctionSection(Decoder& d, ModuleEnvironment* env) {
2084   MaybeSectionRange range;
2085   if (!d.startSection(SectionId::Function, env, &range, "function")) {
2086     return false;
2087   }
2088   if (!range) {
2089     return true;
2090   }
2091 
2092   uint32_t numDefs;
2093   if (!d.readVarU32(&numDefs)) {
2094     return d.fail("expected number of function definitions");
2095   }
2096 
2097   CheckedInt<uint32_t> numFuncs = env->funcs.length();
2098   numFuncs += numDefs;
2099   if (!numFuncs.isValid() || numFuncs.value() > MaxFuncs) {
2100     return d.fail("too many functions");
2101   }
2102 
2103   if (!env->funcs.reserve(numFuncs.value())) {
2104     return false;
2105   }
2106 
2107   for (uint32_t i = 0; i < numDefs; i++) {
2108     uint32_t funcTypeIndex;
2109     if (!DecodeFuncTypeIndex(d, env->types, &funcTypeIndex)) {
2110       return false;
2111     }
2112     env->funcs.infallibleAppend(FuncDesc(&env->types.funcType(funcTypeIndex),
2113                                          &env->typeIds[funcTypeIndex],
2114                                          funcTypeIndex));
2115   }
2116 
2117   return d.finishSection(*range, "function");
2118 }
2119 
DecodeTableSection(Decoder & d,ModuleEnvironment * env)2120 static bool DecodeTableSection(Decoder& d, ModuleEnvironment* env) {
2121   MaybeSectionRange range;
2122   if (!d.startSection(SectionId::Table, env, &range, "table")) {
2123     return false;
2124   }
2125   if (!range) {
2126     return true;
2127   }
2128 
2129   uint32_t numTables;
2130   if (!d.readVarU32(&numTables)) {
2131     return d.fail("failed to read number of tables");
2132   }
2133 
2134   for (uint32_t i = 0; i < numTables; ++i) {
2135     if (!DecodeTableTypeAndLimits(d, env->features, env->types, &env->tables)) {
2136       return false;
2137     }
2138   }
2139 
2140   return d.finishSection(*range, "table");
2141 }
2142 
DecodeMemorySection(Decoder & d,ModuleEnvironment * env)2143 static bool DecodeMemorySection(Decoder& d, ModuleEnvironment* env) {
2144   MaybeSectionRange range;
2145   if (!d.startSection(SectionId::Memory, env, &range, "memory")) {
2146     return false;
2147   }
2148   if (!range) {
2149     return true;
2150   }
2151 
2152   uint32_t numMemories;
2153   if (!d.readVarU32(&numMemories)) {
2154     return d.fail("failed to read number of memories");
2155   }
2156 
2157   if (numMemories > 1) {
2158     return d.fail("the number of memories must be at most one");
2159   }
2160 
2161   for (uint32_t i = 0; i < numMemories; ++i) {
2162     if (!DecodeMemoryLimits(d, env)) {
2163       return false;
2164     }
2165   }
2166 
2167   return d.finishSection(*range, "memory");
2168 }
2169 
DecodeGlobalSection(Decoder & d,ModuleEnvironment * env)2170 static bool DecodeGlobalSection(Decoder& d, ModuleEnvironment* env) {
2171   MaybeSectionRange range;
2172   if (!d.startSection(SectionId::Global, env, &range, "global")) {
2173     return false;
2174   }
2175   if (!range) {
2176     return true;
2177   }
2178 
2179   uint32_t numDefs;
2180   if (!d.readVarU32(&numDefs)) {
2181     return d.fail("expected number of globals");
2182   }
2183 
2184   CheckedInt<uint32_t> numGlobals = env->globals.length();
2185   numGlobals += numDefs;
2186   if (!numGlobals.isValid() || numGlobals.value() > MaxGlobals) {
2187     return d.fail("too many globals");
2188   }
2189 
2190   if (!env->globals.reserve(numGlobals.value())) {
2191     return false;
2192   }
2193 
2194   for (uint32_t i = 0; i < numDefs; i++) {
2195     ValType type;
2196     bool isMutable;
2197     if (!DecodeGlobalType(d, env->types, env->features, &type, &isMutable)) {
2198       return false;
2199     }
2200 
2201     InitExpr initializer;
2202     if (!InitExpr::decodeAndValidate(d, env, type, &initializer)) {
2203       return false;
2204     }
2205 
2206     env->globals.infallibleAppend(
2207         GlobalDesc(std::move(initializer), isMutable));
2208   }
2209 
2210   return d.finishSection(*range, "global");
2211 }
2212 
2213 #ifdef ENABLE_WASM_EXCEPTIONS
DecodeEventSection(Decoder & d,ModuleEnvironment * env)2214 static bool DecodeEventSection(Decoder& d, ModuleEnvironment* env) {
2215   MaybeSectionRange range;
2216   if (!d.startSection(SectionId::Event, env, &range, "event")) {
2217     return false;
2218   }
2219   if (!range) {
2220     return true;
2221   }
2222 
2223   if (!env->exceptionsEnabled()) {
2224     return d.fail("exceptions not enabled");
2225   }
2226 
2227   uint32_t numDefs;
2228   if (!d.readVarU32(&numDefs)) {
2229     return d.fail("expected number of events");
2230   }
2231 
2232   CheckedInt<uint32_t> numEvents = env->events.length();
2233   numEvents += numDefs;
2234   if (!numEvents.isValid() || numEvents.value() > MaxEvents) {
2235     return d.fail("too many events");
2236   }
2237 
2238   if (!env->events.reserve(numEvents.value())) {
2239     return false;
2240   }
2241 
2242   for (uint32_t i = 0; i < numDefs; i++) {
2243     EventKind eventKind;
2244     uint32_t funcTypeIndex;
2245     if (!DecodeEvent(d, env, &eventKind, &funcTypeIndex)) {
2246       return false;
2247     }
2248     const ValTypeVector& args = env->types[funcTypeIndex].funcType().args();
2249     ValTypeVector eventArgs;
2250     if (!eventArgs.appendAll(args)) {
2251       return false;
2252     }
2253     env->events.infallibleEmplaceBack(eventKind, std::move(eventArgs));
2254   }
2255 
2256   return d.finishSection(*range, "event");
2257 }
2258 #endif
2259 
2260 using CStringSet =
2261     HashSet<const char*, mozilla::CStringHasher, SystemAllocPolicy>;
2262 
DecodeExportName(Decoder & d,CStringSet * dupSet)2263 static UniqueChars DecodeExportName(Decoder& d, CStringSet* dupSet) {
2264   UniqueChars exportName = DecodeName(d);
2265   if (!exportName) {
2266     d.fail("expected valid export name");
2267     return nullptr;
2268   }
2269 
2270   CStringSet::AddPtr p = dupSet->lookupForAdd(exportName.get());
2271   if (p) {
2272     d.fail("duplicate export");
2273     return nullptr;
2274   }
2275 
2276   if (!dupSet->add(p, exportName.get())) {
2277     return nullptr;
2278   }
2279 
2280   return exportName;
2281 }
2282 
DecodeExport(Decoder & d,ModuleEnvironment * env,CStringSet * dupSet)2283 static bool DecodeExport(Decoder& d, ModuleEnvironment* env,
2284                          CStringSet* dupSet) {
2285   UniqueChars fieldName = DecodeExportName(d, dupSet);
2286   if (!fieldName) {
2287     return false;
2288   }
2289 
2290   uint8_t exportKind;
2291   if (!d.readFixedU8(&exportKind)) {
2292     return d.fail("failed to read export kind");
2293   }
2294 
2295   switch (DefinitionKind(exportKind)) {
2296     case DefinitionKind::Function: {
2297       uint32_t funcIndex;
2298       if (!d.readVarU32(&funcIndex)) {
2299         return d.fail("expected function index");
2300       }
2301 
2302       if (funcIndex >= env->numFuncs()) {
2303         return d.fail("exported function index out of bounds");
2304       }
2305 #ifdef WASM_PRIVATE_REFTYPES
2306       if (!FuncTypeIsJSCompatible(d, *env->funcs[funcIndex].type)) {
2307         return false;
2308       }
2309 #endif
2310 
2311       env->declareFuncExported(funcIndex, /* eager */ true,
2312                                /* canRefFunc */ true);
2313       return env->exports.emplaceBack(std::move(fieldName), funcIndex,
2314                                       DefinitionKind::Function);
2315     }
2316     case DefinitionKind::Table: {
2317       uint32_t tableIndex;
2318       if (!d.readVarU32(&tableIndex)) {
2319         return d.fail("expected table index");
2320       }
2321 
2322       if (tableIndex >= env->tables.length()) {
2323         return d.fail("exported table index out of bounds");
2324       }
2325       env->tables[tableIndex].importedOrExported = true;
2326       return env->exports.emplaceBack(std::move(fieldName), tableIndex,
2327                                       DefinitionKind::Table);
2328     }
2329     case DefinitionKind::Memory: {
2330       uint32_t memoryIndex;
2331       if (!d.readVarU32(&memoryIndex)) {
2332         return d.fail("expected memory index");
2333       }
2334 
2335       if (memoryIndex > 0 || !env->usesMemory()) {
2336         return d.fail("exported memory index out of bounds");
2337       }
2338 
2339       return env->exports.emplaceBack(std::move(fieldName),
2340                                       DefinitionKind::Memory);
2341     }
2342     case DefinitionKind::Global: {
2343       uint32_t globalIndex;
2344       if (!d.readVarU32(&globalIndex)) {
2345         return d.fail("expected global index");
2346       }
2347 
2348       if (globalIndex >= env->globals.length()) {
2349         return d.fail("exported global index out of bounds");
2350       }
2351 
2352       GlobalDesc* global = &env->globals[globalIndex];
2353       global->setIsExport();
2354       if (!GlobalIsJSCompatible(d, global->type())) {
2355         return false;
2356       }
2357 
2358       return env->exports.emplaceBack(std::move(fieldName), globalIndex,
2359                                       DefinitionKind::Global);
2360     }
2361 #ifdef ENABLE_WASM_EXCEPTIONS
2362     case DefinitionKind::Event: {
2363       uint32_t eventIndex;
2364       if (!d.readVarU32(&eventIndex)) {
2365         return d.fail("expected event index");
2366       }
2367       if (eventIndex >= env->events.length()) {
2368         return d.fail("exported event index out of bounds");
2369       }
2370 
2371 #  ifdef WASM_PRIVATE_REFTYPES
2372       if (!EventIsJSCompatible(d, env->events[eventIndex].type)) {
2373         return false;
2374       }
2375 #  endif
2376 
2377       env->events[eventIndex].isExport = true;
2378       return env->exports.emplaceBack(std::move(fieldName), eventIndex,
2379                                       DefinitionKind::Event);
2380     }
2381 #endif
2382     default:
2383       return d.fail("unexpected export kind");
2384   }
2385 
2386   MOZ_CRASH("unreachable");
2387 }
2388 
DecodeExportSection(Decoder & d,ModuleEnvironment * env)2389 static bool DecodeExportSection(Decoder& d, ModuleEnvironment* env) {
2390   MaybeSectionRange range;
2391   if (!d.startSection(SectionId::Export, env, &range, "export")) {
2392     return false;
2393   }
2394   if (!range) {
2395     return true;
2396   }
2397 
2398   CStringSet dupSet;
2399 
2400   uint32_t numExports;
2401   if (!d.readVarU32(&numExports)) {
2402     return d.fail("failed to read number of exports");
2403   }
2404 
2405   if (numExports > MaxExports) {
2406     return d.fail("too many exports");
2407   }
2408 
2409   for (uint32_t i = 0; i < numExports; i++) {
2410     if (!DecodeExport(d, env, &dupSet)) {
2411       return false;
2412     }
2413   }
2414 
2415   return d.finishSection(*range, "export");
2416 }
2417 
DecodeStartSection(Decoder & d,ModuleEnvironment * env)2418 static bool DecodeStartSection(Decoder& d, ModuleEnvironment* env) {
2419   MaybeSectionRange range;
2420   if (!d.startSection(SectionId::Start, env, &range, "start")) {
2421     return false;
2422   }
2423   if (!range) {
2424     return true;
2425   }
2426 
2427   uint32_t funcIndex;
2428   if (!d.readVarU32(&funcIndex)) {
2429     return d.fail("failed to read start func index");
2430   }
2431 
2432   if (funcIndex >= env->numFuncs()) {
2433     return d.fail("unknown start function");
2434   }
2435 
2436   const FuncType& funcType = *env->funcs[funcIndex].type;
2437   if (funcType.results().length() > 0) {
2438     return d.fail("start function must not return anything");
2439   }
2440 
2441   if (funcType.args().length()) {
2442     return d.fail("start function must be nullary");
2443   }
2444 
2445   env->declareFuncExported(funcIndex, /* eager */ true, /* canFuncRef */ false);
2446   env->startFuncIndex = Some(funcIndex);
2447 
2448   return d.finishSection(*range, "start");
2449 }
2450 
NormalizeElemSegmentKind(ElemSegmentKind decodedKind)2451 static inline ElemSegment::Kind NormalizeElemSegmentKind(
2452     ElemSegmentKind decodedKind) {
2453   switch (decodedKind) {
2454     case ElemSegmentKind::Active:
2455     case ElemSegmentKind::ActiveWithTableIndex: {
2456       return ElemSegment::Kind::Active;
2457     }
2458     case ElemSegmentKind::Passive: {
2459       return ElemSegment::Kind::Passive;
2460     }
2461     case ElemSegmentKind::Declared: {
2462       return ElemSegment::Kind::Declared;
2463     }
2464   }
2465   MOZ_CRASH("unexpected elem segment kind");
2466 }
2467 
DecodeElemSection(Decoder & d,ModuleEnvironment * env)2468 static bool DecodeElemSection(Decoder& d, ModuleEnvironment* env) {
2469   MaybeSectionRange range;
2470   if (!d.startSection(SectionId::Elem, env, &range, "elem")) {
2471     return false;
2472   }
2473   if (!range) {
2474     return true;
2475   }
2476 
2477   uint32_t numSegments;
2478   if (!d.readVarU32(&numSegments)) {
2479     return d.fail("failed to read number of elem segments");
2480   }
2481 
2482   if (numSegments > MaxElemSegments) {
2483     return d.fail("too many elem segments");
2484   }
2485 
2486   if (!env->elemSegments.reserve(numSegments)) {
2487     return false;
2488   }
2489 
2490   for (uint32_t i = 0; i < numSegments; i++) {
2491     uint32_t segmentFlags;
2492     if (!d.readVarU32(&segmentFlags)) {
2493       return d.fail("expected elem segment flags field");
2494     }
2495 
2496     Maybe<ElemSegmentFlags> flags = ElemSegmentFlags::construct(segmentFlags);
2497     if (!flags) {
2498       return d.fail("invalid elem segment flags field");
2499     }
2500 
2501     MutableElemSegment seg = js_new<ElemSegment>();
2502     if (!seg) {
2503       return false;
2504     }
2505 
2506     ElemSegmentKind kind = flags->kind();
2507     seg->kind = NormalizeElemSegmentKind(kind);
2508 
2509     if (kind == ElemSegmentKind::Active ||
2510         kind == ElemSegmentKind::ActiveWithTableIndex) {
2511       if (env->tables.length() == 0) {
2512         return d.fail("active elem segment requires a table");
2513       }
2514 
2515       uint32_t tableIndex = 0;
2516       if (kind == ElemSegmentKind::ActiveWithTableIndex &&
2517           !d.readVarU32(&tableIndex)) {
2518         return d.fail("expected table index");
2519       }
2520       if (tableIndex >= env->tables.length()) {
2521         return d.fail("table index out of range for element segment");
2522       }
2523       seg->tableIndex = tableIndex;
2524 
2525       InitExpr offset;
2526       if (!InitExpr::decodeAndValidate(d, env, ValType::I32, &offset)) {
2527         return false;
2528       }
2529       seg->offsetIfActive.emplace(std::move(offset));
2530     } else {
2531       // Too many bugs result from keeping this value zero.  For passive
2532       // or declared segments, there really is no table index, and we should
2533       // never touch the field.
2534       MOZ_ASSERT(kind == ElemSegmentKind::Passive ||
2535                  kind == ElemSegmentKind::Declared);
2536       seg->tableIndex = (uint32_t)-1;
2537     }
2538 
2539     ElemSegmentPayload payload = flags->payload();
2540     RefType elemType;
2541 
2542     // `ActiveWithTableIndex`, `Declared`, and `Passive` element segments encode
2543     // the type or definition kind of the payload. `Active` element segments are
2544     // restricted to MVP behavior, which assumes only function indices.
2545     if (kind == ElemSegmentKind::Active) {
2546       elemType = RefType::func();
2547     } else {
2548       switch (payload) {
2549         case ElemSegmentPayload::ElemExpression: {
2550           if (!d.readRefType(env->types, env->features, &elemType)) {
2551             return false;
2552           }
2553           break;
2554         }
2555         case ElemSegmentPayload::ExternIndex: {
2556           uint8_t form;
2557           if (!d.readFixedU8(&form)) {
2558             return d.fail("expected type or extern kind");
2559           }
2560 
2561           if (form != uint8_t(DefinitionKind::Function)) {
2562             return d.fail(
2563                 "segments with extern indices can only contain function "
2564                 "references");
2565           }
2566           elemType = RefType::func();
2567         }
2568       }
2569     }
2570 
2571     // Check constraints on the element type.
2572     switch (kind) {
2573       case ElemSegmentKind::Active:
2574       case ElemSegmentKind::ActiveWithTableIndex: {
2575         RefType tblElemType = env->tables[seg->tableIndex].elemType;
2576         TypeCache cache;
2577         if (!CheckIsSubtypeOf(d, *env, d.currentOffset(), ValType(elemType),
2578                               ValType(tblElemType), &cache)) {
2579           return false;
2580         }
2581         break;
2582       }
2583       case ElemSegmentKind::Declared:
2584       case ElemSegmentKind::Passive: {
2585         // Passive segment element types are checked when used with a
2586         // `table.init` instruction.
2587         break;
2588       }
2589     }
2590     seg->elemType = elemType;
2591 
2592     uint32_t numElems;
2593     if (!d.readVarU32(&numElems)) {
2594       return d.fail("expected segment size");
2595     }
2596 
2597     if (numElems > MaxElemSegmentLength) {
2598       return d.fail("too many table elements");
2599     }
2600 
2601     if (!seg->elemFuncIndices.reserve(numElems)) {
2602       return false;
2603     }
2604 
2605 #ifdef WASM_PRIVATE_REFTYPES
2606     // We assume that passive or declared segments may be applied to external
2607     // tables. We can do slightly better: if there are no external tables in
2608     // the module then we don't need to worry about passive or declared
2609     // segments either. But this is a temporary restriction.
2610     bool exportedTable = kind == ElemSegmentKind::Passive ||
2611                          kind == ElemSegmentKind::Declared ||
2612                          env->tables[seg->tableIndex].importedOrExported;
2613 #endif
2614     bool isAsmJS = seg->active() && env->tables[seg->tableIndex].isAsmJS;
2615 
2616     // For passive segments we should use InitExpr but we don't really want to
2617     // generalize the ElemSection data structure yet, so instead read the
2618     // required Ref.Func and End here.
2619 
2620     TypeCache cache;
2621     for (uint32_t i = 0; i < numElems; i++) {
2622       bool needIndex = true;
2623 
2624       if (payload == ElemSegmentPayload::ElemExpression) {
2625         OpBytes op;
2626         if (!d.readOp(&op)) {
2627           return d.fail("failed to read initializer operation");
2628         }
2629 
2630         RefType initType = RefType::extern_();
2631         switch (op.b0) {
2632           case uint16_t(Op::RefFunc):
2633             initType = RefType::func();
2634             break;
2635           case uint16_t(Op::RefNull):
2636             if (!d.readHeapType(env->types, env->features, true, &initType)) {
2637               return false;
2638             }
2639             needIndex = false;
2640             break;
2641           default:
2642             return d.fail("failed to read initializer operation");
2643         }
2644         if (!CheckIsSubtypeOf(d, *env, d.currentOffset(), ValType(initType),
2645                               ValType(elemType), &cache)) {
2646           return false;
2647         }
2648       }
2649 
2650       uint32_t funcIndex = NullFuncIndex;
2651       if (needIndex) {
2652         if (!d.readVarU32(&funcIndex)) {
2653           return d.fail("failed to read element function index");
2654         }
2655         if (funcIndex >= env->numFuncs()) {
2656           return d.fail("table element out of range");
2657         }
2658 #ifdef WASM_PRIVATE_REFTYPES
2659         if (exportedTable &&
2660             !FuncTypeIsJSCompatible(d, *env->funcs[funcIndex].type)) {
2661           return false;
2662         }
2663 #endif
2664       }
2665 
2666       if (payload == ElemSegmentPayload::ElemExpression) {
2667         OpBytes end;
2668         if (!d.readOp(&end) || end.b0 != uint16_t(Op::End)) {
2669           return d.fail("failed to read end of initializer expression");
2670         }
2671       }
2672 
2673       seg->elemFuncIndices.infallibleAppend(funcIndex);
2674       if (funcIndex != NullFuncIndex && !isAsmJS) {
2675         env->declareFuncExported(funcIndex, /* eager */ false,
2676                                  /* canRefFunc */ true);
2677       }
2678     }
2679 
2680     env->elemSegments.infallibleAppend(std::move(seg));
2681   }
2682 
2683   return d.finishSection(*range, "elem");
2684 }
2685 
DecodeDataCountSection(Decoder & d,ModuleEnvironment * env)2686 static bool DecodeDataCountSection(Decoder& d, ModuleEnvironment* env) {
2687   MaybeSectionRange range;
2688   if (!d.startSection(SectionId::DataCount, env, &range, "datacount")) {
2689     return false;
2690   }
2691   if (!range) {
2692     return true;
2693   }
2694 
2695   uint32_t dataCount;
2696   if (!d.readVarU32(&dataCount)) {
2697     return d.fail("expected data segment count");
2698   }
2699 
2700   env->dataCount.emplace(dataCount);
2701 
2702   return d.finishSection(*range, "datacount");
2703 }
2704 
StartsCodeSection(const uint8_t * begin,const uint8_t * end,SectionRange * codeSection)2705 bool wasm::StartsCodeSection(const uint8_t* begin, const uint8_t* end,
2706                              SectionRange* codeSection) {
2707   UniqueChars unused;
2708   Decoder d(begin, end, 0, &unused);
2709 
2710   if (!DecodePreamble(d)) {
2711     return false;
2712   }
2713 
2714   while (!d.done()) {
2715     uint8_t id;
2716     SectionRange range;
2717     if (!d.readSectionHeader(&id, &range)) {
2718       return false;
2719     }
2720 
2721     if (id == uint8_t(SectionId::Code)) {
2722       *codeSection = range;
2723       return true;
2724     }
2725 
2726     if (!d.readBytes(range.size)) {
2727       return false;
2728     }
2729   }
2730 
2731   return false;
2732 }
2733 
DecodeModuleEnvironment(Decoder & d,ModuleEnvironment * env)2734 bool wasm::DecodeModuleEnvironment(Decoder& d, ModuleEnvironment* env) {
2735   if (!DecodePreamble(d)) {
2736     return false;
2737   }
2738 
2739   if (!DecodeTypeSection(d, env)) {
2740     return false;
2741   }
2742 
2743   if (!DecodeImportSection(d, env)) {
2744     return false;
2745   }
2746 
2747   if (!DecodeFunctionSection(d, env)) {
2748     return false;
2749   }
2750 
2751   if (!DecodeTableSection(d, env)) {
2752     return false;
2753   }
2754 
2755   if (!DecodeMemorySection(d, env)) {
2756     return false;
2757   }
2758 
2759 #ifdef ENABLE_WASM_EXCEPTIONS
2760   if (!DecodeEventSection(d, env)) {
2761     return false;
2762   }
2763 #endif
2764 
2765   if (!DecodeGlobalSection(d, env)) {
2766     return false;
2767   }
2768 
2769   if (!DecodeExportSection(d, env)) {
2770     return false;
2771   }
2772 
2773   if (!DecodeStartSection(d, env)) {
2774     return false;
2775   }
2776 
2777   if (!DecodeElemSection(d, env)) {
2778     return false;
2779   }
2780 
2781   if (!DecodeDataCountSection(d, env)) {
2782     return false;
2783   }
2784 
2785   if (!d.startSection(SectionId::Code, env, &env->codeSection, "code")) {
2786     return false;
2787   }
2788 
2789   if (env->codeSection && env->codeSection->size > MaxCodeSectionBytes) {
2790     return d.fail("code section too big");
2791   }
2792 
2793   return true;
2794 }
2795 
DecodeFunctionBody(Decoder & d,const ModuleEnvironment & env,uint32_t funcIndex)2796 static bool DecodeFunctionBody(Decoder& d, const ModuleEnvironment& env,
2797                                uint32_t funcIndex) {
2798   uint32_t bodySize;
2799   if (!d.readVarU32(&bodySize)) {
2800     return d.fail("expected number of function body bytes");
2801   }
2802 
2803   if (bodySize > MaxFunctionBytes) {
2804     return d.fail("function body too big");
2805   }
2806 
2807   if (d.bytesRemain() < bodySize) {
2808     return d.fail("function body length too big");
2809   }
2810 
2811   return ValidateFunctionBody(env, funcIndex, bodySize, d);
2812 }
2813 
DecodeCodeSection(Decoder & d,ModuleEnvironment * env)2814 static bool DecodeCodeSection(Decoder& d, ModuleEnvironment* env) {
2815   if (!env->codeSection) {
2816     if (env->numFuncDefs() != 0) {
2817       return d.fail("expected code section");
2818     }
2819     return true;
2820   }
2821 
2822   uint32_t numFuncDefs;
2823   if (!d.readVarU32(&numFuncDefs)) {
2824     return d.fail("expected function body count");
2825   }
2826 
2827   if (numFuncDefs != env->numFuncDefs()) {
2828     return d.fail(
2829         "function body count does not match function signature count");
2830   }
2831 
2832   for (uint32_t funcDefIndex = 0; funcDefIndex < numFuncDefs; funcDefIndex++) {
2833     if (!DecodeFunctionBody(d, *env, env->numFuncImports() + funcDefIndex)) {
2834       return false;
2835     }
2836   }
2837 
2838   return d.finishSection(*env->codeSection, "code");
2839 }
2840 
DecodeDataSection(Decoder & d,ModuleEnvironment * env)2841 static bool DecodeDataSection(Decoder& d, ModuleEnvironment* env) {
2842   MaybeSectionRange range;
2843   if (!d.startSection(SectionId::Data, env, &range, "data")) {
2844     return false;
2845   }
2846   if (!range) {
2847     if (env->dataCount.isSome() && *env->dataCount > 0) {
2848       return d.fail("number of data segments does not match declared count");
2849     }
2850     return true;
2851   }
2852 
2853   uint32_t numSegments;
2854   if (!d.readVarU32(&numSegments)) {
2855     return d.fail("failed to read number of data segments");
2856   }
2857 
2858   if (numSegments > MaxDataSegments) {
2859     return d.fail("too many data segments");
2860   }
2861 
2862   if (env->dataCount.isSome() && numSegments != *env->dataCount) {
2863     return d.fail("number of data segments does not match declared count");
2864   }
2865 
2866   for (uint32_t i = 0; i < numSegments; i++) {
2867     uint32_t initializerKindVal;
2868     if (!d.readVarU32(&initializerKindVal)) {
2869       return d.fail("expected data initializer-kind field");
2870     }
2871 
2872     switch (initializerKindVal) {
2873       case uint32_t(DataSegmentKind::Active):
2874       case uint32_t(DataSegmentKind::Passive):
2875       case uint32_t(DataSegmentKind::ActiveWithMemoryIndex):
2876         break;
2877       default:
2878         return d.fail("invalid data initializer-kind field");
2879     }
2880 
2881     DataSegmentKind initializerKind = DataSegmentKind(initializerKindVal);
2882 
2883     if (initializerKind != DataSegmentKind::Passive && !env->usesMemory()) {
2884       return d.fail("active data segment requires a memory section");
2885     }
2886 
2887     uint32_t memIndex = 0;
2888     if (initializerKind == DataSegmentKind::ActiveWithMemoryIndex) {
2889       if (!d.readVarU32(&memIndex)) {
2890         return d.fail("expected memory index");
2891       }
2892       if (memIndex > 0) {
2893         return d.fail("memory index must be zero");
2894       }
2895     }
2896 
2897     DataSegmentEnv seg;
2898     if (initializerKind == DataSegmentKind::Active ||
2899         initializerKind == DataSegmentKind::ActiveWithMemoryIndex) {
2900       InitExpr segOffset;
2901       if (!InitExpr::decodeAndValidate(d, env, ValType::I32, &segOffset)) {
2902         return false;
2903       }
2904       seg.offsetIfActive.emplace(std::move(segOffset));
2905     }
2906 
2907     if (!d.readVarU32(&seg.length)) {
2908       return d.fail("expected segment size");
2909     }
2910 
2911     if (seg.length > MaxDataSegmentLengthPages * PageSize) {
2912       return d.fail("segment size too big");
2913     }
2914 
2915     seg.bytecodeOffset = d.currentOffset();
2916 
2917     if (!d.readBytes(seg.length)) {
2918       return d.fail("data segment shorter than declared");
2919     }
2920 
2921     if (!env->dataSegments.append(std::move(seg))) {
2922       return false;
2923     }
2924   }
2925 
2926   return d.finishSection(*range, "data");
2927 }
2928 
DecodeModuleNameSubsection(Decoder & d,const CustomSectionEnv & nameSection,ModuleEnvironment * env)2929 static bool DecodeModuleNameSubsection(Decoder& d,
2930                                        const CustomSectionEnv& nameSection,
2931                                        ModuleEnvironment* env) {
2932   Maybe<uint32_t> endOffset;
2933   if (!d.startNameSubsection(NameType::Module, &endOffset)) {
2934     return false;
2935   }
2936   if (!endOffset) {
2937     return true;
2938   }
2939 
2940   Name moduleName;
2941   if (!d.readVarU32(&moduleName.length)) {
2942     return d.fail("failed to read module name length");
2943   }
2944 
2945   MOZ_ASSERT(d.currentOffset() >= nameSection.payloadOffset);
2946   moduleName.offsetInNamePayload =
2947       d.currentOffset() - nameSection.payloadOffset;
2948 
2949   const uint8_t* bytes;
2950   if (!d.readBytes(moduleName.length, &bytes)) {
2951     return d.fail("failed to read module name bytes");
2952   }
2953 
2954   if (!d.finishNameSubsection(*endOffset)) {
2955     return false;
2956   }
2957 
2958   // Only save the module name if the whole subsection validates.
2959   env->moduleName.emplace(moduleName);
2960   return true;
2961 }
2962 
DecodeFunctionNameSubsection(Decoder & d,const CustomSectionEnv & nameSection,ModuleEnvironment * env)2963 static bool DecodeFunctionNameSubsection(Decoder& d,
2964                                          const CustomSectionEnv& nameSection,
2965                                          ModuleEnvironment* env) {
2966   Maybe<uint32_t> endOffset;
2967   if (!d.startNameSubsection(NameType::Function, &endOffset)) {
2968     return false;
2969   }
2970   if (!endOffset) {
2971     return true;
2972   }
2973 
2974   uint32_t nameCount = 0;
2975   if (!d.readVarU32(&nameCount) || nameCount > MaxFuncs) {
2976     return d.fail("bad function name count");
2977   }
2978 
2979   NameVector funcNames;
2980 
2981   for (uint32_t i = 0; i < nameCount; ++i) {
2982     uint32_t funcIndex = 0;
2983     if (!d.readVarU32(&funcIndex)) {
2984       return d.fail("unable to read function index");
2985     }
2986 
2987     // Names must refer to real functions and be given in ascending order.
2988     if (funcIndex >= env->numFuncs() || funcIndex < funcNames.length()) {
2989       return d.fail("invalid function index");
2990     }
2991 
2992     Name funcName;
2993     if (!d.readVarU32(&funcName.length) ||
2994         funcName.length > JS::MaxStringLength) {
2995       return d.fail("unable to read function name length");
2996     }
2997 
2998     if (!funcName.length) {
2999       continue;
3000     }
3001 
3002     if (!funcNames.resize(funcIndex + 1)) {
3003       return false;
3004     }
3005 
3006     MOZ_ASSERT(d.currentOffset() >= nameSection.payloadOffset);
3007     funcName.offsetInNamePayload =
3008         d.currentOffset() - nameSection.payloadOffset;
3009 
3010     if (!d.readBytes(funcName.length)) {
3011       return d.fail("unable to read function name bytes");
3012     }
3013 
3014     funcNames[funcIndex] = funcName;
3015   }
3016 
3017   if (!d.finishNameSubsection(*endOffset)) {
3018     return false;
3019   }
3020 
3021   // To encourage fully valid function names subsections; only save names if
3022   // the entire subsection decoded correctly.
3023   env->funcNames = std::move(funcNames);
3024   return true;
3025 }
3026 
DecodeNameSection(Decoder & d,ModuleEnvironment * env)3027 static bool DecodeNameSection(Decoder& d, ModuleEnvironment* env) {
3028   MaybeSectionRange range;
3029   if (!d.startCustomSection(NameSectionName, env, &range)) {
3030     return false;
3031   }
3032   if (!range) {
3033     return true;
3034   }
3035 
3036   env->nameCustomSectionIndex = Some(env->customSections.length() - 1);
3037   const CustomSectionEnv& nameSection = env->customSections.back();
3038 
3039   // Once started, custom sections do not report validation errors.
3040 
3041   if (!DecodeModuleNameSubsection(d, nameSection, env)) {
3042     goto finish;
3043   }
3044 
3045   if (!DecodeFunctionNameSubsection(d, nameSection, env)) {
3046     goto finish;
3047   }
3048 
3049   while (d.currentOffset() < range->end()) {
3050     if (!d.skipNameSubsection()) {
3051       goto finish;
3052     }
3053   }
3054 
3055 finish:
3056   d.finishCustomSection(NameSectionName, *range);
3057   return true;
3058 }
3059 
DecodeModuleTail(Decoder & d,ModuleEnvironment * env)3060 bool wasm::DecodeModuleTail(Decoder& d, ModuleEnvironment* env) {
3061   if (!DecodeDataSection(d, env)) {
3062     return false;
3063   }
3064 
3065   if (!DecodeNameSection(d, env)) {
3066     return false;
3067   }
3068 
3069   while (!d.done()) {
3070     if (!d.skipCustomSection(env)) {
3071       if (d.resilientMode()) {
3072         d.clearError();
3073         return true;
3074       }
3075       return false;
3076     }
3077   }
3078 
3079   return true;
3080 }
3081 
3082 // Validate algorithm.
3083 
Validate(JSContext * cx,const ShareableBytes & bytecode,const FeatureOptions & options,UniqueChars * error)3084 bool wasm::Validate(JSContext* cx, const ShareableBytes& bytecode,
3085                     const FeatureOptions& options, UniqueChars* error) {
3086   Decoder d(bytecode.bytes, 0, error);
3087 
3088   FeatureArgs features = FeatureArgs::build(cx, options);
3089   ModuleEnvironment env(features);
3090   if (!DecodeModuleEnvironment(d, &env)) {
3091     return false;
3092   }
3093 
3094   if (!DecodeCodeSection(d, &env)) {
3095     return false;
3096   }
3097 
3098   if (!DecodeModuleTail(d, &env)) {
3099     return false;
3100   }
3101 
3102   MOZ_ASSERT(!*error, "unreported error in decoding");
3103   return true;
3104 }
3105