class NameGenerator : public ExprVisitor::DelegateNop { public:
NameGenerator(NameOpts opts);
Result VisitModule(Module* module);
// Implementation of ExprVisitor::DelegateNop.
Result BeginBlockExpr(BlockExpr* expr) override;
Result BeginTryExpr(TryExpr* expr) override;
Result BeginLoopExpr(LoopExpr* expr) override;
Result BeginIfExpr(IfExpr* expr) override;
// Generate a name with the given prefix, followed by the index and // optionally a disambiguating number. If index == kInvalidIndex, the index // is not appended. void GenerateName(const char* prefix,
Index index, unsigned disambiguator,
std::string* out_str);
// Like GenerateName, but only generates a name if |out_str| is empty. void MaybeGenerateName(const char* prefix, Index index, std::string* out_str);
// Generate a name via GenerateName and bind it to the given binding hash. If // the name already exists, the name will be disambiguated until it can be // added. void GenerateAndBindName(BindingHash* bindings, const char* prefix,
Index index,
std::string* out_str);
// Like GenerateAndBindName, but only generates a name if |out_str| is empty. void MaybeGenerateAndBindName(BindingHash* bindings, const char* prefix,
Index index,
std::string* out_str);
// Like MaybeGenerateAndBindName but uses the name directly, without // appending the index. If the name already exists, a disambiguating suffix // is added. void MaybeUseAndBindName(BindingHash* bindings, const char* name,
Index index,
std::string* out_str);
void GenerateAndBindLocalNames(Func* func);
template <typename T>
Result VisitAll(const std::vector<T*>& items,
Result (NameGenerator::*func)(Index, T*));
Result VisitFunc(Index func_index, Func* func);
Result VisitGlobal(Index global_index, Global* global);
Result VisitType(Index func_type_index, TypeEntry* type);
Result VisitTable(Index table_index, Table* table);
Result VisitMemory(Index memory_index, Memory* memory);
Result VisitTag(Index tag_index, Tag* tag);
Result VisitDataSegment(Index data_segment_index, DataSegment* data_segment);
Result VisitElemSegment(Index elem_segment_index, ElemSegment* elem_segment);
Result VisitImport(Import* import);
Result VisitExport(Export* export_);
Module* module_ = nullptr;
ExprVisitor visitor_;
Index label_count_ = 0;
Index num_func_imports_ = 0;
Index num_table_imports_ = 0;
Index num_memory_imports_ = 0;
Index num_global_imports_ = 0;
Index num_tag_imports_ = 0;
void NameGenerator::GenerateName(const char* prefix,
Index index, unsigned disambiguator,
std::string* str) {
*str = "$";
*str += prefix;
if (index != kInvalidIndex) {
if (opts_ & NameOpts::AlphaNames) { // For params and locals, do not use a prefix char.
if (!strcmp(prefix, "p") || !strcmp(prefix, "l")) {
str->pop_back();
} else {
*str += '_';
}
*str += IndexToAlphaName(index);
} else {
*str += std::to_string(index);
}
}
if (disambiguator != 0) {
*str += '_' + std::to_string(disambiguator);
}
}
void NameGenerator::MaybeGenerateName(const char* prefix,
Index index,
std::string* str) {
if (!HasName(*str)) { // There's no bindings hash, so the name can't be a duplicate. Therefore it // doesn't need a disambiguating number.
GenerateName(prefix, index, 0, str);
}
}
Result NameGenerator::VisitImport(Import* import) {
BindingHash* bindings = nullptr;
std::string* name = nullptr;
Index index = kInvalidIndex;
switch (import->kind()) { case ExternalKind::Func:
if (auto* func_import = cast<FuncImport>(import)) {
bindings = &module_->func_bindings;
name = &func_import->func.name;
index = num_func_imports_++;
} break;
case ExternalKind::Table:
if (auto* table_import = cast<TableImport>(import)) {
bindings = &module_->table_bindings;
name = &table_import->table.name;
index = num_table_imports_++;
} break;
case ExternalKind::Memory:
if (auto* memory_import = cast<MemoryImport>(import)) {
bindings = &module_->memory_bindings;
name = &memory_import->memory.name;
index = num_memory_imports_++;
} break;
case ExternalKind::Global:
if (auto* global_import = cast<GlobalImport>(import)) {
bindings = &module_->global_bindings;
name = &global_import->global.name;
index = num_global_imports_++;
} break;
case ExternalKind::Tag:
if (auto* tag_import = cast<TagImport>(import)) {
bindings = &module_->tag_bindings;
name = &tag_import->tag.name;
index = num_tag_imports_++;
} break;
}
Result NameGenerator::VisitExport(Export* export_) {
BindingHash* bindings = nullptr;
std::string* name = nullptr;
Index index = kInvalidIndex;
switch (export_->kind) { case ExternalKind::Func:
if (Func* func = module_->GetFunc(export_->var)) {
index = module_->GetFuncIndex(export_->var);
bindings = &module_->func_bindings;
name = &func->name;
} break;
case ExternalKind::Table:
if (Table* table = module_->GetTable(export_->var)) {
index = module_->GetTableIndex(export_->var);
bindings = &module_->table_bindings;
name = &table->name;
} break;
case ExternalKind::Memory:
if (Memory* memory = module_->GetMemory(export_->var)) {
index = module_->GetMemoryIndex(export_->var);
bindings = &module_->memory_bindings;
name = &memory->name;
} break;
case ExternalKind::Global:
if (Global* global = module_->GetGlobal(export_->var)) {
index = module_->GetGlobalIndex(export_->var);
bindings = &module_->global_bindings;
name = &global->name;
} break;
case ExternalKind::Tag:
if (Tag* tag = module_->GetTag(export_->var)) {
index = module_->GetTagIndex(export_->var);
bindings = &module_->tag_bindings;
name = &tag->name;
} break;
}
if (bindings && name) {
MaybeUseAndBindName(bindings, export_->name.c_str(), index, name);
}
return Result::Ok;
}
template <typename T>
Result NameGenerator::VisitAll(const std::vector<T*>& items,
Result (NameGenerator::*func)(Index, T*)) {
for (Index i = 0; i < items.size(); ++i) {
CHECK_RESULT((this->*func)(i, items[i]));
} return Result::Ok;
}
Result NameGenerator::VisitModule(Module* module) {
module_ = module; // Visit imports and exports first to give better names, derived from the // import/export name.
for (auto* import : module->imports) {
CHECK_RESULT(VisitImport(import));
}
for (auto* export_ : module->exports) {
CHECK_RESULT(VisitExport(export_));
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.