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, ¤t_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