1 /*
2  * Copyright 2016 WebAssembly Community Group participants
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/binary-reader-ir.h"
18 
19 #include <cassert>
20 #include <cinttypes>
21 #include <cstdarg>
22 #include <cstdint>
23 #include <cstdio>
24 #include <vector>
25 
26 #include "src/binary-reader-nop.h"
27 #include "src/cast.h"
28 #include "src/common.h"
29 #include "src/ir.h"
30 
31 namespace wabt {
32 
33 namespace {
34 
35 struct LabelNode {
36   LabelNode(LabelType, ExprList* exprs, Expr* context = nullptr);
37 
38   LabelType label_type;
39   ExprList* exprs;
40   Expr* context;
41 };
42 
LabelNode(LabelType label_type,ExprList * exprs,Expr * context)43 LabelNode::LabelNode(LabelType label_type, ExprList* exprs, Expr* context)
44     : label_type(label_type), exprs(exprs), context(context) {}
45 
46 class BinaryReaderIR : public BinaryReaderNop {
47  public:
48   BinaryReaderIR(Module* out_module,
49                  const char* filename,
50                  Errors* errors);
51 
52   bool OnError(const Error&) override;
53 
54   Result OnTypeCount(Index count) override;
55   Result OnFuncType(Index index,
56                     Index param_count,
57                     Type* param_types,
58                     Index result_count,
59                     Type* result_types) override;
60   Result OnStructType(Index index, Index field_count, TypeMut* fields) override;
61   Result OnArrayType(Index index, TypeMut field) override;
62 
63   Result OnImportCount(Index count) override;
64   Result OnImportFunc(Index import_index,
65                       string_view module_name,
66                       string_view field_name,
67                       Index func_index,
68                       Index sig_index) override;
69   Result OnImportTable(Index import_index,
70                        string_view module_name,
71                        string_view field_name,
72                        Index table_index,
73                        Type elem_type,
74                        const Limits* elem_limits) override;
75   Result OnImportMemory(Index import_index,
76                         string_view module_name,
77                         string_view field_name,
78                         Index memory_index,
79                         const Limits* page_limits) override;
80   Result OnImportGlobal(Index import_index,
81                         string_view module_name,
82                         string_view field_name,
83                         Index global_index,
84                         Type type,
85                         bool mutable_) override;
86   Result OnImportTag(Index import_index,
87                      string_view module_name,
88                      string_view field_name,
89                      Index tag_index,
90                      Index sig_index) override;
91 
92   Result OnFunctionCount(Index count) override;
93   Result OnFunction(Index index, Index sig_index) override;
94 
95   Result OnTableCount(Index count) override;
96   Result OnTable(Index index,
97                  Type elem_type,
98                  const Limits* elem_limits) override;
99 
100   Result OnMemoryCount(Index count) override;
101   Result OnMemory(Index index, const Limits* limits) override;
102 
103   Result OnGlobalCount(Index count) override;
104   Result BeginGlobal(Index index, Type type, bool mutable_) override;
105   Result BeginGlobalInitExpr(Index index) override;
106   Result EndGlobalInitExpr(Index index) override;
107 
108   Result OnExportCount(Index count) override;
109   Result OnExport(Index index,
110                   ExternalKind kind,
111                   Index item_index,
112                   string_view name) override;
113 
114   Result OnStartFunction(Index func_index) override;
115 
116   Result OnFunctionBodyCount(Index count) override;
117   Result BeginFunctionBody(Index index, Offset size) override;
118   Result OnLocalDecl(Index decl_index, Index count, Type type) override;
119 
120   Result OnAtomicLoadExpr(Opcode opcode,
121                           Address alignment_log2,
122                           Address offset) override;
123   Result OnAtomicStoreExpr(Opcode opcode,
124                            Address alignment_log2,
125                            Address offset) override;
126   Result OnAtomicRmwExpr(Opcode opcode,
127                          Address alignment_log2,
128                          Address offset) override;
129   Result OnAtomicRmwCmpxchgExpr(Opcode opcode,
130                                 Address alignment_log2,
131                                 Address offset) override;
132   Result OnAtomicWaitExpr(Opcode opcode,
133                           Address alignment_log2,
134                           Address offset) override;
135   Result OnAtomicFenceExpr(uint32_t consistency_model) override;
136   Result OnAtomicNotifyExpr(Opcode opcode,
137                             Address alignment_log2,
138                             Address offset) override;
139   Result OnBinaryExpr(Opcode opcode) override;
140   Result OnBlockExpr(Type sig_type) override;
141   Result OnBrExpr(Index depth) override;
142   Result OnBrIfExpr(Index depth) override;
143   Result OnBrTableExpr(Index num_targets,
144                        Index* target_depths,
145                        Index default_target_depth) override;
146   Result OnCallExpr(Index func_index) override;
147   Result OnCatchExpr(Index tag_index) override;
148   Result OnCatchAllExpr() override;
149   Result OnCallIndirectExpr(Index sig_index, Index table_index) override;
150   Result OnCallRefExpr() override;
151   Result OnReturnCallExpr(Index func_index) override;
152   Result OnReturnCallIndirectExpr(Index sig_index, Index table_index) override;
153   Result OnCompareExpr(Opcode opcode) override;
154   Result OnConvertExpr(Opcode opcode) override;
155   Result OnDelegateExpr(Index depth) override;
156   Result OnDropExpr() override;
157   Result OnElseExpr() override;
158   Result OnEndExpr() override;
159   Result OnF32ConstExpr(uint32_t value_bits) override;
160   Result OnF64ConstExpr(uint64_t value_bits) override;
161   Result OnV128ConstExpr(v128 value_bits) override;
162   Result OnGlobalGetExpr(Index global_index) override;
163   Result OnGlobalSetExpr(Index global_index) override;
164   Result OnI32ConstExpr(uint32_t value) override;
165   Result OnI64ConstExpr(uint64_t value) override;
166   Result OnIfExpr(Type sig_type) override;
167   Result OnLoadExpr(Opcode opcode,
168                     Address alignment_log2,
169                     Address offset) override;
170   Result OnLocalGetExpr(Index local_index) override;
171   Result OnLocalSetExpr(Index local_index) override;
172   Result OnLocalTeeExpr(Index local_index) override;
173   Result OnLoopExpr(Type sig_type) override;
174   Result OnMemoryCopyExpr() override;
175   Result OnDataDropExpr(Index segment_index) override;
176   Result OnMemoryFillExpr() override;
177   Result OnMemoryGrowExpr() override;
178   Result OnMemoryInitExpr(Index segment_index) override;
179   Result OnMemorySizeExpr() override;
180   Result OnTableCopyExpr(Index dst_index, Index src_index) override;
181   Result OnElemDropExpr(Index segment_index) override;
182   Result OnTableInitExpr(Index segment_index, Index table_index) override;
183   Result OnTableGetExpr(Index table_index) override;
184   Result OnTableSetExpr(Index table_index) override;
185   Result OnTableGrowExpr(Index table_index) override;
186   Result OnTableSizeExpr(Index table_index) override;
187   Result OnTableFillExpr(Index table_index) override;
188   Result OnRefFuncExpr(Index func_index) override;
189   Result OnRefNullExpr(Type type) override;
190   Result OnRefIsNullExpr() override;
191   Result OnNopExpr() override;
192   Result OnRethrowExpr(Index depth) override;
193   Result OnReturnExpr() override;
194   Result OnSelectExpr(Index result_count, Type* result_types) override;
195   Result OnStoreExpr(Opcode opcode,
196                      Address alignment_log2,
197                      Address offset) override;
198   Result OnThrowExpr(Index tag_index) override;
199   Result OnTryExpr(Type sig_type) override;
200   Result OnUnaryExpr(Opcode opcode) override;
201   Result OnTernaryExpr(Opcode opcode) override;
202   Result OnUnreachableExpr() override;
203   Result EndFunctionBody(Index index) override;
204   Result OnSimdLaneOpExpr(Opcode opcode, uint64_t value) override;
205   Result OnSimdLoadLaneExpr(Opcode opcode,
206                             Address alignment_log2,
207                             Address offset,
208                             uint64_t value) override;
209   Result OnSimdStoreLaneExpr(Opcode opcode,
210                              Address alignment_log2,
211                              Address offset,
212                              uint64_t value) override;
213   Result OnSimdShuffleOpExpr(Opcode opcode, v128 value) override;
214   Result OnLoadSplatExpr(Opcode opcode,
215                          Address alignment_log2,
216                          Address offset) override;
217   Result OnLoadZeroExpr(Opcode opcode,
218                         Address alignment_log2,
219                         Address offset) override;
220 
221   Result OnElemSegmentCount(Index count) override;
222   Result BeginElemSegment(Index index,
223                           Index table_index,
224                           uint8_t flags) override;
225   Result BeginElemSegmentInitExpr(Index index) override;
226   Result EndElemSegmentInitExpr(Index index) override;
227   Result OnElemSegmentElemType(Index index, Type elem_type) override;
228   Result OnElemSegmentElemExprCount(Index index, Index count) override;
229   Result OnElemSegmentElemExpr_RefNull(Index segment_index, Type type) override;
230   Result OnElemSegmentElemExpr_RefFunc(Index segment_index,
231                                        Index func_index) override;
232 
233   Result OnDataSegmentCount(Index count) override;
234   Result BeginDataSegment(Index index,
235                           Index memory_index,
236                           uint8_t flags) override;
237   Result BeginDataSegmentInitExpr(Index index) override;
238   Result EndDataSegmentInitExpr(Index index) override;
239   Result OnDataSegmentData(Index index,
240                            const void* data,
241                            Address size) override;
242 
243   Result OnModuleName(string_view module_name) override;
244   Result OnFunctionNamesCount(Index num_functions) override;
245   Result OnFunctionName(Index function_index,
246                         string_view function_name) override;
247   Result OnLocalNameLocalCount(Index function_index, Index num_locals) override;
248   Result OnLocalName(Index function_index,
249                      Index local_index,
250                      string_view local_name) override;
251   Result OnNameEntry(NameSectionSubsection type,
252                      Index index,
253                      string_view name) override;
254 
BeginTagSection(Offset size)255   Result BeginTagSection(Offset size) override { return Result::Ok; }
OnTagCount(Index count)256   Result OnTagCount(Index count) override { return Result::Ok; }
257   Result OnTagType(Index index, Index sig_index) override;
EndTagSection()258   Result EndTagSection() override { return Result::Ok; }
259 
260   Result OnInitExprF32ConstExpr(Index index, uint32_t value) override;
261   Result OnInitExprF64ConstExpr(Index index, uint64_t value) override;
262   Result OnInitExprV128ConstExpr(Index index, v128 value) override;
263   Result OnInitExprGlobalGetExpr(Index index, Index global_index) override;
264   Result OnInitExprI32ConstExpr(Index index, uint32_t value) override;
265   Result OnInitExprI64ConstExpr(Index index, uint64_t value) override;
266   Result OnInitExprRefNull(Index index, Type type) override;
267   Result OnInitExprRefFunc(Index index, Index func_index) override;
268 
269   Result OnDataSymbol(Index index, uint32_t flags, string_view name,
270                        Index segment, uint32_t offset, uint32_t size) override;
271   Result OnFunctionSymbol(Index index, uint32_t flags, string_view name,
272                            Index func_index) override;
273   Result OnGlobalSymbol(Index index, uint32_t flags, string_view name,
274                          Index global_index) override;
275   Result OnSectionSymbol(Index index, uint32_t flags,
276                           Index section_index) override;
277   Result OnTagSymbol(Index index,
278                      uint32_t flags,
279                      string_view name,
280                      Index tag_index) override;
281   Result OnTableSymbol(Index index, uint32_t flags, string_view name,
282                        Index table_index) override;
283 
284  private:
285   Location GetLocation() const;
286   void PrintError(const char* format, ...);
287   void PushLabel(LabelType label_type,
288                  ExprList* first,
289                  Expr* context = nullptr);
290   Result PopLabel();
291   Result GetLabelAt(LabelNode** label, Index depth);
292   Result TopLabel(LabelNode** label);
293   Result TopLabelExpr(LabelNode** label, Expr** expr);
294   Result AppendExpr(std::unique_ptr<Expr> expr);
295   Result AppendCatch(Catch&& catch_);
296   void SetFuncDeclaration(FuncDeclaration* decl, Var var);
297   void SetBlockDeclaration(BlockDeclaration* decl, Type sig_type);
298   Result SetMemoryName(Index index, string_view name);
299   Result SetTableName(Index index, string_view name);
300   Result SetFunctionName(Index index, string_view name);
301   Result SetGlobalName(Index index, string_view name);
302   Result SetDataSegmentName(Index index, string_view name);
303   Result SetElemSegmentName(Index index, string_view name);
304 
305   std::string GetUniqueName(BindingHash* bindings,
306                             const std::string& original_name);
307 
308   Errors* errors_ = nullptr;
309   Module* module_ = nullptr;
310 
311   Func* current_func_ = nullptr;
312   std::vector<LabelNode> label_stack_;
313   ExprList* current_init_expr_ = nullptr;
314   const char* filename_;
315 };
316 
BinaryReaderIR(Module * out_module,const char * filename,Errors * errors)317 BinaryReaderIR::BinaryReaderIR(Module* out_module,
318                                const char* filename,
319                                Errors* errors)
320     : errors_(errors), module_(out_module), filename_(filename) {}
321 
GetLocation() const322 Location BinaryReaderIR::GetLocation() const {
323   Location loc;
324   loc.filename = filename_;
325   loc.offset = state->offset;
326   return loc;
327 }
328 
PrintError(const char * format,...)329 void WABT_PRINTF_FORMAT(2, 3) BinaryReaderIR::PrintError(const char* format,
330                                                          ...) {
331   WABT_SNPRINTF_ALLOCA(buffer, length, format);
332   errors_->emplace_back(ErrorLevel::Error, Location(kInvalidOffset), buffer);
333 }
334 
PushLabel(LabelType label_type,ExprList * first,Expr * context)335 void BinaryReaderIR::PushLabel(LabelType label_type,
336                                ExprList* first,
337                                Expr* context) {
338   label_stack_.emplace_back(label_type, first, context);
339 }
340 
PopLabel()341 Result BinaryReaderIR::PopLabel() {
342   if (label_stack_.size() == 0) {
343     PrintError("popping empty label stack");
344     return Result::Error;
345   }
346 
347   label_stack_.pop_back();
348   return Result::Ok;
349 }
350 
GetLabelAt(LabelNode ** label,Index depth)351 Result BinaryReaderIR::GetLabelAt(LabelNode** label, Index depth) {
352   if (depth >= label_stack_.size()) {
353     PrintError("accessing stack depth: %" PRIindex " >= max: %" PRIzd, depth,
354                label_stack_.size());
355     return Result::Error;
356   }
357 
358   *label = &label_stack_[label_stack_.size() - depth - 1];
359   return Result::Ok;
360 }
361 
TopLabel(LabelNode ** label)362 Result BinaryReaderIR::TopLabel(LabelNode** label) {
363   return GetLabelAt(label, 0);
364 }
365 
TopLabelExpr(LabelNode ** label,Expr ** expr)366 Result BinaryReaderIR::TopLabelExpr(LabelNode** label, Expr** expr) {
367   CHECK_RESULT(TopLabel(label));
368   LabelNode* parent_label;
369   CHECK_RESULT(GetLabelAt(&parent_label, 1));
370   *expr = &parent_label->exprs->back();
371   return Result::Ok;
372 }
373 
AppendExpr(std::unique_ptr<Expr> expr)374 Result BinaryReaderIR::AppendExpr(std::unique_ptr<Expr> expr) {
375   expr->loc = GetLocation();
376   LabelNode* label;
377   CHECK_RESULT(TopLabel(&label));
378   label->exprs->push_back(std::move(expr));
379   return Result::Ok;
380 }
381 
SetFuncDeclaration(FuncDeclaration * decl,Var var)382 void BinaryReaderIR::SetFuncDeclaration(FuncDeclaration* decl, Var var) {
383   decl->has_func_type = true;
384   decl->type_var = var;
385   if (auto* func_type = module_->GetFuncType(var)) {
386     decl->sig = func_type->sig;
387   }
388 }
389 
SetBlockDeclaration(BlockDeclaration * decl,Type sig_type)390 void BinaryReaderIR::SetBlockDeclaration(BlockDeclaration* decl,
391                                          Type sig_type) {
392   if (sig_type.IsIndex()) {
393     Index type_index = sig_type.GetIndex();
394     SetFuncDeclaration(decl, Var(type_index));
395   } else {
396     decl->has_func_type = false;
397     decl->sig.param_types.clear();
398     decl->sig.result_types = sig_type.GetInlineVector();
399   }
400 }
401 
GetUniqueName(BindingHash * bindings,const std::string & orig_name)402 std::string BinaryReaderIR::GetUniqueName(BindingHash* bindings,
403                                           const std::string& orig_name) {
404   int counter = 1;
405   std::string unique_name = orig_name;
406   while (bindings->count(unique_name) != 0) {
407     unique_name = orig_name + "." + std::to_string(counter++);
408   }
409   return unique_name;
410 }
411 
OnError(const Error & error)412 bool BinaryReaderIR::OnError(const Error& error) {
413   errors_->push_back(error);
414   return true;
415 }
416 
OnTypeCount(Index count)417 Result BinaryReaderIR::OnTypeCount(Index count) {
418   WABT_TRY
419   module_->types.reserve(count);
420   WABT_CATCH_BAD_ALLOC
421   return Result::Ok;
422 }
423 
OnFuncType(Index index,Index param_count,Type * param_types,Index result_count,Type * result_types)424 Result BinaryReaderIR::OnFuncType(Index index,
425                                   Index param_count,
426                                   Type* param_types,
427                                   Index result_count,
428                                   Type* result_types) {
429   auto field = MakeUnique<TypeModuleField>(GetLocation());
430   auto func_type = MakeUnique<FuncType>();
431   func_type->sig.param_types.assign(param_types, param_types + param_count);
432   func_type->sig.result_types.assign(result_types, result_types + result_count);
433   field->type = std::move(func_type);
434   module_->AppendField(std::move(field));
435   return Result::Ok;
436 }
437 
OnStructType(Index index,Index field_count,TypeMut * fields)438 Result BinaryReaderIR::OnStructType(Index index,
439                                     Index field_count,
440                                     TypeMut* fields) {
441   auto field = MakeUnique<TypeModuleField>(GetLocation());
442   auto struct_type = MakeUnique<StructType>();
443   struct_type->fields.resize(field_count);
444   for (Index i = 0; i < field_count; ++i) {
445     struct_type->fields[i].type = fields[i].type;
446     struct_type->fields[i].mutable_ = fields[i].mutable_;
447   }
448   field->type = std::move(struct_type);
449   module_->AppendField(std::move(field));
450   return Result::Ok;
451 }
452 
OnArrayType(Index index,TypeMut type_mut)453 Result BinaryReaderIR::OnArrayType(Index index, TypeMut type_mut) {
454   auto field = MakeUnique<TypeModuleField>(GetLocation());
455   auto array_type = MakeUnique<ArrayType>();
456   array_type->field.type = type_mut.type;
457   array_type->field.mutable_ = type_mut.mutable_;
458   field->type = std::move(array_type);
459   module_->AppendField(std::move(field));
460   return Result::Ok;
461 }
462 
OnImportCount(Index count)463 Result BinaryReaderIR::OnImportCount(Index count) {
464   WABT_TRY
465   module_->imports.reserve(count);
466   WABT_CATCH_BAD_ALLOC
467   return Result::Ok;
468 }
469 
OnImportFunc(Index import_index,string_view module_name,string_view field_name,Index func_index,Index sig_index)470 Result BinaryReaderIR::OnImportFunc(Index import_index,
471                                     string_view module_name,
472                                     string_view field_name,
473                                     Index func_index,
474                                     Index sig_index) {
475   auto import = MakeUnique<FuncImport>();
476   import->module_name = module_name.to_string();
477   import->field_name = field_name.to_string();
478   SetFuncDeclaration(&import->func.decl, Var(sig_index, GetLocation()));
479   module_->AppendField(
480       MakeUnique<ImportModuleField>(std::move(import), GetLocation()));
481   return Result::Ok;
482 }
483 
OnImportTable(Index import_index,string_view module_name,string_view field_name,Index table_index,Type elem_type,const Limits * elem_limits)484 Result BinaryReaderIR::OnImportTable(Index import_index,
485                                      string_view module_name,
486                                      string_view field_name,
487                                      Index table_index,
488                                      Type elem_type,
489                                      const Limits* elem_limits) {
490   auto import = MakeUnique<TableImport>();
491   import->module_name = module_name.to_string();
492   import->field_name = field_name.to_string();
493   import->table.elem_limits = *elem_limits;
494   import->table.elem_type = elem_type;
495   module_->AppendField(
496       MakeUnique<ImportModuleField>(std::move(import), GetLocation()));
497   return Result::Ok;
498 }
499 
OnImportMemory(Index import_index,string_view module_name,string_view field_name,Index memory_index,const Limits * page_limits)500 Result BinaryReaderIR::OnImportMemory(Index import_index,
501                                       string_view module_name,
502                                       string_view field_name,
503                                       Index memory_index,
504                                       const Limits* page_limits) {
505   auto import = MakeUnique<MemoryImport>();
506   import->module_name = module_name.to_string();
507   import->field_name = field_name.to_string();
508   import->memory.page_limits = *page_limits;
509   module_->AppendField(
510       MakeUnique<ImportModuleField>(std::move(import), GetLocation()));
511   return Result::Ok;
512 }
513 
OnImportGlobal(Index import_index,string_view module_name,string_view field_name,Index global_index,Type type,bool mutable_)514 Result BinaryReaderIR::OnImportGlobal(Index import_index,
515                                       string_view module_name,
516                                       string_view field_name,
517                                       Index global_index,
518                                       Type type,
519                                       bool mutable_) {
520   auto import = MakeUnique<GlobalImport>();
521   import->module_name = module_name.to_string();
522   import->field_name = field_name.to_string();
523   import->global.type = type;
524   import->global.mutable_ = mutable_;
525   module_->AppendField(
526       MakeUnique<ImportModuleField>(std::move(import), GetLocation()));
527   return Result::Ok;
528 }
529 
OnImportTag(Index import_index,string_view module_name,string_view field_name,Index tag_index,Index sig_index)530 Result BinaryReaderIR::OnImportTag(Index import_index,
531                                    string_view module_name,
532                                    string_view field_name,
533                                    Index tag_index,
534                                    Index sig_index) {
535   auto import = MakeUnique<TagImport>();
536   import->module_name = module_name.to_string();
537   import->field_name = field_name.to_string();
538   SetFuncDeclaration(&import->tag.decl, Var(sig_index, GetLocation()));
539   module_->AppendField(
540       MakeUnique<ImportModuleField>(std::move(import), GetLocation()));
541   return Result::Ok;
542 }
543 
OnFunctionCount(Index count)544 Result BinaryReaderIR::OnFunctionCount(Index count) {
545   WABT_TRY
546   module_->funcs.reserve(module_->num_func_imports + count);
547   WABT_CATCH_BAD_ALLOC
548   return Result::Ok;
549 }
550 
OnFunction(Index index,Index sig_index)551 Result BinaryReaderIR::OnFunction(Index index, Index sig_index) {
552   auto field = MakeUnique<FuncModuleField>(GetLocation());
553   Func& func = field->func;
554   SetFuncDeclaration(&func.decl, Var(sig_index, GetLocation()));
555   module_->AppendField(std::move(field));
556   return Result::Ok;
557 }
558 
OnTableCount(Index count)559 Result BinaryReaderIR::OnTableCount(Index count) {
560   WABT_TRY
561   module_->tables.reserve(module_->num_table_imports + count);
562   WABT_CATCH_BAD_ALLOC
563   return Result::Ok;
564 }
565 
OnTable(Index index,Type elem_type,const Limits * elem_limits)566 Result BinaryReaderIR::OnTable(Index index,
567                                Type elem_type,
568                                const Limits* elem_limits) {
569   auto field = MakeUnique<TableModuleField>(GetLocation());
570   Table& table = field->table;
571   table.elem_limits = *elem_limits;
572   table.elem_type = elem_type;
573   module_->AppendField(std::move(field));
574   return Result::Ok;
575 }
576 
OnMemoryCount(Index count)577 Result BinaryReaderIR::OnMemoryCount(Index count) {
578   WABT_TRY
579   module_->memories.reserve(module_->num_memory_imports + count);
580   WABT_CATCH_BAD_ALLOC
581   return Result::Ok;
582 }
583 
OnMemory(Index index,const Limits * page_limits)584 Result BinaryReaderIR::OnMemory(Index index, const Limits* page_limits) {
585   auto field = MakeUnique<MemoryModuleField>(GetLocation());
586   Memory& memory = field->memory;
587   memory.page_limits = *page_limits;
588   module_->AppendField(std::move(field));
589   return Result::Ok;
590 }
591 
OnGlobalCount(Index count)592 Result BinaryReaderIR::OnGlobalCount(Index count) {
593   WABT_TRY
594   module_->globals.reserve(module_->num_global_imports + count);
595   WABT_CATCH_BAD_ALLOC
596   return Result::Ok;
597 }
598 
BeginGlobal(Index index,Type type,bool mutable_)599 Result BinaryReaderIR::BeginGlobal(Index index, Type type, bool mutable_) {
600   auto field = MakeUnique<GlobalModuleField>(GetLocation());
601   Global& global = field->global;
602   global.type = type;
603   global.mutable_ = mutable_;
604   module_->AppendField(std::move(field));
605   return Result::Ok;
606 }
607 
BeginGlobalInitExpr(Index index)608 Result BinaryReaderIR::BeginGlobalInitExpr(Index index) {
609   assert(index == module_->globals.size() - 1);
610   Global* global = module_->globals[index];
611   current_init_expr_ = &global->init_expr;
612   return Result::Ok;
613 }
614 
EndGlobalInitExpr(Index index)615 Result BinaryReaderIR::EndGlobalInitExpr(Index index) {
616   current_init_expr_ = nullptr;
617   return Result::Ok;
618 }
619 
OnExportCount(Index count)620 Result BinaryReaderIR::OnExportCount(Index count) {
621   WABT_TRY
622   module_->exports.reserve(count);
623   WABT_CATCH_BAD_ALLOC
624   return Result::Ok;
625 }
626 
OnExport(Index index,ExternalKind kind,Index item_index,string_view name)627 Result BinaryReaderIR::OnExport(Index index,
628                                 ExternalKind kind,
629                                 Index item_index,
630                                 string_view name) {
631   auto field = MakeUnique<ExportModuleField>(GetLocation());
632   Export& export_ = field->export_;
633   export_.name = name.to_string();
634   export_.var = Var(item_index, GetLocation());
635   export_.kind = kind;
636   module_->AppendField(std::move(field));
637   return Result::Ok;
638 }
639 
OnStartFunction(Index func_index)640 Result BinaryReaderIR::OnStartFunction(Index func_index) {
641   Var start(func_index, GetLocation());
642   module_->AppendField(MakeUnique<StartModuleField>(start, GetLocation()));
643   return Result::Ok;
644 }
645 
OnFunctionBodyCount(Index count)646 Result BinaryReaderIR::OnFunctionBodyCount(Index count) {
647   assert(module_->num_func_imports + count == module_->funcs.size());
648   return Result::Ok;
649 }
650 
BeginFunctionBody(Index index,Offset size)651 Result BinaryReaderIR::BeginFunctionBody(Index index, Offset size) {
652   current_func_ = module_->funcs[index];
653   PushLabel(LabelType::Func, &current_func_->exprs);
654   return Result::Ok;
655 }
656 
OnLocalDecl(Index decl_index,Index count,Type type)657 Result BinaryReaderIR::OnLocalDecl(Index decl_index, Index count, Type type) {
658   current_func_->local_types.AppendDecl(type, count);
659   return Result::Ok;
660 }
661 
OnAtomicLoadExpr(Opcode opcode,Address alignment_log2,Address offset)662 Result BinaryReaderIR::OnAtomicLoadExpr(Opcode opcode,
663                                         Address alignment_log2,
664                                         Address offset) {
665   return AppendExpr(
666       MakeUnique<AtomicLoadExpr>(opcode, 1 << alignment_log2, offset));
667 }
668 
OnAtomicStoreExpr(Opcode opcode,Address alignment_log2,Address offset)669 Result BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode,
670                                          Address alignment_log2,
671                                          Address offset) {
672   return AppendExpr(
673       MakeUnique<AtomicStoreExpr>(opcode, 1 << alignment_log2, offset));
674 }
675 
OnAtomicRmwExpr(Opcode opcode,Address alignment_log2,Address offset)676 Result BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode,
677                                        Address alignment_log2,
678                                        Address offset) {
679   return AppendExpr(
680       MakeUnique<AtomicRmwExpr>(opcode, 1 << alignment_log2, offset));
681 }
682 
OnAtomicRmwCmpxchgExpr(Opcode opcode,Address alignment_log2,Address offset)683 Result BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode,
684                                               Address alignment_log2,
685                                               Address offset) {
686   return AppendExpr(
687       MakeUnique<AtomicRmwCmpxchgExpr>(opcode, 1 << alignment_log2, offset));
688 }
689 
OnAtomicWaitExpr(Opcode opcode,Address alignment_log2,Address offset)690 Result BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode,
691                                         Address alignment_log2,
692                                         Address offset) {
693   return AppendExpr(
694       MakeUnique<AtomicWaitExpr>(opcode, 1 << alignment_log2, offset));
695 }
696 
OnAtomicFenceExpr(uint32_t consistency_model)697 Result BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model) {
698   return AppendExpr(MakeUnique<AtomicFenceExpr>(consistency_model));
699 }
700 
OnAtomicNotifyExpr(Opcode opcode,Address alignment_log2,Address offset)701 Result BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode,
702                                           Address alignment_log2,
703                                           Address offset) {
704   return AppendExpr(
705       MakeUnique<AtomicNotifyExpr>(opcode, 1 << alignment_log2, offset));
706 }
707 
OnBinaryExpr(Opcode opcode)708 Result BinaryReaderIR::OnBinaryExpr(Opcode opcode) {
709   return AppendExpr(MakeUnique<BinaryExpr>(opcode));
710 }
711 
OnBlockExpr(Type sig_type)712 Result BinaryReaderIR::OnBlockExpr(Type sig_type) {
713   auto expr = MakeUnique<BlockExpr>();
714   SetBlockDeclaration(&expr->block.decl, sig_type);
715   ExprList* expr_list = &expr->block.exprs;
716   CHECK_RESULT(AppendExpr(std::move(expr)));
717   PushLabel(LabelType::Block, expr_list);
718   return Result::Ok;
719 }
720 
OnBrExpr(Index depth)721 Result BinaryReaderIR::OnBrExpr(Index depth) {
722   return AppendExpr(MakeUnique<BrExpr>(Var(depth)));
723 }
724 
OnBrIfExpr(Index depth)725 Result BinaryReaderIR::OnBrIfExpr(Index depth) {
726   return AppendExpr(MakeUnique<BrIfExpr>(Var(depth)));
727 }
728 
OnBrTableExpr(Index num_targets,Index * target_depths,Index default_target_depth)729 Result BinaryReaderIR::OnBrTableExpr(Index num_targets,
730                                      Index* target_depths,
731                                      Index default_target_depth) {
732   auto expr = MakeUnique<BrTableExpr>();
733   expr->default_target = Var(default_target_depth);
734   expr->targets.resize(num_targets);
735   for (Index i = 0; i < num_targets; ++i) {
736     expr->targets[i] = Var(target_depths[i]);
737   }
738   return AppendExpr(std::move(expr));
739 }
740 
OnCallExpr(Index func_index)741 Result BinaryReaderIR::OnCallExpr(Index func_index) {
742   return AppendExpr(MakeUnique<CallExpr>(Var(func_index)));
743 }
744 
OnCallIndirectExpr(Index sig_index,Index table_index)745 Result BinaryReaderIR::OnCallIndirectExpr(Index sig_index, Index table_index) {
746   auto expr = MakeUnique<CallIndirectExpr>();
747   SetFuncDeclaration(&expr->decl, Var(sig_index, GetLocation()));
748   expr->table = Var(table_index);
749   return AppendExpr(std::move(expr));
750 }
751 
OnCallRefExpr()752 Result BinaryReaderIR::OnCallRefExpr() {
753   return AppendExpr(MakeUnique<CallRefExpr>());
754 }
755 
OnReturnCallExpr(Index func_index)756 Result BinaryReaderIR::OnReturnCallExpr(Index func_index) {
757   return AppendExpr(MakeUnique<ReturnCallExpr>(Var(func_index)));
758 }
759 
OnReturnCallIndirectExpr(Index sig_index,Index table_index)760 Result BinaryReaderIR::OnReturnCallIndirectExpr(Index sig_index, Index table_index) {
761   auto expr = MakeUnique<ReturnCallIndirectExpr>();
762   SetFuncDeclaration(&expr->decl, Var(sig_index, GetLocation()));
763   expr->table = Var(table_index);
764   return AppendExpr(std::move(expr));
765 }
766 
OnCompareExpr(Opcode opcode)767 Result BinaryReaderIR::OnCompareExpr(Opcode opcode) {
768   return AppendExpr(MakeUnique<CompareExpr>(opcode));
769 }
770 
OnConvertExpr(Opcode opcode)771 Result BinaryReaderIR::OnConvertExpr(Opcode opcode) {
772   return AppendExpr(MakeUnique<ConvertExpr>(opcode));
773 }
774 
OnDropExpr()775 Result BinaryReaderIR::OnDropExpr() {
776   return AppendExpr(MakeUnique<DropExpr>());
777 }
778 
OnElseExpr()779 Result BinaryReaderIR::OnElseExpr() {
780   LabelNode* label;
781   Expr* expr;
782   CHECK_RESULT(TopLabelExpr(&label, &expr));
783 
784   if (label->label_type == LabelType::If) {
785     auto* if_expr = cast<IfExpr>(expr);
786     if_expr->true_.end_loc = GetLocation();
787     label->exprs = &if_expr->false_;
788     label->label_type = LabelType::Else;
789   } else {
790     PrintError("else expression without matching if");
791     return Result::Error;
792   }
793 
794   return Result::Ok;
795 }
796 
OnEndExpr()797 Result BinaryReaderIR::OnEndExpr() {
798   LabelNode* label;
799   Expr* expr;
800   CHECK_RESULT(TopLabelExpr(&label, &expr));
801   switch (label->label_type) {
802     case LabelType::Block:
803       cast<BlockExpr>(expr)->block.end_loc = GetLocation();
804       break;
805     case LabelType::Loop:
806       cast<LoopExpr>(expr)->block.end_loc = GetLocation();
807       break;
808     case LabelType::If:
809       cast<IfExpr>(expr)->true_.end_loc = GetLocation();
810       break;
811     case LabelType::Else:
812       cast<IfExpr>(expr)->false_end_loc = GetLocation();
813       break;
814     case LabelType::Try:
815       cast<TryExpr>(expr)->block.end_loc = GetLocation();
816       break;
817 
818     case LabelType::Func:
819     case LabelType::Catch:
820       break;
821   }
822 
823   return PopLabel();
824 }
825 
OnF32ConstExpr(uint32_t value_bits)826 Result BinaryReaderIR::OnF32ConstExpr(uint32_t value_bits) {
827   return AppendExpr(
828       MakeUnique<ConstExpr>(Const::F32(value_bits, GetLocation())));
829 }
830 
OnF64ConstExpr(uint64_t value_bits)831 Result BinaryReaderIR::OnF64ConstExpr(uint64_t value_bits) {
832   return AppendExpr(
833       MakeUnique<ConstExpr>(Const::F64(value_bits, GetLocation())));
834 }
835 
OnV128ConstExpr(v128 value_bits)836 Result BinaryReaderIR::OnV128ConstExpr(v128 value_bits) {
837   return AppendExpr(
838       MakeUnique<ConstExpr>(Const::V128(value_bits, GetLocation())));
839 }
840 
OnGlobalGetExpr(Index global_index)841 Result BinaryReaderIR::OnGlobalGetExpr(Index global_index) {
842   return AppendExpr(
843       MakeUnique<GlobalGetExpr>(Var(global_index, GetLocation())));
844 }
845 
OnLocalGetExpr(Index local_index)846 Result BinaryReaderIR::OnLocalGetExpr(Index local_index) {
847   return AppendExpr(MakeUnique<LocalGetExpr>(Var(local_index, GetLocation())));
848 }
849 
OnI32ConstExpr(uint32_t value)850 Result BinaryReaderIR::OnI32ConstExpr(uint32_t value) {
851   return AppendExpr(MakeUnique<ConstExpr>(Const::I32(value, GetLocation())));
852 }
853 
OnI64ConstExpr(uint64_t value)854 Result BinaryReaderIR::OnI64ConstExpr(uint64_t value) {
855   return AppendExpr(MakeUnique<ConstExpr>(Const::I64(value, GetLocation())));
856 }
857 
OnIfExpr(Type sig_type)858 Result BinaryReaderIR::OnIfExpr(Type sig_type) {
859   auto expr = MakeUnique<IfExpr>();
860   SetBlockDeclaration(&expr->true_.decl, sig_type);
861   ExprList* expr_list = &expr->true_.exprs;
862   CHECK_RESULT(AppendExpr(std::move(expr)));
863   PushLabel(LabelType::If, expr_list);
864   return Result::Ok;
865 }
866 
OnLoadExpr(Opcode opcode,Address alignment_log2,Address offset)867 Result BinaryReaderIR::OnLoadExpr(Opcode opcode,
868                                   Address alignment_log2,
869                                   Address offset) {
870   return AppendExpr(MakeUnique<LoadExpr>(opcode, 1 << alignment_log2, offset));
871 }
872 
OnLoopExpr(Type sig_type)873 Result BinaryReaderIR::OnLoopExpr(Type sig_type) {
874   auto expr = MakeUnique<LoopExpr>();
875   SetBlockDeclaration(&expr->block.decl, sig_type);
876   ExprList* expr_list = &expr->block.exprs;
877   CHECK_RESULT(AppendExpr(std::move(expr)));
878   PushLabel(LabelType::Loop, expr_list);
879   return Result::Ok;
880 }
881 
OnMemoryCopyExpr()882 Result BinaryReaderIR::OnMemoryCopyExpr() {
883   return AppendExpr(MakeUnique<MemoryCopyExpr>());
884 }
885 
OnDataDropExpr(Index segment)886 Result BinaryReaderIR::OnDataDropExpr(Index segment) {
887   return AppendExpr(MakeUnique<DataDropExpr>(Var(segment)));
888 }
889 
OnMemoryFillExpr()890 Result BinaryReaderIR::OnMemoryFillExpr() {
891   return AppendExpr(MakeUnique<MemoryFillExpr>());
892 }
893 
OnMemoryGrowExpr()894 Result BinaryReaderIR::OnMemoryGrowExpr() {
895   return AppendExpr(MakeUnique<MemoryGrowExpr>());
896 }
897 
OnMemoryInitExpr(Index segment)898 Result BinaryReaderIR::OnMemoryInitExpr(Index segment) {
899   return AppendExpr(MakeUnique<MemoryInitExpr>(Var(segment)));
900 }
901 
OnMemorySizeExpr()902 Result BinaryReaderIR::OnMemorySizeExpr() {
903   return AppendExpr(MakeUnique<MemorySizeExpr>());
904 }
905 
OnTableCopyExpr(Index dst_index,Index src_index)906 Result BinaryReaderIR::OnTableCopyExpr(Index dst_index, Index src_index) {
907   return AppendExpr(MakeUnique<TableCopyExpr>(Var(dst_index), Var(src_index)));
908 }
909 
OnElemDropExpr(Index segment)910 Result BinaryReaderIR::OnElemDropExpr(Index segment) {
911   return AppendExpr(MakeUnique<ElemDropExpr>(Var(segment)));
912 }
913 
OnTableInitExpr(Index segment,Index table_index)914 Result BinaryReaderIR::OnTableInitExpr(Index segment, Index table_index) {
915   return AppendExpr(MakeUnique<TableInitExpr>(Var(segment), Var(table_index)));
916 }
917 
OnTableGetExpr(Index table_index)918 Result BinaryReaderIR::OnTableGetExpr(Index table_index) {
919   return AppendExpr(MakeUnique<TableGetExpr>(Var(table_index)));
920 }
921 
OnTableSetExpr(Index table_index)922 Result BinaryReaderIR::OnTableSetExpr(Index table_index) {
923   return AppendExpr(MakeUnique<TableSetExpr>(Var(table_index)));
924 }
925 
OnTableGrowExpr(Index table_index)926 Result BinaryReaderIR::OnTableGrowExpr(Index table_index) {
927   return AppendExpr(MakeUnique<TableGrowExpr>(Var(table_index)));
928 }
929 
OnTableSizeExpr(Index table_index)930 Result BinaryReaderIR::OnTableSizeExpr(Index table_index) {
931   return AppendExpr(MakeUnique<TableSizeExpr>(Var(table_index)));
932 }
933 
OnTableFillExpr(Index table_index)934 Result BinaryReaderIR::OnTableFillExpr(Index table_index) {
935   return AppendExpr(MakeUnique<TableFillExpr>(Var(table_index)));
936 }
937 
OnRefFuncExpr(Index func_index)938 Result BinaryReaderIR::OnRefFuncExpr(Index func_index) {
939   return AppendExpr(MakeUnique<RefFuncExpr>(Var(func_index)));
940 }
941 
OnRefNullExpr(Type type)942 Result BinaryReaderIR::OnRefNullExpr(Type type) {
943   return AppendExpr(MakeUnique<RefNullExpr>(type));
944 }
945 
OnRefIsNullExpr()946 Result BinaryReaderIR::OnRefIsNullExpr() {
947   return AppendExpr(MakeUnique<RefIsNullExpr>());
948 }
949 
OnNopExpr()950 Result BinaryReaderIR::OnNopExpr() {
951   return AppendExpr(MakeUnique<NopExpr>());
952 }
953 
OnRethrowExpr(Index depth)954 Result BinaryReaderIR::OnRethrowExpr(Index depth) {
955   return AppendExpr(MakeUnique<RethrowExpr>(Var(depth, GetLocation())));
956 }
957 
OnReturnExpr()958 Result BinaryReaderIR::OnReturnExpr() {
959   return AppendExpr(MakeUnique<ReturnExpr>());
960 }
961 
OnSelectExpr(Index result_count,Type * result_types)962 Result BinaryReaderIR::OnSelectExpr(Index result_count, Type* result_types) {
963   TypeVector results;
964   results.assign(result_types, result_types + result_count);
965   return AppendExpr(MakeUnique<SelectExpr>(results));
966 }
967 
OnGlobalSetExpr(Index global_index)968 Result BinaryReaderIR::OnGlobalSetExpr(Index global_index) {
969   return AppendExpr(
970       MakeUnique<GlobalSetExpr>(Var(global_index, GetLocation())));
971 }
972 
OnLocalSetExpr(Index local_index)973 Result BinaryReaderIR::OnLocalSetExpr(Index local_index) {
974   return AppendExpr(MakeUnique<LocalSetExpr>(Var(local_index, GetLocation())));
975 }
976 
OnStoreExpr(Opcode opcode,Address alignment_log2,Address offset)977 Result BinaryReaderIR::OnStoreExpr(Opcode opcode,
978                                    Address alignment_log2,
979                                    Address offset) {
980   return AppendExpr(MakeUnique<StoreExpr>(opcode, 1 << alignment_log2, offset));
981 }
982 
OnThrowExpr(Index tag_index)983 Result BinaryReaderIR::OnThrowExpr(Index tag_index) {
984   return AppendExpr(MakeUnique<ThrowExpr>(Var(tag_index, GetLocation())));
985 }
986 
OnLocalTeeExpr(Index local_index)987 Result BinaryReaderIR::OnLocalTeeExpr(Index local_index) {
988   return AppendExpr(MakeUnique<LocalTeeExpr>(Var(local_index, GetLocation())));
989 }
990 
OnTryExpr(Type sig_type)991 Result BinaryReaderIR::OnTryExpr(Type sig_type) {
992   auto expr_ptr = MakeUnique<TryExpr>();
993   // Save expr so it can be used below, after expr_ptr has been moved.
994   TryExpr* expr = expr_ptr.get();
995   ExprList* expr_list = &expr->block.exprs;
996   SetBlockDeclaration(&expr->block.decl, sig_type);
997   CHECK_RESULT(AppendExpr(std::move(expr_ptr)));
998   PushLabel(LabelType::Try, expr_list, expr);
999   return Result::Ok;
1000 }
1001 
AppendCatch(Catch && catch_)1002 Result BinaryReaderIR::AppendCatch(Catch&& catch_) {
1003   LabelNode* label = nullptr;
1004   CHECK_RESULT(TopLabel(&label));
1005 
1006   if (label->label_type != LabelType::Try) {
1007     PrintError("catch not inside try block");
1008     return Result::Error;
1009   }
1010 
1011   auto* try_ = cast<TryExpr>(label->context);
1012 
1013   if (catch_.IsCatchAll() && !try_->catches.empty() && try_->catches.back().IsCatchAll()) {
1014     PrintError("only one catch_all allowed in try block");
1015     return Result::Error;
1016   }
1017 
1018   if (try_->kind == TryKind::Plain) {
1019     try_->kind = TryKind::Catch;
1020   } else if (try_->kind != TryKind::Catch) {
1021     PrintError("catch not allowed in try-delegate");
1022     return Result::Error;
1023   }
1024 
1025   try_->catches.push_back(std::move(catch_));
1026   label->exprs = &try_->catches.back().exprs;
1027   return Result::Ok;
1028 }
1029 
OnCatchExpr(Index except_index)1030 Result BinaryReaderIR::OnCatchExpr(Index except_index) {
1031   return AppendCatch(Catch(Var(except_index, GetLocation())));
1032 }
1033 
OnCatchAllExpr()1034 Result BinaryReaderIR::OnCatchAllExpr() {
1035   return AppendCatch(Catch(GetLocation()));
1036 }
1037 
OnDelegateExpr(Index depth)1038 Result BinaryReaderIR::OnDelegateExpr(Index depth) {
1039   LabelNode* label = nullptr;
1040   CHECK_RESULT(TopLabel(&label));
1041 
1042   if (label->label_type != LabelType::Try) {
1043     PrintError("delegate not inside try block");
1044     return Result::Error;
1045   }
1046 
1047   auto* try_ = cast<TryExpr>(label->context);
1048 
1049   if (try_->kind == TryKind::Plain) {
1050     try_->kind = TryKind::Delegate;
1051   } else if (try_->kind != TryKind::Delegate) {
1052     PrintError("delegate not allowed in try-catch");
1053     return Result::Error;
1054   }
1055 
1056   try_->delegate_target = Var(depth, GetLocation());
1057 
1058   PopLabel();
1059   return Result::Ok;
1060 }
1061 
OnUnaryExpr(Opcode opcode)1062 Result BinaryReaderIR::OnUnaryExpr(Opcode opcode) {
1063   return AppendExpr(MakeUnique<UnaryExpr>(opcode));
1064 }
1065 
OnTernaryExpr(Opcode opcode)1066 Result BinaryReaderIR::OnTernaryExpr(Opcode opcode) {
1067   return AppendExpr(MakeUnique<TernaryExpr>(opcode));
1068 }
1069 
OnUnreachableExpr()1070 Result BinaryReaderIR::OnUnreachableExpr() {
1071   return AppendExpr(MakeUnique<UnreachableExpr>());
1072 }
1073 
EndFunctionBody(Index index)1074 Result BinaryReaderIR::EndFunctionBody(Index index) {
1075   CHECK_RESULT(PopLabel());
1076   current_func_ = nullptr;
1077   return Result::Ok;
1078 }
1079 
OnSimdLaneOpExpr(Opcode opcode,uint64_t value)1080 Result BinaryReaderIR::OnSimdLaneOpExpr(Opcode opcode, uint64_t value) {
1081   return AppendExpr(MakeUnique<SimdLaneOpExpr>(opcode, value));
1082 }
1083 
OnSimdLoadLaneExpr(Opcode opcode,Address alignment_log2,Address offset,uint64_t value)1084 Result BinaryReaderIR::OnSimdLoadLaneExpr(Opcode opcode,
1085                                           Address alignment_log2,
1086                                           Address offset,
1087                                           uint64_t value) {
1088   return AppendExpr(
1089       MakeUnique<SimdLoadLaneExpr>(opcode, 1 << alignment_log2, offset, value));
1090 }
1091 
OnSimdStoreLaneExpr(Opcode opcode,Address alignment_log2,Address offset,uint64_t value)1092 Result BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode,
1093                                           Address alignment_log2,
1094                                           Address offset,
1095                                           uint64_t value) {
1096   return AppendExpr(
1097       MakeUnique<SimdStoreLaneExpr>(opcode, 1 << alignment_log2, offset, value));
1098 }
1099 
OnSimdShuffleOpExpr(Opcode opcode,v128 value)1100 Result BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode, v128 value) {
1101   return AppendExpr(MakeUnique<SimdShuffleOpExpr>(opcode, value));
1102 }
1103 
OnLoadSplatExpr(Opcode opcode,Address alignment_log2,Address offset)1104 Result BinaryReaderIR::OnLoadSplatExpr(Opcode opcode,
1105                                        Address alignment_log2,
1106                                        Address offset) {
1107   return AppendExpr(
1108       MakeUnique<LoadSplatExpr>(opcode, 1 << alignment_log2, offset));
1109 }
1110 
OnLoadZeroExpr(Opcode opcode,Address alignment_log2,Address offset)1111 Result BinaryReaderIR::OnLoadZeroExpr(Opcode opcode,
1112                                       Address alignment_log2,
1113                                       Address offset) {
1114   return AppendExpr(
1115       MakeUnique<LoadZeroExpr>(opcode, 1 << alignment_log2, offset));
1116 }
1117 
OnElemSegmentCount(Index count)1118 Result BinaryReaderIR::OnElemSegmentCount(Index count) {
1119   WABT_TRY
1120   module_->elem_segments.reserve(count);
1121   WABT_CATCH_BAD_ALLOC
1122   return Result::Ok;
1123 }
1124 
BeginElemSegment(Index index,Index table_index,uint8_t flags)1125 Result BinaryReaderIR::BeginElemSegment(Index index,
1126                                         Index table_index,
1127                                         uint8_t flags) {
1128   auto field = MakeUnique<ElemSegmentModuleField>(GetLocation());
1129   ElemSegment& elem_segment = field->elem_segment;
1130   elem_segment.table_var = Var(table_index, GetLocation());
1131   if ((flags & SegDeclared) == SegDeclared) {
1132     elem_segment.kind = SegmentKind::Declared;
1133   } else if ((flags & SegPassive) == SegPassive) {
1134     elem_segment.kind = SegmentKind::Passive;
1135   } else {
1136     elem_segment.kind = SegmentKind::Active;
1137   }
1138   module_->AppendField(std::move(field));
1139   return Result::Ok;
1140 }
1141 
BeginElemSegmentInitExpr(Index index)1142 Result BinaryReaderIR::BeginElemSegmentInitExpr(Index index) {
1143   assert(index == module_->elem_segments.size() - 1);
1144   ElemSegment* segment = module_->elem_segments[index];
1145   current_init_expr_ = &segment->offset;
1146   return Result::Ok;
1147 }
1148 
EndElemSegmentInitExpr(Index index)1149 Result BinaryReaderIR::EndElemSegmentInitExpr(Index index) {
1150   current_init_expr_ = nullptr;
1151   return Result::Ok;
1152 }
1153 
OnElemSegmentElemType(Index index,Type elem_type)1154 Result BinaryReaderIR::OnElemSegmentElemType(Index index, Type elem_type) {
1155   assert(index == module_->elem_segments.size() - 1);
1156   ElemSegment* segment = module_->elem_segments[index];
1157   segment->elem_type = elem_type;
1158   return Result::Ok;
1159 }
1160 
OnElemSegmentElemExprCount(Index index,Index count)1161 Result BinaryReaderIR::OnElemSegmentElemExprCount(Index index, Index count) {
1162   assert(index == module_->elem_segments.size() - 1);
1163   ElemSegment* segment = module_->elem_segments[index];
1164   WABT_TRY
1165   segment->elem_exprs.reserve(count);
1166   WABT_CATCH_BAD_ALLOC
1167   return Result::Ok;
1168 }
1169 
OnElemSegmentElemExpr_RefNull(Index segment_index,Type type)1170 Result BinaryReaderIR::OnElemSegmentElemExpr_RefNull(Index segment_index,
1171                                                      Type type) {
1172   assert(segment_index == module_->elem_segments.size() - 1);
1173   ElemSegment* segment = module_->elem_segments[segment_index];
1174   segment->elem_exprs.emplace_back(type);
1175   return Result::Ok;
1176 }
1177 
OnElemSegmentElemExpr_RefFunc(Index segment_index,Index func_index)1178 Result BinaryReaderIR::OnElemSegmentElemExpr_RefFunc(Index segment_index,
1179                                                      Index func_index) {
1180   assert(segment_index == module_->elem_segments.size() - 1);
1181   ElemSegment* segment = module_->elem_segments[segment_index];
1182   segment->elem_exprs.emplace_back(Var(func_index, GetLocation()));
1183   return Result::Ok;
1184 }
1185 
OnDataSegmentCount(Index count)1186 Result BinaryReaderIR::OnDataSegmentCount(Index count) {
1187   WABT_TRY
1188   module_->data_segments.reserve(count);
1189   WABT_CATCH_BAD_ALLOC
1190   return Result::Ok;
1191 }
1192 
BeginDataSegment(Index index,Index memory_index,uint8_t flags)1193 Result BinaryReaderIR::BeginDataSegment(Index index,
1194                                         Index memory_index,
1195                                         uint8_t flags) {
1196   auto field = MakeUnique<DataSegmentModuleField>(GetLocation());
1197   DataSegment& data_segment = field->data_segment;
1198   data_segment.memory_var = Var(memory_index, GetLocation());
1199   if ((flags & SegPassive) == SegPassive) {
1200     data_segment.kind = SegmentKind::Passive;
1201   } else {
1202     data_segment.kind = SegmentKind::Active;
1203   }
1204   module_->AppendField(std::move(field));
1205   return Result::Ok;
1206 }
1207 
BeginDataSegmentInitExpr(Index index)1208 Result BinaryReaderIR::BeginDataSegmentInitExpr(Index index) {
1209   assert(index == module_->data_segments.size() - 1);
1210   DataSegment* segment = module_->data_segments[index];
1211   current_init_expr_ = &segment->offset;
1212   return Result::Ok;
1213 }
1214 
EndDataSegmentInitExpr(Index index)1215 Result BinaryReaderIR::EndDataSegmentInitExpr(Index index) {
1216   current_init_expr_ = nullptr;
1217   return Result::Ok;
1218 }
1219 
OnDataSegmentData(Index index,const void * data,Address size)1220 Result BinaryReaderIR::OnDataSegmentData(Index index,
1221                                          const void* data,
1222                                          Address size) {
1223   assert(index == module_->data_segments.size() - 1);
1224   DataSegment* segment = module_->data_segments[index];
1225   segment->data.resize(size);
1226   if (size > 0) {
1227     memcpy(segment->data.data(), data, size);
1228   }
1229   return Result::Ok;
1230 }
1231 
OnFunctionNamesCount(Index count)1232 Result BinaryReaderIR::OnFunctionNamesCount(Index count) {
1233   if (count > module_->funcs.size()) {
1234     PrintError("expected function name count (%" PRIindex
1235                ") <= function count (%" PRIzd ")",
1236                count, module_->funcs.size());
1237     return Result::Error;
1238   }
1239   return Result::Ok;
1240 }
1241 
MakeDollarName(string_view name)1242 static std::string MakeDollarName(string_view name) {
1243   return std::string("$") + name.to_string();
1244 }
1245 
OnModuleName(string_view name)1246 Result BinaryReaderIR::OnModuleName(string_view name) {
1247   if (name.empty()) {
1248     return Result::Ok;
1249   }
1250 
1251   module_->name = MakeDollarName(name);
1252   return Result::Ok;
1253 }
1254 
SetGlobalName(Index index,string_view name)1255 Result BinaryReaderIR::SetGlobalName(Index index, string_view name) {
1256   if (name.empty()) {
1257     return Result::Ok;
1258   }
1259   if (index >= module_->globals.size()) {
1260     PrintError("invalid global index: %" PRIindex, index);
1261     return Result::Error;
1262   }
1263   Global* glob = module_->globals[index];
1264   std::string dollar_name =
1265       GetUniqueName(&module_->global_bindings, MakeDollarName(name));
1266   glob->name = dollar_name;
1267   module_->global_bindings.emplace(dollar_name, Binding(index));
1268   return Result::Ok;
1269 }
1270 
SetFunctionName(Index index,string_view name)1271 Result BinaryReaderIR::SetFunctionName(Index index, string_view name) {
1272   if (name.empty()) {
1273     return Result::Ok;
1274   }
1275   if (index >= module_->funcs.size()) {
1276     PrintError("invalid function index: %" PRIindex, index);
1277     return Result::Error;
1278   }
1279   Func* func = module_->funcs[index];
1280   std::string dollar_name =
1281       GetUniqueName(&module_->func_bindings, MakeDollarName(name));
1282   func->name = dollar_name;
1283   module_->func_bindings.emplace(dollar_name, Binding(index));
1284   return Result::Ok;
1285 }
1286 
SetTableName(Index index,string_view name)1287 Result BinaryReaderIR::SetTableName(Index index, string_view name) {
1288   if (name.empty()) {
1289     return Result::Ok;
1290   }
1291   if (index >= module_->tables.size()) {
1292     PrintError("invalid table index: %" PRIindex, index);
1293     return Result::Error;
1294   }
1295   Table* table = module_->tables[index];
1296   std::string dollar_name =
1297       GetUniqueName(&module_->table_bindings, MakeDollarName(name));
1298   table->name = dollar_name;
1299   module_->table_bindings.emplace(dollar_name, Binding(index));
1300   return Result::Ok;
1301 }
1302 
SetDataSegmentName(Index index,string_view name)1303 Result BinaryReaderIR::SetDataSegmentName(Index index, string_view name) {
1304   if (name.empty()) {
1305     return Result::Ok;
1306   }
1307   if (index >= module_->data_segments.size()) {
1308     PrintError("invalid data segment index: %" PRIindex, index);
1309     return Result::Error;
1310   }
1311   DataSegment* segment = module_->data_segments[index];
1312   std::string dollar_name =
1313       GetUniqueName(&module_->data_segment_bindings, MakeDollarName(name));
1314   segment->name = dollar_name;
1315   module_->data_segment_bindings.emplace(dollar_name, Binding(index));
1316   return Result::Ok;
1317 }
1318 
SetElemSegmentName(Index index,string_view name)1319 Result BinaryReaderIR::SetElemSegmentName(Index index, string_view name) {
1320   if (name.empty()) {
1321     return Result::Ok;
1322   }
1323   if (index >= module_->elem_segments.size()) {
1324     PrintError("invalid elem segment index: %" PRIindex, index);
1325     return Result::Error;
1326   }
1327   ElemSegment* segment = module_->elem_segments[index];
1328   std::string dollar_name =
1329       GetUniqueName(&module_->elem_segment_bindings, MakeDollarName(name));
1330   segment->name = dollar_name;
1331   module_->elem_segment_bindings.emplace(dollar_name, Binding(index));
1332   return Result::Ok;
1333 }
1334 
SetMemoryName(Index index,string_view name)1335 Result BinaryReaderIR::SetMemoryName(Index index, string_view name) {
1336   if (name.empty()) {
1337     return Result::Ok;
1338   }
1339   if (index >= module_->memories.size()) {
1340     PrintError("invalid memory index: %" PRIindex, index);
1341     return Result::Error;
1342   }
1343   Memory* memory = module_->memories[index];
1344   std::string dollar_name =
1345       GetUniqueName(&module_->memory_bindings, MakeDollarName(name));
1346   memory->name = dollar_name;
1347   module_->memory_bindings.emplace(dollar_name, Binding(index));
1348   return Result::Ok;
1349 }
1350 
OnFunctionName(Index index,string_view name)1351 Result BinaryReaderIR::OnFunctionName(Index index, string_view name) {
1352   return SetFunctionName(index, name);
1353 }
1354 
OnNameEntry(NameSectionSubsection type,Index index,string_view name)1355 Result BinaryReaderIR::OnNameEntry(NameSectionSubsection type,
1356                                    Index index,
1357                                    string_view name) {
1358   switch (type) {
1359     // TODO(sbc): remove OnFunctionName in favor of just using
1360     // OnNameEntry so that this works
1361     case NameSectionSubsection::Function:
1362     case NameSectionSubsection::Local:
1363     case NameSectionSubsection::Module:
1364     case NameSectionSubsection::Label:
1365     case NameSectionSubsection::Type:
1366       break;
1367     case NameSectionSubsection::Global:
1368       SetGlobalName(index, name);
1369       break;
1370     case NameSectionSubsection::Table:
1371       SetTableName(index, name);
1372       break;
1373     case NameSectionSubsection::DataSegment:
1374       SetDataSegmentName(index, name);
1375       break;
1376     case NameSectionSubsection::Memory:
1377       SetMemoryName(index, name);
1378       break;
1379     case NameSectionSubsection::ElemSegment:
1380       SetElemSegmentName(index, name);
1381       break;
1382   }
1383   return Result::Ok;
1384 }
1385 
OnLocalNameLocalCount(Index index,Index count)1386 Result BinaryReaderIR::OnLocalNameLocalCount(Index index, Index count) {
1387   assert(index < module_->funcs.size());
1388   Func* func = module_->funcs[index];
1389   Index num_params_and_locals = func->GetNumParamsAndLocals();
1390   if (count > num_params_and_locals) {
1391     PrintError("expected local name count (%" PRIindex
1392                ") <= local count (%" PRIindex ")",
1393                count, num_params_and_locals);
1394     return Result::Error;
1395   }
1396   return Result::Ok;
1397 }
1398 
OnInitExprF32ConstExpr(Index index,uint32_t value)1399 Result BinaryReaderIR::OnInitExprF32ConstExpr(Index index, uint32_t value) {
1400   Location loc = GetLocation();
1401   current_init_expr_->push_back(
1402       MakeUnique<ConstExpr>(Const::F32(value, loc), loc));
1403   return Result::Ok;
1404 }
1405 
OnInitExprF64ConstExpr(Index index,uint64_t value)1406 Result BinaryReaderIR::OnInitExprF64ConstExpr(Index index, uint64_t value) {
1407   Location loc = GetLocation();
1408   current_init_expr_->push_back(
1409       MakeUnique<ConstExpr>(Const::F64(value, loc), loc));
1410   return Result::Ok;
1411 }
1412 
OnInitExprV128ConstExpr(Index index,v128 value)1413 Result BinaryReaderIR::OnInitExprV128ConstExpr(Index index, v128 value) {
1414   Location loc = GetLocation();
1415   current_init_expr_->push_back(
1416       MakeUnique<ConstExpr>(Const::V128(value, loc), loc));
1417   return Result::Ok;
1418 }
1419 
OnInitExprGlobalGetExpr(Index index,Index global_index)1420 Result BinaryReaderIR::OnInitExprGlobalGetExpr(Index index,
1421                                                Index global_index) {
1422   Location loc = GetLocation();
1423   current_init_expr_->push_back(
1424       MakeUnique<GlobalGetExpr>(Var(global_index, loc), loc));
1425   return Result::Ok;
1426 }
1427 
OnInitExprI32ConstExpr(Index index,uint32_t value)1428 Result BinaryReaderIR::OnInitExprI32ConstExpr(Index index, uint32_t value) {
1429   Location loc = GetLocation();
1430   current_init_expr_->push_back(
1431       MakeUnique<ConstExpr>(Const::I32(value, loc), loc));
1432   return Result::Ok;
1433 }
1434 
OnInitExprI64ConstExpr(Index index,uint64_t value)1435 Result BinaryReaderIR::OnInitExprI64ConstExpr(Index index, uint64_t value) {
1436   Location loc = GetLocation();
1437   current_init_expr_->push_back(
1438       MakeUnique<ConstExpr>(Const::I64(value, loc), loc));
1439   return Result::Ok;
1440 }
1441 
OnInitExprRefNull(Index index,Type type)1442 Result BinaryReaderIR::OnInitExprRefNull(Index index, Type type) {
1443   Location loc = GetLocation();
1444   current_init_expr_->push_back(MakeUnique<RefNullExpr>(type, loc));
1445   return Result::Ok;
1446 }
1447 
OnInitExprRefFunc(Index index,Index func_index)1448 Result BinaryReaderIR::OnInitExprRefFunc(Index index, Index func_index) {
1449   Location loc = GetLocation();
1450   current_init_expr_->push_back(
1451       MakeUnique<RefFuncExpr>(Var(func_index, loc), loc));
1452   return Result::Ok;
1453 }
1454 
OnLocalName(Index func_index,Index local_index,string_view name)1455 Result BinaryReaderIR::OnLocalName(Index func_index,
1456                                    Index local_index,
1457                                    string_view name) {
1458   if (name.empty()) {
1459     return Result::Ok;
1460   }
1461 
1462   Func* func = module_->funcs[func_index];
1463   func->bindings.emplace(GetUniqueName(&func->bindings, MakeDollarName(name)),
1464                          Binding(local_index));
1465   return Result::Ok;
1466 }
1467 
OnTagType(Index index,Index sig_index)1468 Result BinaryReaderIR::OnTagType(Index index, Index sig_index) {
1469   auto field = MakeUnique<TagModuleField>(GetLocation());
1470   Tag& tag = field->tag;
1471   SetFuncDeclaration(&tag.decl, Var(sig_index, GetLocation()));
1472   module_->AppendField(std::move(field));
1473   return Result::Ok;
1474 }
1475 
OnDataSymbol(Index index,uint32_t flags,string_view name,Index segment,uint32_t offset,uint32_t size)1476 Result BinaryReaderIR::OnDataSymbol(Index index, uint32_t flags,
1477                                     string_view name, Index segment,
1478                                     uint32_t offset, uint32_t size) {
1479   if (name.empty()) {
1480     return Result::Ok;
1481   }
1482   if (flags & WABT_SYMBOL_FLAG_UNDEFINED) {
1483     // Refers to data in another file, `segment` not valid.
1484     return Result::Ok;
1485   }
1486   if (offset) {
1487     // If it is pointing into the data segment, then it's not really naming
1488     // the whole segment.
1489     return Result::Ok;
1490   }
1491   if (segment >= module_->data_segments.size()) {
1492     PrintError("invalid data segment index: %" PRIindex, segment);
1493     return Result::Error;
1494   }
1495   DataSegment* seg = module_->data_segments[segment];
1496   std::string dollar_name =
1497       GetUniqueName(&module_->data_segment_bindings, MakeDollarName(name));
1498   seg->name = dollar_name;
1499   module_->data_segment_bindings.emplace(dollar_name, Binding(segment));
1500   return Result::Ok;
1501 }
1502 
OnFunctionSymbol(Index index,uint32_t flags,string_view name,Index func_index)1503 Result BinaryReaderIR::OnFunctionSymbol(Index index, uint32_t flags,
1504                                         string_view name, Index func_index) {
1505   if (name.empty()) {
1506     return Result::Ok;
1507   }
1508   if (func_index >= module_->funcs.size()) {
1509     PrintError("invalid function index: %" PRIindex, func_index);
1510     return Result::Error;
1511   }
1512   Func* func = module_->funcs[func_index];
1513   if (!func->name.empty()) {
1514     // The name section has already named this function.
1515     return Result::Ok;
1516   }
1517   std::string dollar_name =
1518       GetUniqueName(&module_->func_bindings, MakeDollarName(name));
1519   func->name = dollar_name;
1520   module_->func_bindings.emplace(dollar_name, Binding(func_index));
1521   return Result::Ok;
1522 }
1523 
OnGlobalSymbol(Index index,uint32_t flags,string_view name,Index global_index)1524 Result BinaryReaderIR::OnGlobalSymbol(Index index, uint32_t flags,
1525                                       string_view name, Index global_index) {
1526   return SetGlobalName(global_index, name);
1527 }
1528 
OnSectionSymbol(Index index,uint32_t flags,Index section_index)1529 Result BinaryReaderIR::OnSectionSymbol(Index index, uint32_t flags,
1530                                        Index section_index) {
1531   return Result::Ok;
1532 }
1533 
OnTagSymbol(Index index,uint32_t flags,string_view name,Index tag_index)1534 Result BinaryReaderIR::OnTagSymbol(Index index,
1535                                    uint32_t flags,
1536                                    string_view name,
1537                                    Index tag_index) {
1538   if (name.empty()) {
1539     return Result::Ok;
1540   }
1541   if (tag_index >= module_->tags.size()) {
1542     PrintError("invalid tag index: %" PRIindex, tag_index);
1543     return Result::Error;
1544   }
1545   Tag* tag = module_->tags[tag_index];
1546   std::string dollar_name =
1547       GetUniqueName(&module_->tag_bindings, MakeDollarName(name));
1548   tag->name = dollar_name;
1549   module_->tag_bindings.emplace(dollar_name, Binding(tag_index));
1550   return Result::Ok;
1551 }
1552 
OnTableSymbol(Index index,uint32_t flags,string_view name,Index table_index)1553 Result BinaryReaderIR::OnTableSymbol(Index index, uint32_t flags,
1554                                      string_view name, Index table_index) {
1555   return SetTableName(index, name);
1556 }
1557 
1558 }  // end anonymous namespace
1559 
ReadBinaryIr(const char * filename,const void * data,size_t size,const ReadBinaryOptions & options,Errors * errors,Module * out_module)1560 Result ReadBinaryIr(const char* filename,
1561                     const void* data,
1562                     size_t size,
1563                     const ReadBinaryOptions& options,
1564                     Errors* errors,
1565                     Module* out_module) {
1566   BinaryReaderIR reader(out_module, filename, errors);
1567   return ReadBinary(data, size, &reader, options);
1568 }
1569 
1570 }  // namespace wabt
1571