2 * Copyright 2016 WebAssembly Community Group participants
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "wabt/binary-reader-ir.h"
27 #include "wabt/binary-reader-nop.h"
28 #include "wabt/cast.h"
29 #include "wabt/common.h"
37 LabelNode(LabelType
, ExprList
* exprs
, Expr
* context
= nullptr);
44 LabelNode::LabelNode(LabelType label_type
, ExprList
* exprs
, Expr
* context
)
45 : label_type(label_type
), exprs(exprs
), context(context
) {}
47 class CodeMetadataExprQueue
{
51 std::deque
<std::unique_ptr
<CodeMetadataExpr
>> func_queue
;
52 Entry(Func
* f
) : func(f
) {}
54 std::deque
<Entry
> entries
;
57 CodeMetadataExprQueue() {}
58 void push_func(Func
* f
) { entries
.emplace_back(f
); }
59 void push_metadata(std::unique_ptr
<CodeMetadataExpr
> meta
) {
60 assert(!entries
.empty());
61 entries
.back().func_queue
.push_back(std::move(meta
));
64 std::unique_ptr
<CodeMetadataExpr
> pop_match(Func
* f
, Offset offset
) {
65 std::unique_ptr
<CodeMetadataExpr
> ret
;
66 if (entries
.empty()) {
70 auto& current_entry
= entries
.front();
72 if (current_entry
.func
!= f
)
74 if (current_entry
.func_queue
.empty()) {
79 auto& current_metadata
= current_entry
.func_queue
.front();
80 if (current_metadata
->loc
.offset
+ current_entry
.func
->loc
.offset
!=
85 current_metadata
->loc
= Location(offset
);
86 ret
= std::move(current_metadata
);
87 current_entry
.func_queue
.pop_front();
93 class BinaryReaderIR
: public BinaryReaderNop
{
94 static constexpr size_t kMaxNestingDepth
= 16384; // max depth of label stack
95 static constexpr size_t kMaxFunctionLocals
= 50000; // matches V8
96 static constexpr size_t kMaxFunctionParams
= 1000; // matches V8
97 static constexpr size_t kMaxFunctionResults
= 1000; // matches V8
100 BinaryReaderIR(Module
* out_module
, const char* filename
, Errors
* errors
);
102 bool OnError(const Error
&) override
;
104 Result
OnTypeCount(Index count
) override
;
105 Result
OnFuncType(Index index
,
109 Type
* result_types
) override
;
110 Result
OnStructType(Index index
, Index field_count
, TypeMut
* fields
) override
;
111 Result
OnArrayType(Index index
, TypeMut field
) override
;
113 Result
OnImportCount(Index count
) override
;
114 Result
OnImportFunc(Index import_index
,
115 std::string_view module_name
,
116 std::string_view field_name
,
118 Index sig_index
) override
;
119 Result
OnImportTable(Index import_index
,
120 std::string_view module_name
,
121 std::string_view field_name
,
124 const Limits
* elem_limits
) override
;
125 Result
OnImportMemory(Index import_index
,
126 std::string_view module_name
,
127 std::string_view field_name
,
129 const Limits
* page_limits
) override
;
130 Result
OnImportGlobal(Index import_index
,
131 std::string_view module_name
,
132 std::string_view field_name
,
135 bool mutable_
) override
;
136 Result
OnImportTag(Index import_index
,
137 std::string_view module_name
,
138 std::string_view field_name
,
140 Index sig_index
) override
;
142 Result
OnFunctionCount(Index count
) override
;
143 Result
OnFunction(Index index
, Index sig_index
) override
;
145 Result
OnTableCount(Index count
) override
;
146 Result
OnTable(Index index
,
148 const Limits
* elem_limits
) override
;
150 Result
OnMemoryCount(Index count
) override
;
151 Result
OnMemory(Index index
, const Limits
* limits
) override
;
153 Result
OnGlobalCount(Index count
) override
;
154 Result
BeginGlobal(Index index
, Type type
, bool mutable_
) override
;
155 Result
BeginGlobalInitExpr(Index index
) override
;
156 Result
EndGlobalInitExpr(Index index
) override
;
158 Result
OnExportCount(Index count
) override
;
159 Result
OnExport(Index index
,
162 std::string_view name
) override
;
164 Result
OnStartFunction(Index func_index
) override
;
166 Result
OnFunctionBodyCount(Index count
) override
;
167 Result
BeginFunctionBody(Index index
, Offset size
) override
;
168 Result
OnLocalDecl(Index decl_index
, Index count
, Type type
) override
;
170 Result
OnOpcode(Opcode opcode
) override
;
171 Result
OnAtomicLoadExpr(Opcode opcode
,
173 Address alignment_log2
,
174 Address offset
) override
;
175 Result
OnAtomicStoreExpr(Opcode opcode
,
177 Address alignment_log2
,
178 Address offset
) override
;
179 Result
OnAtomicRmwExpr(Opcode opcode
,
181 Address alignment_log2
,
182 Address offset
) override
;
183 Result
OnAtomicRmwCmpxchgExpr(Opcode opcode
,
185 Address alignment_log2
,
186 Address offset
) override
;
187 Result
OnAtomicWaitExpr(Opcode opcode
,
189 Address alignment_log2
,
190 Address offset
) override
;
191 Result
OnAtomicFenceExpr(uint32_t consistency_model
) override
;
192 Result
OnAtomicNotifyExpr(Opcode opcode
,
194 Address alignment_log2
,
195 Address offset
) override
;
196 Result
OnBinaryExpr(Opcode opcode
) override
;
197 Result
OnBlockExpr(Type sig_type
) override
;
198 Result
OnBrExpr(Index depth
) override
;
199 Result
OnBrIfExpr(Index depth
) override
;
200 Result
OnBrTableExpr(Index num_targets
,
201 Index
* target_depths
,
202 Index default_target_depth
) override
;
203 Result
OnCallExpr(Index func_index
) override
;
204 Result
OnCatchExpr(Index tag_index
) override
;
205 Result
OnCatchAllExpr() override
;
206 Result
OnCallIndirectExpr(Index sig_index
, Index table_index
) override
;
207 Result
OnCallRefExpr() override
;
208 Result
OnReturnCallExpr(Index func_index
) override
;
209 Result
OnReturnCallIndirectExpr(Index sig_index
, Index table_index
) override
;
210 Result
OnCompareExpr(Opcode opcode
) override
;
211 Result
OnConvertExpr(Opcode opcode
) override
;
212 Result
OnDelegateExpr(Index depth
) override
;
213 Result
OnDropExpr() override
;
214 Result
OnElseExpr() override
;
215 Result
OnEndExpr() override
;
216 Result
OnF32ConstExpr(uint32_t value_bits
) override
;
217 Result
OnF64ConstExpr(uint64_t value_bits
) override
;
218 Result
OnV128ConstExpr(v128 value_bits
) override
;
219 Result
OnGlobalGetExpr(Index global_index
) override
;
220 Result
OnGlobalSetExpr(Index global_index
) override
;
221 Result
OnI32ConstExpr(uint32_t value
) override
;
222 Result
OnI64ConstExpr(uint64_t value
) override
;
223 Result
OnIfExpr(Type sig_type
) override
;
224 Result
OnLoadExpr(Opcode opcode
,
226 Address alignment_log2
,
227 Address offset
) override
;
228 Result
OnLocalGetExpr(Index local_index
) override
;
229 Result
OnLocalSetExpr(Index local_index
) override
;
230 Result
OnLocalTeeExpr(Index local_index
) override
;
231 Result
OnLoopExpr(Type sig_type
) override
;
232 Result
OnMemoryCopyExpr(Index srcmemidx
, Index destmemidx
) override
;
233 Result
OnDataDropExpr(Index segment_index
) override
;
234 Result
OnMemoryFillExpr(Index memidx
) override
;
235 Result
OnMemoryGrowExpr(Index memidx
) override
;
236 Result
OnMemoryInitExpr(Index segment_index
, Index memidx
) override
;
237 Result
OnMemorySizeExpr(Index memidx
) override
;
238 Result
OnTableCopyExpr(Index dst_index
, Index src_index
) override
;
239 Result
OnElemDropExpr(Index segment_index
) override
;
240 Result
OnTableInitExpr(Index segment_index
, Index table_index
) override
;
241 Result
OnTableGetExpr(Index table_index
) override
;
242 Result
OnTableSetExpr(Index table_index
) override
;
243 Result
OnTableGrowExpr(Index table_index
) override
;
244 Result
OnTableSizeExpr(Index table_index
) override
;
245 Result
OnTableFillExpr(Index table_index
) override
;
246 Result
OnRefFuncExpr(Index func_index
) override
;
247 Result
OnRefNullExpr(Type type
) override
;
248 Result
OnRefIsNullExpr() override
;
249 Result
OnNopExpr() override
;
250 Result
OnRethrowExpr(Index depth
) override
;
251 Result
OnReturnExpr() override
;
252 Result
OnSelectExpr(Index result_count
, Type
* result_types
) override
;
253 Result
OnStoreExpr(Opcode opcode
,
255 Address alignment_log2
,
256 Address offset
) override
;
257 Result
OnThrowExpr(Index tag_index
) override
;
258 Result
OnTryExpr(Type sig_type
) override
;
259 Result
OnUnaryExpr(Opcode opcode
) override
;
260 Result
OnTernaryExpr(Opcode opcode
) override
;
261 Result
OnUnreachableExpr() override
;
262 Result
EndFunctionBody(Index index
) override
;
263 Result
OnSimdLaneOpExpr(Opcode opcode
, uint64_t value
) override
;
264 Result
OnSimdLoadLaneExpr(Opcode opcode
,
266 Address alignment_log2
,
268 uint64_t value
) override
;
269 Result
OnSimdStoreLaneExpr(Opcode opcode
,
271 Address alignment_log2
,
273 uint64_t value
) override
;
274 Result
OnSimdShuffleOpExpr(Opcode opcode
, v128 value
) override
;
275 Result
OnLoadSplatExpr(Opcode opcode
,
277 Address alignment_log2
,
278 Address offset
) override
;
279 Result
OnLoadZeroExpr(Opcode opcode
,
281 Address alignment_log2
,
282 Address offset
) override
;
284 Result
OnElemSegmentCount(Index count
) override
;
285 Result
BeginElemSegment(Index index
,
287 uint8_t flags
) override
;
288 Result
BeginElemSegmentInitExpr(Index index
) override
;
289 Result
EndElemSegmentInitExpr(Index index
) override
;
290 Result
OnElemSegmentElemType(Index index
, Type elem_type
) override
;
291 Result
OnElemSegmentElemExprCount(Index index
, Index count
) override
;
292 Result
OnElemSegmentElemExpr_RefNull(Index segment_index
, Type type
) override
;
293 Result
OnElemSegmentElemExpr_RefFunc(Index segment_index
,
294 Index func_index
) override
;
296 Result
OnDataSegmentCount(Index count
) override
;
297 Result
BeginDataSegment(Index index
,
299 uint8_t flags
) override
;
300 Result
BeginDataSegmentInitExpr(Index index
) override
;
301 Result
EndDataSegmentInitExpr(Index index
) override
;
302 Result
OnDataSegmentData(Index index
,
304 Address size
) override
;
306 Result
OnModuleName(std::string_view module_name
) override
;
307 Result
OnFunctionNamesCount(Index num_functions
) override
;
308 Result
OnFunctionName(Index function_index
,
309 std::string_view function_name
) override
;
310 Result
OnLocalNameLocalCount(Index function_index
, Index num_locals
) override
;
311 Result
OnLocalName(Index function_index
,
313 std::string_view local_name
) override
;
314 Result
OnNameEntry(NameSectionSubsection type
,
316 std::string_view name
) override
;
318 Result
BeginTagSection(Offset size
) override
{ return Result::Ok
; }
319 Result
OnTagCount(Index count
) override
{ return Result::Ok
; }
320 Result
OnTagType(Index index
, Index sig_index
) override
;
321 Result
EndTagSection() override
{ return Result::Ok
; }
323 Result
OnDataSymbol(Index index
,
325 std::string_view name
,
328 uint32_t size
) override
;
329 Result
OnFunctionSymbol(Index index
,
331 std::string_view name
,
332 Index func_index
) override
;
333 Result
OnGlobalSymbol(Index index
,
335 std::string_view name
,
336 Index global_index
) override
;
337 Result
OnSectionSymbol(Index index
,
339 Index section_index
) override
;
340 /* Code Metadata sections */
341 Result
BeginCodeMetadataSection(std::string_view name
, Offset size
) override
;
342 Result
OnCodeMetadataFuncCount(Index count
) override
;
343 Result
OnCodeMetadataCount(Index function_index
, Index count
) override
;
344 Result
OnCodeMetadata(Offset offset
, const void* data
, Address size
) override
;
346 Result
OnTagSymbol(Index index
,
348 std::string_view name
,
349 Index tag_index
) override
;
350 Result
OnTableSymbol(Index index
,
352 std::string_view name
,
353 Index table_index
) override
;
356 Location
GetLocation() const;
357 void PrintError(const char* format
, ...);
358 Result
PushLabel(LabelType label_type
,
360 Expr
* context
= nullptr);
361 Result
BeginInitExpr(ExprList
* init_expr
);
362 Result
EndInitExpr();
364 Result
GetLabelAt(LabelNode
** label
, Index depth
);
365 Result
TopLabel(LabelNode
** label
);
366 Result
TopLabelExpr(LabelNode
** label
, Expr
** expr
);
367 Result
AppendExpr(std::unique_ptr
<Expr
> expr
);
368 Result
AppendCatch(Catch
&& catch_
);
369 void SetFuncDeclaration(FuncDeclaration
* decl
, Var var
);
370 void SetBlockDeclaration(BlockDeclaration
* decl
, Type sig_type
);
371 Result
SetMemoryName(Index index
, std::string_view name
);
372 Result
SetTableName(Index index
, std::string_view name
);
373 Result
SetFunctionName(Index index
, std::string_view name
);
374 Result
SetTypeName(Index index
, std::string_view name
);
375 Result
SetGlobalName(Index index
, std::string_view name
);
376 Result
SetDataSegmentName(Index index
, std::string_view name
);
377 Result
SetElemSegmentName(Index index
, std::string_view name
);
378 Result
SetTagName(Index index
, std::string_view name
);
380 std::string
GetUniqueName(BindingHash
* bindings
,
381 const std::string
& original_name
);
383 Errors
* errors_
= nullptr;
384 Module
* module_
= nullptr;
386 Func
* current_func_
= nullptr;
387 std::vector
<LabelNode
> label_stack_
;
388 const char* filename_
;
390 CodeMetadataExprQueue code_metadata_queue_
;
391 std::string_view current_metadata_name_
;
394 BinaryReaderIR::BinaryReaderIR(Module
* out_module
,
395 const char* filename
,
397 : errors_(errors
), module_(out_module
), filename_(filename
) {}
399 Location
BinaryReaderIR::GetLocation() const {
401 loc
.filename
= filename_
;
402 loc
.offset
= state
->offset
;
406 void WABT_PRINTF_FORMAT(2, 3) BinaryReaderIR::PrintError(const char* format
,
408 WABT_SNPRINTF_ALLOCA(buffer
, length
, format
);
409 errors_
->emplace_back(ErrorLevel::Error
, Location(kInvalidOffset
), buffer
);
412 Result
BinaryReaderIR::PushLabel(LabelType label_type
,
415 if (label_stack_
.size() >= kMaxNestingDepth
) {
416 PrintError("label stack exceeds max nesting depth");
417 return Result::Error
;
419 label_stack_
.emplace_back(label_type
, first
, context
);
423 Result
BinaryReaderIR::PopLabel() {
424 if (label_stack_
.size() == 0) {
425 PrintError("popping empty label stack");
426 return Result::Error
;
429 label_stack_
.pop_back();
433 Result
BinaryReaderIR::GetLabelAt(LabelNode
** label
, Index depth
) {
434 if (depth
>= label_stack_
.size()) {
435 PrintError("accessing stack depth: %" PRIindex
" >= max: %" PRIzd
, depth
,
436 label_stack_
.size());
437 return Result::Error
;
440 *label
= &label_stack_
[label_stack_
.size() - depth
- 1];
444 Result
BinaryReaderIR::TopLabel(LabelNode
** label
) {
445 return GetLabelAt(label
, 0);
448 Result
BinaryReaderIR::TopLabelExpr(LabelNode
** label
, Expr
** expr
) {
449 CHECK_RESULT(TopLabel(label
));
450 LabelNode
* parent_label
;
451 CHECK_RESULT(GetLabelAt(&parent_label
, 1));
452 if (parent_label
->exprs
->empty()) {
453 PrintError("TopLabelExpr: parent label has empty expr list");
454 return Result::Error
;
456 *expr
= &parent_label
->exprs
->back();
460 Result
BinaryReaderIR::AppendExpr(std::unique_ptr
<Expr
> expr
) {
461 expr
->loc
= GetLocation();
463 CHECK_RESULT(TopLabel(&label
));
464 label
->exprs
->push_back(std::move(expr
));
468 void BinaryReaderIR::SetFuncDeclaration(FuncDeclaration
* decl
, Var var
) {
469 decl
->has_func_type
= true;
470 decl
->type_var
= var
;
471 if (auto* func_type
= module_
->GetFuncType(var
)) {
472 decl
->sig
= func_type
->sig
;
476 void BinaryReaderIR::SetBlockDeclaration(BlockDeclaration
* decl
,
478 if (sig_type
.IsIndex()) {
479 Index type_index
= sig_type
.GetIndex();
480 SetFuncDeclaration(decl
, Var(type_index
, GetLocation()));
482 decl
->has_func_type
= false;
483 decl
->sig
.param_types
.clear();
484 decl
->sig
.result_types
= sig_type
.GetInlineVector();
488 std::string
BinaryReaderIR::GetUniqueName(BindingHash
* bindings
,
489 const std::string
& orig_name
) {
491 std::string unique_name
= orig_name
;
492 while (bindings
->count(unique_name
) != 0) {
493 unique_name
= orig_name
+ "." + std::to_string(counter
++);
498 bool BinaryReaderIR::OnError(const Error
& error
) {
499 errors_
->push_back(error
);
503 Result
BinaryReaderIR::OnTypeCount(Index count
) {
505 module_
->types
.reserve(count
);
510 Result
BinaryReaderIR::OnFuncType(Index index
,
514 Type
* result_types
) {
515 if (param_count
> kMaxFunctionParams
) {
516 PrintError("FuncType param count exceeds maximum value");
517 return Result::Error
;
520 if (result_count
> kMaxFunctionResults
) {
521 PrintError("FuncType result count exceeds maximum value");
522 return Result::Error
;
525 auto field
= std::make_unique
<TypeModuleField
>(GetLocation());
526 auto func_type
= std::make_unique
<FuncType
>();
527 func_type
->sig
.param_types
.assign(param_types
, param_types
+ param_count
);
528 func_type
->sig
.result_types
.assign(result_types
, result_types
+ result_count
);
530 module_
->features_used
.simd
|=
531 std::any_of(func_type
->sig
.param_types
.begin(),
532 func_type
->sig
.param_types
.end(),
533 [](auto x
) { return x
== Type::V128
; }) ||
534 std::any_of(func_type
->sig
.result_types
.begin(),
535 func_type
->sig
.result_types
.end(),
536 [](auto x
) { return x
== Type::V128
; });
538 field
->type
= std::move(func_type
);
539 module_
->AppendField(std::move(field
));
543 Result
BinaryReaderIR::OnStructType(Index index
,
546 auto field
= std::make_unique
<TypeModuleField
>(GetLocation());
547 auto struct_type
= std::make_unique
<StructType
>();
548 struct_type
->fields
.resize(field_count
);
549 for (Index i
= 0; i
< field_count
; ++i
) {
550 struct_type
->fields
[i
].type
= fields
[i
].type
;
551 struct_type
->fields
[i
].mutable_
= fields
[i
].mutable_
;
552 module_
->features_used
.simd
|= (fields
[i
].type
== Type::V128
);
554 field
->type
= std::move(struct_type
);
555 module_
->AppendField(std::move(field
));
559 Result
BinaryReaderIR::OnArrayType(Index index
, TypeMut type_mut
) {
560 auto field
= std::make_unique
<TypeModuleField
>(GetLocation());
561 auto array_type
= std::make_unique
<ArrayType
>();
562 array_type
->field
.type
= type_mut
.type
;
563 array_type
->field
.mutable_
= type_mut
.mutable_
;
564 module_
->features_used
.simd
|= (type_mut
.type
== Type::V128
);
565 field
->type
= std::move(array_type
);
566 module_
->AppendField(std::move(field
));
570 Result
BinaryReaderIR::OnImportCount(Index count
) {
572 module_
->imports
.reserve(count
);
577 Result
BinaryReaderIR::OnImportFunc(Index import_index
,
578 std::string_view module_name
,
579 std::string_view field_name
,
582 auto import
= std::make_unique
<FuncImport
>();
583 import
->module_name
= module_name
;
584 import
->field_name
= field_name
;
585 SetFuncDeclaration(&import
->func
.decl
, Var(sig_index
, GetLocation()));
586 module_
->AppendField(
587 std::make_unique
<ImportModuleField
>(std::move(import
), GetLocation()));
591 Result
BinaryReaderIR::OnImportTable(Index import_index
,
592 std::string_view module_name
,
593 std::string_view field_name
,
596 const Limits
* elem_limits
) {
597 auto import
= std::make_unique
<TableImport
>();
598 import
->module_name
= module_name
;
599 import
->field_name
= field_name
;
600 import
->table
.elem_limits
= *elem_limits
;
601 import
->table
.elem_type
= elem_type
;
602 module_
->AppendField(
603 std::make_unique
<ImportModuleField
>(std::move(import
), GetLocation()));
607 Result
BinaryReaderIR::OnImportMemory(Index import_index
,
608 std::string_view module_name
,
609 std::string_view field_name
,
611 const Limits
* page_limits
) {
612 auto import
= std::make_unique
<MemoryImport
>();
613 import
->module_name
= module_name
;
614 import
->field_name
= field_name
;
615 import
->memory
.page_limits
= *page_limits
;
616 module_
->AppendField(
617 std::make_unique
<ImportModuleField
>(std::move(import
), GetLocation()));
621 Result
BinaryReaderIR::OnImportGlobal(Index import_index
,
622 std::string_view module_name
,
623 std::string_view field_name
,
627 auto import
= std::make_unique
<GlobalImport
>();
628 import
->module_name
= module_name
;
629 import
->field_name
= field_name
;
630 import
->global
.type
= type
;
631 import
->global
.mutable_
= mutable_
;
632 module_
->AppendField(
633 std::make_unique
<ImportModuleField
>(std::move(import
), GetLocation()));
634 module_
->features_used
.simd
|= (type
== Type::V128
);
638 Result
BinaryReaderIR::OnImportTag(Index import_index
,
639 std::string_view module_name
,
640 std::string_view field_name
,
643 auto import
= std::make_unique
<TagImport
>();
644 import
->module_name
= module_name
;
645 import
->field_name
= field_name
;
646 SetFuncDeclaration(&import
->tag
.decl
, Var(sig_index
, GetLocation()));
647 module_
->AppendField(
648 std::make_unique
<ImportModuleField
>(std::move(import
), GetLocation()));
649 module_
->features_used
.exceptions
= true;
653 Result
BinaryReaderIR::OnFunctionCount(Index count
) {
655 module_
->funcs
.reserve(module_
->num_func_imports
+ count
);
660 Result
BinaryReaderIR::OnFunction(Index index
, Index sig_index
) {
661 auto field
= std::make_unique
<FuncModuleField
>(GetLocation());
662 Func
& func
= field
->func
;
663 SetFuncDeclaration(&func
.decl
, Var(sig_index
, GetLocation()));
664 module_
->AppendField(std::move(field
));
668 Result
BinaryReaderIR::OnTableCount(Index count
) {
670 module_
->tables
.reserve(module_
->num_table_imports
+ count
);
675 Result
BinaryReaderIR::OnTable(Index index
,
677 const Limits
* elem_limits
) {
678 auto field
= std::make_unique
<TableModuleField
>(GetLocation());
679 Table
& table
= field
->table
;
680 table
.elem_limits
= *elem_limits
;
681 table
.elem_type
= elem_type
;
682 module_
->AppendField(std::move(field
));
686 Result
BinaryReaderIR::OnMemoryCount(Index count
) {
688 module_
->memories
.reserve(module_
->num_memory_imports
+ count
);
693 Result
BinaryReaderIR::OnMemory(Index index
, const Limits
* page_limits
) {
694 auto field
= std::make_unique
<MemoryModuleField
>(GetLocation());
695 Memory
& memory
= field
->memory
;
696 memory
.page_limits
= *page_limits
;
697 module_
->AppendField(std::move(field
));
701 Result
BinaryReaderIR::OnGlobalCount(Index count
) {
703 module_
->globals
.reserve(module_
->num_global_imports
+ count
);
708 Result
BinaryReaderIR::BeginGlobal(Index index
, Type type
, bool mutable_
) {
709 auto field
= std::make_unique
<GlobalModuleField
>(GetLocation());
710 Global
& global
= field
->global
;
712 global
.mutable_
= mutable_
;
713 module_
->AppendField(std::move(field
));
714 module_
->features_used
.simd
|= (type
== Type::V128
);
718 Result
BinaryReaderIR::BeginGlobalInitExpr(Index index
) {
719 assert(index
== module_
->globals
.size() - 1);
720 Global
* global
= module_
->globals
[index
];
721 return BeginInitExpr(&global
->init_expr
);
724 Result
BinaryReaderIR::EndGlobalInitExpr(Index index
) {
725 return EndInitExpr();
728 Result
BinaryReaderIR::OnExportCount(Index count
) {
730 module_
->exports
.reserve(count
);
735 Result
BinaryReaderIR::OnExport(Index index
,
738 std::string_view name
) {
739 auto field
= std::make_unique
<ExportModuleField
>(GetLocation());
740 Export
& export_
= field
->export_
;
742 export_
.var
= Var(item_index
, GetLocation());
744 module_
->AppendField(std::move(field
));
748 Result
BinaryReaderIR::OnStartFunction(Index func_index
) {
749 Var
start(func_index
, GetLocation());
750 module_
->AppendField(
751 std::make_unique
<StartModuleField
>(start
, GetLocation()));
755 Result
BinaryReaderIR::OnFunctionBodyCount(Index count
) {
756 // Can hit this case on a malformed module if we don't stop on first error.
757 if (module_
->num_func_imports
+ count
!= module_
->funcs
.size()) {
759 "number of imported func + func count in code section does not match "
760 "actual number of funcs in module");
761 return Result::Error
;
766 Result
BinaryReaderIR::BeginFunctionBody(Index index
, Offset size
) {
767 current_func_
= module_
->funcs
[index
];
768 current_func_
->loc
= GetLocation();
769 return PushLabel(LabelType::Func
, ¤t_func_
->exprs
);
772 Result
BinaryReaderIR::OnLocalDecl(Index decl_index
, Index count
, Type type
) {
773 current_func_
->local_types
.AppendDecl(type
, count
);
775 if (current_func_
->GetNumLocals() > kMaxFunctionLocals
) {
776 PrintError("function local count exceeds maximum value");
777 return Result::Error
;
780 module_
->features_used
.simd
|= (type
== Type::V128
);
784 Result
BinaryReaderIR::OnOpcode(Opcode opcode
) {
785 std::unique_ptr
<CodeMetadataExpr
> metadata
=
786 code_metadata_queue_
.pop_match(current_func_
, GetLocation().offset
- 1);
788 return AppendExpr(std::move(metadata
));
790 module_
->features_used
.simd
|= (opcode
.GetResultType() == Type::V128
);
794 Result
BinaryReaderIR::OnAtomicLoadExpr(Opcode opcode
,
796 Address alignment_log2
,
798 return AppendExpr(std::make_unique
<AtomicLoadExpr
>(
799 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
802 Result
BinaryReaderIR::OnAtomicStoreExpr(Opcode opcode
,
804 Address alignment_log2
,
806 return AppendExpr(std::make_unique
<AtomicStoreExpr
>(
807 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
810 Result
BinaryReaderIR::OnAtomicRmwExpr(Opcode opcode
,
812 Address alignment_log2
,
814 return AppendExpr(std::make_unique
<AtomicRmwExpr
>(
815 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
818 Result
BinaryReaderIR::OnAtomicRmwCmpxchgExpr(Opcode opcode
,
820 Address alignment_log2
,
822 return AppendExpr(std::make_unique
<AtomicRmwCmpxchgExpr
>(
823 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
826 Result
BinaryReaderIR::OnAtomicWaitExpr(Opcode opcode
,
828 Address alignment_log2
,
830 return AppendExpr(std::make_unique
<AtomicWaitExpr
>(
831 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
834 Result
BinaryReaderIR::OnAtomicFenceExpr(uint32_t consistency_model
) {
835 return AppendExpr(std::make_unique
<AtomicFenceExpr
>(consistency_model
));
838 Result
BinaryReaderIR::OnAtomicNotifyExpr(Opcode opcode
,
840 Address alignment_log2
,
842 return AppendExpr(std::make_unique
<AtomicNotifyExpr
>(
843 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
846 Result
BinaryReaderIR::OnBinaryExpr(Opcode opcode
) {
847 return AppendExpr(std::make_unique
<BinaryExpr
>(opcode
));
850 Result
BinaryReaderIR::OnBlockExpr(Type sig_type
) {
851 auto expr
= std::make_unique
<BlockExpr
>();
852 SetBlockDeclaration(&expr
->block
.decl
, sig_type
);
853 ExprList
* expr_list
= &expr
->block
.exprs
;
854 CHECK_RESULT(AppendExpr(std::move(expr
)));
855 return PushLabel(LabelType::Block
, expr_list
);
858 Result
BinaryReaderIR::OnBrExpr(Index depth
) {
859 return AppendExpr(std::make_unique
<BrExpr
>(Var(depth
, GetLocation())));
862 Result
BinaryReaderIR::OnBrIfExpr(Index depth
) {
863 return AppendExpr(std::make_unique
<BrIfExpr
>(Var(depth
, GetLocation())));
866 Result
BinaryReaderIR::OnBrTableExpr(Index num_targets
,
867 Index
* target_depths
,
868 Index default_target_depth
) {
869 auto expr
= std::make_unique
<BrTableExpr
>();
870 expr
->default_target
= Var(default_target_depth
, GetLocation());
871 expr
->targets
.resize(num_targets
);
872 for (Index i
= 0; i
< num_targets
; ++i
) {
873 expr
->targets
[i
] = Var(target_depths
[i
], GetLocation());
875 return AppendExpr(std::move(expr
));
878 Result
BinaryReaderIR::OnCallExpr(Index func_index
) {
879 return AppendExpr(std::make_unique
<CallExpr
>(Var(func_index
, GetLocation())));
882 Result
BinaryReaderIR::OnCallIndirectExpr(Index sig_index
, Index table_index
) {
883 auto expr
= std::make_unique
<CallIndirectExpr
>();
884 SetFuncDeclaration(&expr
->decl
, Var(sig_index
, GetLocation()));
885 expr
->table
= Var(table_index
, GetLocation());
886 return AppendExpr(std::move(expr
));
889 Result
BinaryReaderIR::OnCallRefExpr() {
890 return AppendExpr(std::make_unique
<CallRefExpr
>());
893 Result
BinaryReaderIR::OnReturnCallExpr(Index func_index
) {
895 std::make_unique
<ReturnCallExpr
>(Var(func_index
, GetLocation())));
898 Result
BinaryReaderIR::OnReturnCallIndirectExpr(Index sig_index
,
900 auto expr
= std::make_unique
<ReturnCallIndirectExpr
>();
901 SetFuncDeclaration(&expr
->decl
, Var(sig_index
, GetLocation()));
902 expr
->table
= Var(table_index
, GetLocation());
903 return AppendExpr(std::move(expr
));
906 Result
BinaryReaderIR::OnCompareExpr(Opcode opcode
) {
907 return AppendExpr(std::make_unique
<CompareExpr
>(opcode
));
910 Result
BinaryReaderIR::OnConvertExpr(Opcode opcode
) {
911 return AppendExpr(std::make_unique
<ConvertExpr
>(opcode
));
914 Result
BinaryReaderIR::OnDropExpr() {
915 return AppendExpr(std::make_unique
<DropExpr
>());
918 Result
BinaryReaderIR::OnElseExpr() {
921 CHECK_RESULT(TopLabelExpr(&label
, &expr
));
923 if (label
->label_type
== LabelType::If
) {
924 auto* if_expr
= cast
<IfExpr
>(expr
);
925 if_expr
->true_
.end_loc
= GetLocation();
926 label
->exprs
= &if_expr
->false_
;
927 label
->label_type
= LabelType::Else
;
929 PrintError("else expression without matching if");
930 return Result::Error
;
936 Result
BinaryReaderIR::OnEndExpr() {
937 if (label_stack_
.size() > 1) {
940 CHECK_RESULT(TopLabelExpr(&label
, &expr
));
941 switch (label
->label_type
) {
942 case LabelType::Block
:
943 cast
<BlockExpr
>(expr
)->block
.end_loc
= GetLocation();
945 case LabelType::Loop
:
946 cast
<LoopExpr
>(expr
)->block
.end_loc
= GetLocation();
949 cast
<IfExpr
>(expr
)->true_
.end_loc
= GetLocation();
951 case LabelType::Else
:
952 cast
<IfExpr
>(expr
)->false_end_loc
= GetLocation();
955 cast
<TryExpr
>(expr
)->block
.end_loc
= GetLocation();
958 case LabelType::InitExpr
:
959 case LabelType::Func
:
960 case LabelType::Catch
:
968 Result
BinaryReaderIR::OnF32ConstExpr(uint32_t value_bits
) {
970 std::make_unique
<ConstExpr
>(Const::F32(value_bits
, GetLocation())));
973 Result
BinaryReaderIR::OnF64ConstExpr(uint64_t value_bits
) {
975 std::make_unique
<ConstExpr
>(Const::F64(value_bits
, GetLocation())));
978 Result
BinaryReaderIR::OnV128ConstExpr(v128 value_bits
) {
980 std::make_unique
<ConstExpr
>(Const::V128(value_bits
, GetLocation())));
983 Result
BinaryReaderIR::OnGlobalGetExpr(Index global_index
) {
985 std::make_unique
<GlobalGetExpr
>(Var(global_index
, GetLocation())));
988 Result
BinaryReaderIR::OnLocalGetExpr(Index local_index
) {
990 std::make_unique
<LocalGetExpr
>(Var(local_index
, GetLocation())));
993 Result
BinaryReaderIR::OnI32ConstExpr(uint32_t value
) {
995 std::make_unique
<ConstExpr
>(Const::I32(value
, GetLocation())));
998 Result
BinaryReaderIR::OnI64ConstExpr(uint64_t value
) {
1000 std::make_unique
<ConstExpr
>(Const::I64(value
, GetLocation())));
1003 Result
BinaryReaderIR::OnIfExpr(Type sig_type
) {
1004 auto expr
= std::make_unique
<IfExpr
>();
1005 SetBlockDeclaration(&expr
->true_
.decl
, sig_type
);
1006 ExprList
* expr_list
= &expr
->true_
.exprs
;
1007 CHECK_RESULT(AppendExpr(std::move(expr
)));
1008 return PushLabel(LabelType::If
, expr_list
);
1011 Result
BinaryReaderIR::OnLoadExpr(Opcode opcode
,
1013 Address alignment_log2
,
1015 return AppendExpr(std::make_unique
<LoadExpr
>(
1016 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
1019 Result
BinaryReaderIR::OnLoopExpr(Type sig_type
) {
1020 auto expr
= std::make_unique
<LoopExpr
>();
1021 SetBlockDeclaration(&expr
->block
.decl
, sig_type
);
1022 ExprList
* expr_list
= &expr
->block
.exprs
;
1023 CHECK_RESULT(AppendExpr(std::move(expr
)));
1024 return PushLabel(LabelType::Loop
, expr_list
);
1027 Result
BinaryReaderIR::OnMemoryCopyExpr(Index srcmemidx
, Index destmemidx
) {
1028 return AppendExpr(std::make_unique
<MemoryCopyExpr
>(
1029 Var(srcmemidx
, GetLocation()), Var(destmemidx
, GetLocation())));
1032 Result
BinaryReaderIR::OnDataDropExpr(Index segment
) {
1034 std::make_unique
<DataDropExpr
>(Var(segment
, GetLocation())));
1037 Result
BinaryReaderIR::OnMemoryFillExpr(Index memidx
) {
1039 std::make_unique
<MemoryFillExpr
>(Var(memidx
, GetLocation())));
1042 Result
BinaryReaderIR::OnMemoryGrowExpr(Index memidx
) {
1044 std::make_unique
<MemoryGrowExpr
>(Var(memidx
, GetLocation())));
1047 Result
BinaryReaderIR::OnMemoryInitExpr(Index segment
, Index memidx
) {
1048 return AppendExpr(std::make_unique
<MemoryInitExpr
>(
1049 Var(segment
, GetLocation()), Var(memidx
, GetLocation())));
1052 Result
BinaryReaderIR::OnMemorySizeExpr(Index memidx
) {
1054 std::make_unique
<MemorySizeExpr
>(Var(memidx
, GetLocation())));
1057 Result
BinaryReaderIR::OnTableCopyExpr(Index dst_index
, Index src_index
) {
1058 return AppendExpr(std::make_unique
<TableCopyExpr
>(
1059 Var(dst_index
, GetLocation()), Var(src_index
, GetLocation())));
1062 Result
BinaryReaderIR::OnElemDropExpr(Index segment
) {
1064 std::make_unique
<ElemDropExpr
>(Var(segment
, GetLocation())));
1067 Result
BinaryReaderIR::OnTableInitExpr(Index segment
, Index table_index
) {
1068 return AppendExpr(std::make_unique
<TableInitExpr
>(
1069 Var(segment
, GetLocation()), Var(table_index
, GetLocation())));
1072 Result
BinaryReaderIR::OnTableGetExpr(Index table_index
) {
1074 std::make_unique
<TableGetExpr
>(Var(table_index
, GetLocation())));
1077 Result
BinaryReaderIR::OnTableSetExpr(Index table_index
) {
1079 std::make_unique
<TableSetExpr
>(Var(table_index
, GetLocation())));
1082 Result
BinaryReaderIR::OnTableGrowExpr(Index table_index
) {
1084 std::make_unique
<TableGrowExpr
>(Var(table_index
, GetLocation())));
1087 Result
BinaryReaderIR::OnTableSizeExpr(Index table_index
) {
1089 std::make_unique
<TableSizeExpr
>(Var(table_index
, GetLocation())));
1092 Result
BinaryReaderIR::OnTableFillExpr(Index table_index
) {
1094 std::make_unique
<TableFillExpr
>(Var(table_index
, GetLocation())));
1097 Result
BinaryReaderIR::OnRefFuncExpr(Index func_index
) {
1099 std::make_unique
<RefFuncExpr
>(Var(func_index
, GetLocation())));
1102 Result
BinaryReaderIR::OnRefNullExpr(Type type
) {
1103 return AppendExpr(std::make_unique
<RefNullExpr
>(type
));
1106 Result
BinaryReaderIR::OnRefIsNullExpr() {
1107 return AppendExpr(std::make_unique
<RefIsNullExpr
>());
1110 Result
BinaryReaderIR::OnNopExpr() {
1111 return AppendExpr(std::make_unique
<NopExpr
>());
1114 Result
BinaryReaderIR::OnRethrowExpr(Index depth
) {
1115 return AppendExpr(std::make_unique
<RethrowExpr
>(Var(depth
, GetLocation())));
1118 Result
BinaryReaderIR::OnReturnExpr() {
1119 return AppendExpr(std::make_unique
<ReturnExpr
>());
1122 Result
BinaryReaderIR::OnSelectExpr(Index result_count
, Type
* result_types
) {
1124 results
.assign(result_types
, result_types
+ result_count
);
1125 return AppendExpr(std::make_unique
<SelectExpr
>(results
));
1128 Result
BinaryReaderIR::OnGlobalSetExpr(Index global_index
) {
1130 std::make_unique
<GlobalSetExpr
>(Var(global_index
, GetLocation())));
1133 Result
BinaryReaderIR::OnLocalSetExpr(Index local_index
) {
1135 std::make_unique
<LocalSetExpr
>(Var(local_index
, GetLocation())));
1138 Result
BinaryReaderIR::OnStoreExpr(Opcode opcode
,
1140 Address alignment_log2
,
1142 return AppendExpr(std::make_unique
<StoreExpr
>(
1143 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
1146 Result
BinaryReaderIR::OnThrowExpr(Index tag_index
) {
1147 return AppendExpr(std::make_unique
<ThrowExpr
>(Var(tag_index
, GetLocation())));
1150 Result
BinaryReaderIR::OnLocalTeeExpr(Index local_index
) {
1152 std::make_unique
<LocalTeeExpr
>(Var(local_index
, GetLocation())));
1155 Result
BinaryReaderIR::OnTryExpr(Type sig_type
) {
1156 auto expr_ptr
= std::make_unique
<TryExpr
>();
1157 // Save expr so it can be used below, after expr_ptr has been moved.
1158 TryExpr
* expr
= expr_ptr
.get();
1159 ExprList
* expr_list
= &expr
->block
.exprs
;
1160 SetBlockDeclaration(&expr
->block
.decl
, sig_type
);
1161 CHECK_RESULT(AppendExpr(std::move(expr_ptr
)));
1162 module_
->features_used
.exceptions
= true;
1163 return PushLabel(LabelType::Try
, expr_list
, expr
);
1166 Result
BinaryReaderIR::AppendCatch(Catch
&& catch_
) {
1167 LabelNode
* label
= nullptr;
1168 CHECK_RESULT(TopLabel(&label
));
1170 if (label
->label_type
!= LabelType::Try
) {
1171 PrintError("catch not inside try block");
1172 return Result::Error
;
1175 auto* try_
= cast
<TryExpr
>(label
->context
);
1177 if (catch_
.IsCatchAll() && !try_
->catches
.empty() &&
1178 try_
->catches
.back().IsCatchAll()) {
1179 PrintError("only one catch_all allowed in try block");
1180 return Result::Error
;
1183 if (try_
->kind
== TryKind::Plain
) {
1184 try_
->kind
= TryKind::Catch
;
1185 } else if (try_
->kind
!= TryKind::Catch
) {
1186 PrintError("catch not allowed in try-delegate");
1187 return Result::Error
;
1190 try_
->catches
.push_back(std::move(catch_
));
1191 label
->exprs
= &try_
->catches
.back().exprs
;
1195 Result
BinaryReaderIR::OnCatchExpr(Index except_index
) {
1196 return AppendCatch(Catch(Var(except_index
, GetLocation())));
1199 Result
BinaryReaderIR::OnCatchAllExpr() {
1200 return AppendCatch(Catch(GetLocation()));
1203 Result
BinaryReaderIR::OnDelegateExpr(Index depth
) {
1204 LabelNode
* label
= nullptr;
1205 CHECK_RESULT(TopLabel(&label
));
1207 if (label
->label_type
!= LabelType::Try
) {
1208 PrintError("delegate not inside try block");
1209 return Result::Error
;
1212 auto* try_
= cast
<TryExpr
>(label
->context
);
1214 if (try_
->kind
== TryKind::Plain
) {
1215 try_
->kind
= TryKind::Delegate
;
1216 } else if (try_
->kind
!= TryKind::Delegate
) {
1217 PrintError("delegate not allowed in try-catch");
1218 return Result::Error
;
1221 try_
->delegate_target
= Var(depth
, GetLocation());
1227 Result
BinaryReaderIR::OnUnaryExpr(Opcode opcode
) {
1228 return AppendExpr(std::make_unique
<UnaryExpr
>(opcode
));
1231 Result
BinaryReaderIR::OnTernaryExpr(Opcode opcode
) {
1232 return AppendExpr(std::make_unique
<TernaryExpr
>(opcode
));
1235 Result
BinaryReaderIR::OnUnreachableExpr() {
1236 return AppendExpr(std::make_unique
<UnreachableExpr
>());
1239 Result
BinaryReaderIR::EndFunctionBody(Index index
) {
1240 current_func_
= nullptr;
1241 if (!label_stack_
.empty()) {
1242 PrintError("function %" PRIindex
" missing end marker", index
);
1243 return Result::Error
;
1248 Result
BinaryReaderIR::OnSimdLaneOpExpr(Opcode opcode
, uint64_t value
) {
1249 return AppendExpr(std::make_unique
<SimdLaneOpExpr
>(opcode
, value
));
1252 Result
BinaryReaderIR::OnSimdLoadLaneExpr(Opcode opcode
,
1254 Address alignment_log2
,
1257 return AppendExpr(std::make_unique
<SimdLoadLaneExpr
>(
1258 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
, value
));
1261 Result
BinaryReaderIR::OnSimdStoreLaneExpr(Opcode opcode
,
1263 Address alignment_log2
,
1266 return AppendExpr(std::make_unique
<SimdStoreLaneExpr
>(
1267 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
, value
));
1270 Result
BinaryReaderIR::OnSimdShuffleOpExpr(Opcode opcode
, v128 value
) {
1271 return AppendExpr(std::make_unique
<SimdShuffleOpExpr
>(opcode
, value
));
1274 Result
BinaryReaderIR::OnLoadSplatExpr(Opcode opcode
,
1276 Address alignment_log2
,
1278 return AppendExpr(std::make_unique
<LoadSplatExpr
>(
1279 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
1282 Result
BinaryReaderIR::OnLoadZeroExpr(Opcode opcode
,
1284 Address alignment_log2
,
1286 return AppendExpr(std::make_unique
<LoadZeroExpr
>(
1287 opcode
, Var(memidx
, GetLocation()), 1 << alignment_log2
, offset
));
1290 Result
BinaryReaderIR::OnElemSegmentCount(Index count
) {
1292 module_
->elem_segments
.reserve(count
);
1293 WABT_CATCH_BAD_ALLOC
1297 Result
BinaryReaderIR::BeginElemSegment(Index index
,
1300 auto field
= std::make_unique
<ElemSegmentModuleField
>(GetLocation());
1301 ElemSegment
& elem_segment
= field
->elem_segment
;
1302 elem_segment
.table_var
= Var(table_index
, GetLocation());
1303 if ((flags
& SegDeclared
) == SegDeclared
) {
1304 elem_segment
.kind
= SegmentKind::Declared
;
1305 } else if ((flags
& SegPassive
) == SegPassive
) {
1306 elem_segment
.kind
= SegmentKind::Passive
;
1308 elem_segment
.kind
= SegmentKind::Active
;
1310 module_
->AppendField(std::move(field
));
1314 Result
BinaryReaderIR::BeginInitExpr(ExprList
* expr
) {
1315 return PushLabel(LabelType::InitExpr
, expr
);
1318 Result
BinaryReaderIR::BeginElemSegmentInitExpr(Index index
) {
1319 assert(index
== module_
->elem_segments
.size() - 1);
1320 ElemSegment
* segment
= module_
->elem_segments
[index
];
1321 return BeginInitExpr(&segment
->offset
);
1324 Result
BinaryReaderIR::EndInitExpr() {
1325 if (!label_stack_
.empty()) {
1326 PrintError("init expression missing end marker");
1327 return Result::Error
;
1332 Result
BinaryReaderIR::EndElemSegmentInitExpr(Index index
) {
1333 return EndInitExpr();
1336 Result
BinaryReaderIR::OnElemSegmentElemType(Index index
, Type elem_type
) {
1337 assert(index
== module_
->elem_segments
.size() - 1);
1338 ElemSegment
* segment
= module_
->elem_segments
[index
];
1339 segment
->elem_type
= elem_type
;
1343 Result
BinaryReaderIR::OnElemSegmentElemExprCount(Index index
, Index count
) {
1344 assert(index
== module_
->elem_segments
.size() - 1);
1345 ElemSegment
* segment
= module_
->elem_segments
[index
];
1347 segment
->elem_exprs
.reserve(count
);
1348 WABT_CATCH_BAD_ALLOC
1352 Result
BinaryReaderIR::OnElemSegmentElemExpr_RefNull(Index segment_index
,
1354 assert(segment_index
== module_
->elem_segments
.size() - 1);
1355 ElemSegment
* segment
= module_
->elem_segments
[segment_index
];
1356 Location loc
= GetLocation();
1358 init_expr
.push_back(std::make_unique
<RefNullExpr
>(type
, loc
));
1359 segment
->elem_exprs
.push_back(std::move(init_expr
));
1363 Result
BinaryReaderIR::OnElemSegmentElemExpr_RefFunc(Index segment_index
,
1365 assert(segment_index
== module_
->elem_segments
.size() - 1);
1366 ElemSegment
* segment
= module_
->elem_segments
[segment_index
];
1367 Location loc
= GetLocation();
1369 init_expr
.push_back(std::make_unique
<RefFuncExpr
>(Var(func_index
, loc
), loc
));
1370 segment
->elem_exprs
.push_back(std::move(init_expr
));
1374 Result
BinaryReaderIR::OnDataSegmentCount(Index count
) {
1376 module_
->data_segments
.reserve(count
);
1377 WABT_CATCH_BAD_ALLOC
1381 Result
BinaryReaderIR::BeginDataSegment(Index index
,
1384 auto field
= std::make_unique
<DataSegmentModuleField
>(GetLocation());
1385 DataSegment
& data_segment
= field
->data_segment
;
1386 data_segment
.memory_var
= Var(memory_index
, GetLocation());
1387 if ((flags
& SegPassive
) == SegPassive
) {
1388 data_segment
.kind
= SegmentKind::Passive
;
1390 data_segment
.kind
= SegmentKind::Active
;
1392 module_
->AppendField(std::move(field
));
1396 Result
BinaryReaderIR::BeginDataSegmentInitExpr(Index index
) {
1397 assert(index
== module_
->data_segments
.size() - 1);
1398 DataSegment
* segment
= module_
->data_segments
[index
];
1399 return BeginInitExpr(&segment
->offset
);
1402 Result
BinaryReaderIR::EndDataSegmentInitExpr(Index index
) {
1403 return EndInitExpr();
1406 Result
BinaryReaderIR::OnDataSegmentData(Index index
,
1409 assert(index
== module_
->data_segments
.size() - 1);
1410 DataSegment
* segment
= module_
->data_segments
[index
];
1411 segment
->data
.resize(size
);
1413 memcpy(segment
->data
.data(), data
, size
);
1418 Result
BinaryReaderIR::OnFunctionNamesCount(Index count
) {
1419 if (count
> module_
->funcs
.size()) {
1420 PrintError("expected function name count (%" PRIindex
1421 ") <= function count (%" PRIzd
")",
1422 count
, module_
->funcs
.size());
1423 return Result::Error
;
1428 static std::string
MakeDollarName(std::string_view name
) {
1429 return std::string("$") + std::string(name
);
1432 Result
BinaryReaderIR::OnModuleName(std::string_view name
) {
1437 module_
->name
= MakeDollarName(name
);
1441 Result
BinaryReaderIR::SetGlobalName(Index index
, std::string_view name
) {
1445 if (index
>= module_
->globals
.size()) {
1446 PrintError("invalid global index: %" PRIindex
, index
);
1447 return Result::Error
;
1449 Global
* glob
= module_
->globals
[index
];
1450 std::string dollar_name
=
1451 GetUniqueName(&module_
->global_bindings
, MakeDollarName(name
));
1452 glob
->name
= dollar_name
;
1453 module_
->global_bindings
.emplace(dollar_name
, Binding(index
));
1457 Result
BinaryReaderIR::SetFunctionName(Index index
, std::string_view name
) {
1461 if (index
>= module_
->funcs
.size()) {
1462 PrintError("invalid function index: %" PRIindex
, index
);
1463 return Result::Error
;
1465 Func
* func
= module_
->funcs
[index
];
1466 std::string dollar_name
=
1467 GetUniqueName(&module_
->func_bindings
, MakeDollarName(name
));
1468 func
->name
= dollar_name
;
1469 module_
->func_bindings
.emplace(dollar_name
, Binding(index
));
1473 Result
BinaryReaderIR::SetTypeName(Index index
, std::string_view name
) {
1477 if (index
>= module_
->types
.size()) {
1478 PrintError("invalid type index: %" PRIindex
, index
);
1479 return Result::Error
;
1481 TypeEntry
* type
= module_
->types
[index
];
1482 std::string dollar_name
=
1483 GetUniqueName(&module_
->type_bindings
, MakeDollarName(name
));
1484 type
->name
= dollar_name
;
1485 module_
->type_bindings
.emplace(dollar_name
, Binding(index
));
1489 Result
BinaryReaderIR::SetTableName(Index index
, std::string_view name
) {
1493 if (index
>= module_
->tables
.size()) {
1494 PrintError("invalid table index: %" PRIindex
, index
);
1495 return Result::Error
;
1497 Table
* table
= module_
->tables
[index
];
1498 std::string dollar_name
=
1499 GetUniqueName(&module_
->table_bindings
, MakeDollarName(name
));
1500 table
->name
= dollar_name
;
1501 module_
->table_bindings
.emplace(dollar_name
, Binding(index
));
1505 Result
BinaryReaderIR::SetDataSegmentName(Index index
, std::string_view name
) {
1509 if (index
>= module_
->data_segments
.size()) {
1510 PrintError("invalid data segment index: %" PRIindex
, index
);
1511 return Result::Error
;
1513 DataSegment
* segment
= module_
->data_segments
[index
];
1514 std::string dollar_name
=
1515 GetUniqueName(&module_
->data_segment_bindings
, MakeDollarName(name
));
1516 segment
->name
= dollar_name
;
1517 module_
->data_segment_bindings
.emplace(dollar_name
, Binding(index
));
1521 Result
BinaryReaderIR::SetElemSegmentName(Index index
, std::string_view name
) {
1525 if (index
>= module_
->elem_segments
.size()) {
1526 PrintError("invalid elem segment index: %" PRIindex
, index
);
1527 return Result::Error
;
1529 ElemSegment
* segment
= module_
->elem_segments
[index
];
1530 std::string dollar_name
=
1531 GetUniqueName(&module_
->elem_segment_bindings
, MakeDollarName(name
));
1532 segment
->name
= dollar_name
;
1533 module_
->elem_segment_bindings
.emplace(dollar_name
, Binding(index
));
1537 Result
BinaryReaderIR::SetMemoryName(Index index
, std::string_view name
) {
1541 if (index
>= module_
->memories
.size()) {
1542 PrintError("invalid memory index: %" PRIindex
, index
);
1543 return Result::Error
;
1545 Memory
* memory
= module_
->memories
[index
];
1546 std::string dollar_name
=
1547 GetUniqueName(&module_
->memory_bindings
, MakeDollarName(name
));
1548 memory
->name
= dollar_name
;
1549 module_
->memory_bindings
.emplace(dollar_name
, Binding(index
));
1553 Result
BinaryReaderIR::SetTagName(Index index
, std::string_view name
) {
1557 if (index
>= module_
->tags
.size()) {
1558 PrintError("invalid tag index: %" PRIindex
, index
);
1559 return Result::Error
;
1561 Tag
* tag
= module_
->tags
[index
];
1562 std::string dollar_name
=
1563 GetUniqueName(&module_
->tag_bindings
, MakeDollarName(name
));
1564 tag
->name
= dollar_name
;
1565 module_
->tag_bindings
.emplace(dollar_name
, Binding(index
));
1569 Result
BinaryReaderIR::OnFunctionName(Index index
, std::string_view name
) {
1570 return SetFunctionName(index
, name
);
1573 Result
BinaryReaderIR::OnNameEntry(NameSectionSubsection type
,
1575 std::string_view name
) {
1577 // TODO(sbc): remove OnFunctionName in favor of just using
1578 // OnNameEntry so that this works
1579 case NameSectionSubsection::Function
:
1580 case NameSectionSubsection::Local
:
1581 case NameSectionSubsection::Module
:
1582 case NameSectionSubsection::Label
:
1584 case NameSectionSubsection::Type
:
1585 SetTypeName(index
, name
);
1587 case NameSectionSubsection::Tag
:
1588 SetTagName(index
, name
);
1590 case NameSectionSubsection::Global
:
1591 SetGlobalName(index
, name
);
1593 case NameSectionSubsection::Table
:
1594 SetTableName(index
, name
);
1596 case NameSectionSubsection::DataSegment
:
1597 SetDataSegmentName(index
, name
);
1599 case NameSectionSubsection::Memory
:
1600 SetMemoryName(index
, name
);
1602 case NameSectionSubsection::ElemSegment
:
1603 SetElemSegmentName(index
, name
);
1609 Result
BinaryReaderIR::OnLocalNameLocalCount(Index index
, Index count
) {
1610 assert(index
< module_
->funcs
.size());
1611 Func
* func
= module_
->funcs
[index
];
1612 Index num_params_and_locals
= func
->GetNumParamsAndLocals();
1613 if (count
> num_params_and_locals
) {
1614 PrintError("expected local name count (%" PRIindex
1615 ") <= local count (%" PRIindex
")",
1616 count
, num_params_and_locals
);
1617 return Result::Error
;
1622 Result
BinaryReaderIR::BeginCodeMetadataSection(std::string_view name
,
1624 current_metadata_name_
= name
;
1628 Result
BinaryReaderIR::OnCodeMetadataFuncCount(Index count
) {
1632 Result
BinaryReaderIR::OnCodeMetadataCount(Index function_index
, Index count
) {
1633 code_metadata_queue_
.push_func(module_
->funcs
[function_index
]);
1637 Result
BinaryReaderIR::OnCodeMetadata(Offset offset
,
1640 std::vector
<uint8_t> data_(static_cast<const uint8_t*>(data
),
1641 static_cast<const uint8_t*>(data
) + size
);
1642 auto meta
= std::make_unique
<CodeMetadataExpr
>(current_metadata_name_
,
1644 meta
->loc
.offset
= offset
;
1645 code_metadata_queue_
.push_metadata(std::move(meta
));
1649 Result
BinaryReaderIR::OnLocalName(Index func_index
,
1651 std::string_view name
) {
1656 Func
* func
= module_
->funcs
[func_index
];
1657 func
->bindings
.emplace(GetUniqueName(&func
->bindings
, MakeDollarName(name
)),
1658 Binding(local_index
));
1662 Result
BinaryReaderIR::OnTagType(Index index
, Index sig_index
) {
1663 auto field
= std::make_unique
<TagModuleField
>(GetLocation());
1664 Tag
& tag
= field
->tag
;
1665 SetFuncDeclaration(&tag
.decl
, Var(sig_index
, GetLocation()));
1666 module_
->AppendField(std::move(field
));
1667 module_
->features_used
.exceptions
= true;
1671 Result
BinaryReaderIR::OnDataSymbol(Index index
,
1673 std::string_view name
,
1680 if (flags
& WABT_SYMBOL_FLAG_UNDEFINED
) {
1681 // Refers to data in another file, `segment` not valid.
1685 // If it is pointing into the data segment, then it's not really naming
1686 // the whole segment.
1689 if (segment
>= module_
->data_segments
.size()) {
1690 PrintError("invalid data segment index: %" PRIindex
, segment
);
1691 return Result::Error
;
1693 DataSegment
* seg
= module_
->data_segments
[segment
];
1694 std::string dollar_name
=
1695 GetUniqueName(&module_
->data_segment_bindings
, MakeDollarName(name
));
1696 seg
->name
= dollar_name
;
1697 module_
->data_segment_bindings
.emplace(dollar_name
, Binding(segment
));
1701 Result
BinaryReaderIR::OnFunctionSymbol(Index index
,
1703 std::string_view name
,
1708 if (func_index
>= module_
->funcs
.size()) {
1709 PrintError("invalid function index: %" PRIindex
, func_index
);
1710 return Result::Error
;
1712 Func
* func
= module_
->funcs
[func_index
];
1713 if (!func
->name
.empty()) {
1714 // The name section has already named this function.
1717 std::string dollar_name
=
1718 GetUniqueName(&module_
->func_bindings
, MakeDollarName(name
));
1719 func
->name
= dollar_name
;
1720 module_
->func_bindings
.emplace(dollar_name
, Binding(func_index
));
1724 Result
BinaryReaderIR::OnGlobalSymbol(Index index
,
1726 std::string_view name
,
1727 Index global_index
) {
1728 return SetGlobalName(global_index
, name
);
1731 Result
BinaryReaderIR::OnSectionSymbol(Index index
,
1733 Index section_index
) {
1737 Result
BinaryReaderIR::OnTagSymbol(Index index
,
1739 std::string_view name
,
1744 if (tag_index
>= module_
->tags
.size()) {
1745 PrintError("invalid tag index: %" PRIindex
, tag_index
);
1746 return Result::Error
;
1748 Tag
* tag
= module_
->tags
[tag_index
];
1749 std::string dollar_name
=
1750 GetUniqueName(&module_
->tag_bindings
, MakeDollarName(name
));
1751 tag
->name
= dollar_name
;
1752 module_
->tag_bindings
.emplace(dollar_name
, Binding(tag_index
));
1756 Result
BinaryReaderIR::OnTableSymbol(Index index
,
1758 std::string_view name
,
1759 Index table_index
) {
1760 return SetTableName(table_index
, name
);
1763 } // end anonymous namespace
1765 Result
ReadBinaryIr(const char* filename
,
1768 const ReadBinaryOptions
& options
,
1770 Module
* out_module
) {
1771 BinaryReaderIR
reader(out_module
, filename
, errors
);
1772 return ReadBinary(data
, size
, &reader
, options
);