#ifndef wasm_ir_names_h
#define wasm_ir_names_h
#include "wasm.h"
namespace wasm::Names {
inline void ensureNames(Function* func) {
std::unordered_set<Name> seen;
for (auto& [_, name] : func->localNames) {
seen.insert(name);
}
Index nameIndex = seen.size();
for (Index i = 0; i < func->getNumLocals(); i++) {
if (!func->hasLocalName(i)) {
while (1) {
auto name = Name::fromInt(nameIndex++);
if (seen.emplace(name).second) {
func->localNames[i] = name;
func->localIndices[name] = i;
break;
}
}
}
}
}
inline Name
getValidName(Name root, std::function<bool(Name)> check, Index hint = 0) {
if (check(root)) {
return root;
}
auto prefixed = std::string(root.str) + '_';
Index num = hint;
while (1) {
auto name = prefixed + std::to_string(num);
if (check(name)) {
return name;
}
num++;
}
}
inline Name getValidExportName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getExportOrNull(test); },
module.exports.size());
}
inline Name getValidGlobalName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getGlobalOrNull(test); },
module.globals.size());
}
inline Name getValidFunctionName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getFunctionOrNull(test); },
module.functions.size());
}
inline Name getValidTableName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getTableOrNull(test); },
module.tables.size());
}
inline Name getValidTagName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getTagOrNull(test); },
module.tags.size());
}
inline Name getValidElementSegmentName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getElementSegmentOrNull(test); },
module.elementSegments.size());
}
inline Name getValidDataSegmentName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getDataSegmentOrNull(test); },
module.dataSegments.size());
}
inline Name getValidMemoryName(Module& module, Name root) {
return getValidName(
root,
[&](Name test) { return !module.getMemoryOrNull(test); },
module.memories.size());
}
inline Name getValidLocalName(Function& func, Name root) {
return getValidName(
root,
[&](Name test) { return !func.hasLocalIndex(test); },
func.getNumLocals());
}
template<typename T>
inline Name getValidNameGivenExisting(Name root, const T& existingNames) {
return getValidName(
root,
[&](Name test) { return !existingNames.count(test); },
existingNames.size());
}
class MinifiedNameGenerator {
size_t state = 0;
public:
std::string getName();
};
}
#endif