summaryrefslogtreecommitdiffstats
path: root/third_party/wasm2c/src/apply-names.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/wasm2c/src/apply-names.cc')
-rw-r--r--third_party/wasm2c/src/apply-names.cc581
1 files changed, 581 insertions, 0 deletions
diff --git a/third_party/wasm2c/src/apply-names.cc b/third_party/wasm2c/src/apply-names.cc
new file mode 100644
index 0000000000..506ab1fe71
--- /dev/null
+++ b/third_party/wasm2c/src/apply-names.cc
@@ -0,0 +1,581 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "wabt/apply-names.h"
+
+#include <cassert>
+#include <cstdio>
+#include <string_view>
+#include <vector>
+
+#include "wabt/cast.h"
+#include "wabt/expr-visitor.h"
+#include "wabt/ir.h"
+
+namespace wabt {
+
+namespace {
+
+class NameApplier : public ExprVisitor::DelegateNop {
+ public:
+ NameApplier();
+
+ Result VisitModule(Module* module);
+
+ // Implementation of ExprVisitor::DelegateNop.
+ Result BeginBlockExpr(BlockExpr*) override;
+ Result EndBlockExpr(BlockExpr*) override;
+ Result OnBrExpr(BrExpr*) override;
+ Result OnBrIfExpr(BrIfExpr*) override;
+ Result OnBrTableExpr(BrTableExpr*) override;
+ Result OnCallExpr(CallExpr*) override;
+ Result OnRefFuncExpr(RefFuncExpr*) override;
+ Result OnCallIndirectExpr(CallIndirectExpr*) override;
+ Result OnReturnCallExpr(ReturnCallExpr*) override;
+ Result OnReturnCallIndirectExpr(ReturnCallIndirectExpr*) override;
+ Result OnGlobalGetExpr(GlobalGetExpr*) override;
+ Result OnGlobalSetExpr(GlobalSetExpr*) override;
+ Result BeginIfExpr(IfExpr*) override;
+ Result EndIfExpr(IfExpr*) override;
+ Result OnLoadExpr(LoadExpr*) override;
+ Result OnLocalGetExpr(LocalGetExpr*) override;
+ Result OnLocalSetExpr(LocalSetExpr*) override;
+ Result OnLocalTeeExpr(LocalTeeExpr*) override;
+ Result BeginLoopExpr(LoopExpr*) override;
+ Result EndLoopExpr(LoopExpr*) override;
+ Result OnMemoryCopyExpr(MemoryCopyExpr*) override;
+ Result OnDataDropExpr(DataDropExpr*) override;
+ Result OnMemoryFillExpr(MemoryFillExpr*) override;
+ Result OnMemoryGrowExpr(MemoryGrowExpr*) override;
+ Result OnMemoryInitExpr(MemoryInitExpr*) override;
+ Result OnMemorySizeExpr(MemorySizeExpr*) override;
+ Result OnElemDropExpr(ElemDropExpr*) override;
+ Result OnTableCopyExpr(TableCopyExpr*) override;
+ Result OnTableInitExpr(TableInitExpr*) override;
+ Result OnTableGetExpr(TableGetExpr*) override;
+ Result OnTableSetExpr(TableSetExpr*) override;
+ Result OnTableGrowExpr(TableGrowExpr*) override;
+ Result OnTableSizeExpr(TableSizeExpr*) override;
+ Result OnTableFillExpr(TableFillExpr*) override;
+ Result OnStoreExpr(StoreExpr*) override;
+ Result BeginTryExpr(TryExpr*) override;
+ Result EndTryExpr(TryExpr*) override;
+ Result OnCatchExpr(TryExpr*, Catch*) override;
+ Result OnDelegateExpr(TryExpr*) override;
+ Result OnThrowExpr(ThrowExpr*) override;
+ Result OnRethrowExpr(RethrowExpr*) override;
+ Result OnSimdLoadLaneExpr(SimdLoadLaneExpr*) override;
+ Result OnSimdStoreLaneExpr(SimdStoreLaneExpr*) override;
+
+ private:
+ void PushLabel(const std::string& label);
+ void PopLabel();
+ std::string_view FindLabelByVar(Var* var);
+ void UseNameForVar(std::string_view name, Var* var);
+ Result UseNameForFuncTypeVar(Var* var);
+ Result UseNameForFuncVar(Var* var);
+ Result UseNameForGlobalVar(Var* var);
+ Result UseNameForTableVar(Var* var);
+ Result UseNameForMemoryVar(Var* var);
+ Result UseNameForTagVar(Var* var);
+ Result UseNameForDataSegmentVar(Var* var);
+ Result UseNameForElemSegmentVar(Var* var);
+ Result UseNameForParamAndLocalVar(Func* func, Var* var);
+ Result VisitFunc(Index func_index, Func* func);
+ Result VisitGlobal(Global* global);
+ Result VisitTag(Tag* tag);
+ Result VisitExport(Index export_index, Export* export_);
+ Result VisitElemSegment(Index elem_segment_index, ElemSegment* segment);
+ Result VisitDataSegment(Index data_segment_index, DataSegment* segment);
+ Result VisitStart(Var* start_var);
+
+ Module* module_ = nullptr;
+ Func* current_func_ = nullptr;
+ ExprVisitor visitor_;
+ std::vector<std::string> param_and_local_index_to_name_;
+ std::vector<std::string> labels_;
+};
+
+NameApplier::NameApplier() : visitor_(this) {}
+
+void NameApplier::PushLabel(const std::string& label) {
+ labels_.push_back(label);
+}
+
+void NameApplier::PopLabel() {
+ labels_.pop_back();
+}
+
+std::string_view NameApplier::FindLabelByVar(Var* var) {
+ if (var->is_name()) {
+ for (int i = labels_.size() - 1; i >= 0; --i) {
+ const std::string& label = labels_[i];
+ if (label == var->name()) {
+ return label;
+ }
+ }
+ return std::string_view();
+ } else {
+ if (var->index() >= labels_.size()) {
+ return std::string_view();
+ }
+ return labels_[labels_.size() - 1 - var->index()];
+ }
+}
+
+void NameApplier::UseNameForVar(std::string_view name, Var* var) {
+ if (var->is_name()) {
+ assert(name == var->name());
+ return;
+ }
+
+ if (!name.empty()) {
+ var->set_name(name);
+ }
+}
+
+Result NameApplier::UseNameForFuncTypeVar(Var* var) {
+ FuncType* func_type = module_->GetFuncType(*var);
+ if (!func_type) {
+ return Result::Error;
+ }
+ UseNameForVar(func_type->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForFuncVar(Var* var) {
+ Func* func = module_->GetFunc(*var);
+ if (!func) {
+ return Result::Error;
+ }
+ UseNameForVar(func->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForGlobalVar(Var* var) {
+ Global* global = module_->GetGlobal(*var);
+ if (!global) {
+ return Result::Error;
+ }
+ UseNameForVar(global->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForTableVar(Var* var) {
+ Table* table = module_->GetTable(*var);
+ if (!table) {
+ return Result::Error;
+ }
+ UseNameForVar(table->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForMemoryVar(Var* var) {
+ Memory* memory = module_->GetMemory(*var);
+ if (!memory) {
+ return Result::Error;
+ }
+ UseNameForVar(memory->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForTagVar(Var* var) {
+ Tag* tag = module_->GetTag(*var);
+ if (!tag) {
+ return Result::Error;
+ }
+ UseNameForVar(tag->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForDataSegmentVar(Var* var) {
+ DataSegment* data_segment = module_->GetDataSegment(*var);
+ if (!data_segment) {
+ return Result::Error;
+ }
+ UseNameForVar(data_segment->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForElemSegmentVar(Var* var) {
+ ElemSegment* elem_segment = module_->GetElemSegment(*var);
+ if (!elem_segment) {
+ return Result::Error;
+ }
+ UseNameForVar(elem_segment->name, var);
+ return Result::Ok;
+}
+
+Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) {
+ Index local_index = func->GetLocalIndex(*var);
+ if (local_index >= func->GetNumParamsAndLocals()) {
+ return Result::Error;
+ }
+
+ std::string name = param_and_local_index_to_name_[local_index];
+ if (var->is_name()) {
+ assert(name == var->name());
+ return Result::Ok;
+ }
+
+ if (!name.empty()) {
+ var->set_name(name);
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::BeginBlockExpr(BlockExpr* expr) {
+ PushLabel(expr->block.label);
+ return Result::Ok;
+}
+
+Result NameApplier::EndBlockExpr(BlockExpr* expr) {
+ PopLabel();
+ return Result::Ok;
+}
+
+Result NameApplier::BeginLoopExpr(LoopExpr* expr) {
+ PushLabel(expr->block.label);
+ return Result::Ok;
+}
+
+Result NameApplier::EndLoopExpr(LoopExpr* expr) {
+ PopLabel();
+ return Result::Ok;
+}
+
+Result NameApplier::OnDataDropExpr(DataDropExpr* expr) {
+ CHECK_RESULT(UseNameForDataSegmentVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnMemoryCopyExpr(MemoryCopyExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->srcmemidx));
+ CHECK_RESULT(UseNameForMemoryVar(&expr->destmemidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnMemoryFillExpr(MemoryFillExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnMemoryGrowExpr(MemoryGrowExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnMemoryInitExpr(MemoryInitExpr* expr) {
+ CHECK_RESULT(UseNameForDataSegmentVar(&expr->var));
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnMemorySizeExpr(MemorySizeExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnElemDropExpr(ElemDropExpr* expr) {
+ CHECK_RESULT(UseNameForElemSegmentVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableCopyExpr(TableCopyExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->dst_table));
+ CHECK_RESULT(UseNameForTableVar(&expr->src_table));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableInitExpr(TableInitExpr* expr) {
+ CHECK_RESULT(UseNameForElemSegmentVar(&expr->segment_index));
+ CHECK_RESULT(UseNameForTableVar(&expr->table_index));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableGetExpr(TableGetExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableSetExpr(TableSetExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableGrowExpr(TableGrowExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableSizeExpr(TableSizeExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnTableFillExpr(TableFillExpr* expr) {
+ CHECK_RESULT(UseNameForTableVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnStoreExpr(StoreExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnBrExpr(BrExpr* expr) {
+ std::string_view label = FindLabelByVar(&expr->var);
+ UseNameForVar(label, &expr->var);
+ return Result::Ok;
+}
+
+Result NameApplier::OnBrIfExpr(BrIfExpr* expr) {
+ std::string_view label = FindLabelByVar(&expr->var);
+ UseNameForVar(label, &expr->var);
+ return Result::Ok;
+}
+
+Result NameApplier::OnBrTableExpr(BrTableExpr* expr) {
+ for (Var& target : expr->targets) {
+ std::string_view label = FindLabelByVar(&target);
+ UseNameForVar(label, &target);
+ }
+
+ std::string_view label = FindLabelByVar(&expr->default_target);
+ UseNameForVar(label, &expr->default_target);
+ return Result::Ok;
+}
+
+Result NameApplier::BeginTryExpr(TryExpr* expr) {
+ PushLabel(expr->block.label);
+ return Result::Ok;
+}
+
+Result NameApplier::EndTryExpr(TryExpr*) {
+ PopLabel();
+ return Result::Ok;
+}
+
+Result NameApplier::OnCatchExpr(TryExpr*, Catch* expr) {
+ if (!expr->IsCatchAll()) {
+ CHECK_RESULT(UseNameForTagVar(&expr->var));
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::OnDelegateExpr(TryExpr* expr) {
+ PopLabel();
+ std::string_view label = FindLabelByVar(&expr->delegate_target);
+ UseNameForVar(label, &expr->delegate_target);
+ return Result::Ok;
+}
+
+Result NameApplier::OnThrowExpr(ThrowExpr* expr) {
+ CHECK_RESULT(UseNameForTagVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnRethrowExpr(RethrowExpr* expr) {
+ std::string_view label = FindLabelByVar(&expr->var);
+ UseNameForVar(label, &expr->var);
+ return Result::Ok;
+}
+
+Result NameApplier::OnCallExpr(CallExpr* expr) {
+ CHECK_RESULT(UseNameForFuncVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnRefFuncExpr(RefFuncExpr* expr) {
+ CHECK_RESULT(UseNameForFuncVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnCallIndirectExpr(CallIndirectExpr* expr) {
+ if (expr->decl.has_func_type) {
+ CHECK_RESULT(UseNameForFuncTypeVar(&expr->decl.type_var));
+ }
+ CHECK_RESULT(UseNameForTableVar(&expr->table));
+ return Result::Ok;
+}
+
+Result NameApplier::OnReturnCallExpr(ReturnCallExpr* expr) {
+ CHECK_RESULT(UseNameForFuncVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnReturnCallIndirectExpr(ReturnCallIndirectExpr* expr) {
+ if (expr->decl.has_func_type) {
+ CHECK_RESULT(UseNameForFuncTypeVar(&expr->decl.type_var));
+ }
+ CHECK_RESULT(UseNameForTableVar(&expr->table));
+ return Result::Ok;
+}
+
+Result NameApplier::OnGlobalGetExpr(GlobalGetExpr* expr) {
+ CHECK_RESULT(UseNameForGlobalVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnLocalGetExpr(LocalGetExpr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::BeginIfExpr(IfExpr* expr) {
+ PushLabel(expr->true_.label);
+ return Result::Ok;
+}
+
+Result NameApplier::EndIfExpr(IfExpr* expr) {
+ PopLabel();
+ return Result::Ok;
+}
+
+Result NameApplier::OnLoadExpr(LoadExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnGlobalSetExpr(GlobalSetExpr* expr) {
+ CHECK_RESULT(UseNameForGlobalVar(&expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnLocalSetExpr(LocalSetExpr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnLocalTeeExpr(LocalTeeExpr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->var));
+ return Result::Ok;
+}
+
+Result NameApplier::OnSimdLoadLaneExpr(SimdLoadLaneExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::OnSimdStoreLaneExpr(SimdStoreLaneExpr* expr) {
+ CHECK_RESULT(UseNameForMemoryVar(&expr->memidx));
+ return Result::Ok;
+}
+
+Result NameApplier::VisitFunc(Index func_index, Func* func) {
+ current_func_ = func;
+ if (func->decl.has_func_type) {
+ CHECK_RESULT(UseNameForFuncTypeVar(&func->decl.type_var));
+ }
+
+ MakeTypeBindingReverseMapping(func->GetNumParamsAndLocals(), func->bindings,
+ &param_and_local_index_to_name_);
+
+ CHECK_RESULT(visitor_.VisitFunc(func));
+ current_func_ = nullptr;
+ return Result::Ok;
+}
+
+Result NameApplier::VisitGlobal(Global* global) {
+ CHECK_RESULT(visitor_.VisitExprList(global->init_expr));
+ return Result::Ok;
+}
+
+Result NameApplier::VisitTag(Tag* tag) {
+ if (tag->decl.has_func_type) {
+ CHECK_RESULT(UseNameForFuncTypeVar(&tag->decl.type_var));
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::VisitExport(Index export_index, Export* export_) {
+ switch (export_->kind) {
+ case ExternalKind::Func:
+ UseNameForFuncVar(&export_->var);
+ break;
+
+ case ExternalKind::Table:
+ UseNameForTableVar(&export_->var);
+ break;
+
+ case ExternalKind::Memory:
+ UseNameForMemoryVar(&export_->var);
+ break;
+
+ case ExternalKind::Global:
+ UseNameForGlobalVar(&export_->var);
+ break;
+
+ case ExternalKind::Tag:
+ UseNameForTagVar(&export_->var);
+ break;
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::VisitElemSegment(Index elem_segment_index,
+ ElemSegment* segment) {
+ CHECK_RESULT(UseNameForTableVar(&segment->table_var));
+ CHECK_RESULT(visitor_.VisitExprList(segment->offset));
+ for (ExprList& elem_expr : segment->elem_exprs) {
+ Expr* expr = &elem_expr.front();
+ if (expr->type() == ExprType::RefFunc) {
+ CHECK_RESULT(UseNameForFuncVar(&cast<RefFuncExpr>(expr)->var));
+ }
+ }
+ return Result::Ok;
+}
+
+Result NameApplier::VisitDataSegment(Index data_segment_index,
+ DataSegment* segment) {
+ CHECK_RESULT(UseNameForMemoryVar(&segment->memory_var));
+ CHECK_RESULT(visitor_.VisitExprList(segment->offset));
+ return Result::Ok;
+}
+
+Result NameApplier::VisitStart(Var* start_var) {
+ CHECK_RESULT(UseNameForFuncVar(start_var));
+ return Result::Ok;
+}
+
+Result NameApplier::VisitModule(Module* module) {
+ module_ = module;
+ for (size_t i = 0; i < module->funcs.size(); ++i)
+ CHECK_RESULT(VisitFunc(i, module->funcs[i]));
+ for (size_t i = 0; i < module->globals.size(); ++i)
+ CHECK_RESULT(VisitGlobal(module->globals[i]));
+ for (size_t i = 0; i < module->tags.size(); ++i)
+ CHECK_RESULT(VisitTag(module->tags[i]));
+ for (size_t i = 0; i < module->exports.size(); ++i)
+ CHECK_RESULT(VisitExport(i, module->exports[i]));
+ for (size_t i = 0; i < module->elem_segments.size(); ++i)
+ CHECK_RESULT(VisitElemSegment(i, module->elem_segments[i]));
+ for (size_t i = 0; i < module->data_segments.size(); ++i)
+ CHECK_RESULT(VisitDataSegment(i, module->data_segments[i]));
+ for (size_t i = 0; i < module->starts.size(); ++i)
+ CHECK_RESULT(VisitStart(module->starts[i]));
+ module_ = nullptr;
+ return Result::Ok;
+}
+
+} // end anonymous namespace
+
+Result ApplyNames(Module* module) {
+ NameApplier applier;
+ return applier.VisitModule(module);
+}
+
+} // namespace wabt