summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apply-names.cc221
-rw-r--r--src/generate-names.cc182
-rw-r--r--src/resolve-names.cc347
3 files changed, 406 insertions, 344 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc
index b61cd7f7..acfd511b 100644
--- a/src/apply-names.cc
+++ b/src/apply-names.cc
@@ -33,9 +33,13 @@ namespace wabt {
namespace {
-struct Context : ExprVisitor::DelegateNop {
- Context();
+class NameApplier : public ExprVisitor::DelegateNop {
+ public:
+ NameApplier();
+ Result VisitModule(Module* module);
+
+ // Implementation of ExprVisitor::DelegateNop.
Result BeginBlockExpr(Expr*) override;
Result EndBlockExpr(Expr*) override;
Result OnBrExpr(Expr*) override;
@@ -53,42 +57,57 @@ struct Context : ExprVisitor::DelegateNop {
Result OnSetLocalExpr(Expr*) override;
Result OnTeeLocalExpr(Expr*) override;
- Module* module = nullptr;
- Func* current_func = nullptr;
- ExprVisitor visitor;
+ private:
+ void PushLabel(Label* label);
+ void PopLabel();
+ Label* FindLabelByVar(Var* var);
+ void UseNameForVar(StringSlice* name, Var* var);
+ Result UseNameForFuncTypeVar(Module* module, Var* var);
+ Result UseNameForFuncVar(Module* module, Var* var);
+ Result UseNameForGlobalVar(Module* module, Var* var);
+ Result UseNameForTableVar(Module* module, Var* var);
+ Result UseNameForMemoryVar(Module* module, Var* var);
+ Result UseNameForParamAndLocalVar(Func* func, Var* var);
+ Result VisitFunc(Index func_index, Func* func);
+ Result VisitExport(Index export_index, Export* export_);
+ Result VisitElemSegment(Index elem_segment_index, ElemSegment* segment);
+ Result VisitDataSegment(Index data_segment_index, DataSegment* segment);
+
+ Module* module_ = nullptr;
+ Func* current_func_ = nullptr;
+ ExprVisitor visitor_;
/* mapping from param index to its name, if any, for the current func */
- std::vector<std::string> param_index_to_name;
- std::vector<std::string> local_index_to_name;
- std::vector<Label*> labels;
+ std::vector<std::string> param_index_to_name_;
+ std::vector<std::string> local_index_to_name_;
+ std::vector<Label*> labels_;
};
-Context::Context() : visitor(this) {
-}
+NameApplier::NameApplier() : visitor_(this) {}
-void push_label(Context* ctx, Label* label) {
- ctx->labels.push_back(label);
+void NameApplier::PushLabel(Label* label) {
+ labels_.push_back(label);
}
-void pop_label(Context* ctx) {
- ctx->labels.pop_back();
+void NameApplier::PopLabel() {
+ labels_.pop_back();
}
-Label* find_label_by_var(Context* ctx, Var* var) {
+Label* NameApplier::FindLabelByVar(Var* var) {
if (var->type == VarType::Name) {
- for (int i = ctx->labels.size() - 1; i >= 0; --i) {
- Label* label = ctx->labels[i];
+ for (int i = labels_.size() - 1; i >= 0; --i) {
+ Label* label = labels_[i];
if (string_slices_are_equal(label, &var->name))
return label;
}
return nullptr;
} else {
- if (var->index >= ctx->labels.size())
+ if (var->index >= labels_.size())
return nullptr;
- return ctx->labels[ctx->labels.size() - 1 - var->index];
+ return labels_[labels_.size() - 1 - var->index];
}
}
-void use_name_for_var(StringSlice* name, Var* var) {
+void NameApplier::UseNameForVar(StringSlice* name, Var* var) {
if (var->type == VarType::Name) {
assert(string_slices_are_equal(name, &var->name));
}
@@ -99,47 +118,47 @@ void use_name_for_var(StringSlice* name, Var* var) {
}
}
-Result use_name_for_func_type_var(Module* module, Var* var) {
+Result NameApplier::UseNameForFuncTypeVar(Module* module, Var* var) {
FuncType* func_type = get_func_type_by_var(module, var);
if (!func_type)
return Result::Error;
- use_name_for_var(&func_type->name, var);
+ UseNameForVar(&func_type->name, var);
return Result::Ok;
}
-Result use_name_for_func_var(Module* module, Var* var) {
+Result NameApplier::UseNameForFuncVar(Module* module, Var* var) {
Func* func = get_func_by_var(module, var);
if (!func)
return Result::Error;
- use_name_for_var(&func->name, var);
+ UseNameForVar(&func->name, var);
return Result::Ok;
}
-Result use_name_for_global_var(Module* module, Var* var) {
+Result NameApplier::UseNameForGlobalVar(Module* module, Var* var) {
Global* global = get_global_by_var(module, var);
if (!global)
return Result::Error;
- use_name_for_var(&global->name, var);
+ UseNameForVar(&global->name, var);
return Result::Ok;
}
-Result use_name_for_table_var(Module* module, Var* var) {
+Result NameApplier::UseNameForTableVar(Module* module, Var* var) {
Table* table = get_table_by_var(module, var);
if (!table)
return Result::Error;
- use_name_for_var(&table->name, var);
+ UseNameForVar(&table->name, var);
return Result::Ok;
}
-Result use_name_for_memory_var(Module* module, Var* var) {
+Result NameApplier::UseNameForMemoryVar(Module* module, Var* var) {
Memory* memory = get_memory_by_var(module, var);
if (!memory)
return Result::Error;
- use_name_for_var(&memory->name, var);
+ UseNameForVar(&memory->name, var);
return Result::Ok;
}
-Result use_name_for_param_and_local_var(Context* ctx, Func* func, Var* var) {
+Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) {
Index local_index = get_local_index_by_var(func, var);
if (local_index >= get_num_params_and_locals(func))
return Result::Error;
@@ -148,13 +167,13 @@ Result use_name_for_param_and_local_var(Context* ctx, Func* func, Var* var) {
std::string* name;
if (local_index < num_params) {
/* param */
- assert(local_index < ctx->param_index_to_name.size());
- name = &ctx->param_index_to_name[local_index];
+ assert(local_index < param_index_to_name_.size());
+ name = &param_index_to_name_[local_index];
} else {
/* local */
local_index -= num_params;
- assert(local_index < ctx->local_index_to_name.size());
- name = &ctx->local_index_to_name[local_index];
+ assert(local_index < local_index_to_name_.size());
+ name = &local_index_to_name_[local_index];
}
if (var->type == VarType::Name) {
@@ -170,159 +189,153 @@ Result use_name_for_param_and_local_var(Context* ctx, Func* func, Var* var) {
return Result::Ok;
}
-Result Context::BeginBlockExpr(Expr* expr) {
- push_label(this, &expr->block->label);
+Result NameApplier::BeginBlockExpr(Expr* expr) {
+ PushLabel(&expr->block->label);
return Result::Ok;
}
-Result Context::EndBlockExpr(Expr* expr) {
- pop_label(this);
+Result NameApplier::EndBlockExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::BeginLoopExpr(Expr* expr) {
- push_label(this, &expr->loop->label);
+Result NameApplier::BeginLoopExpr(Expr* expr) {
+ PushLabel(&expr->loop->label);
return Result::Ok;
}
-Result Context::EndLoopExpr(Expr* expr) {
- pop_label(this);
+Result NameApplier::EndLoopExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::OnBrExpr(Expr* expr) {
- Label* label = find_label_by_var(this, &expr->br.var);
- use_name_for_var(label, &expr->br.var);
+Result NameApplier::OnBrExpr(Expr* expr) {
+ Label* label = FindLabelByVar(&expr->br.var);
+ UseNameForVar(label, &expr->br.var);
return Result::Ok;
}
-Result Context::OnBrIfExpr(Expr* expr) {
- Label* label = find_label_by_var(this, &expr->br_if.var);
- use_name_for_var(label, &expr->br_if.var);
+Result NameApplier::OnBrIfExpr(Expr* expr) {
+ Label* label = FindLabelByVar(&expr->br_if.var);
+ UseNameForVar(label, &expr->br_if.var);
return Result::Ok;
}
-Result Context::OnBrTableExpr(Expr* expr) {
+Result NameApplier::OnBrTableExpr(Expr* expr) {
VarVector& targets = *expr->br_table.targets;
for (Var& target : targets) {
- Label* label = find_label_by_var(this, &target);
- use_name_for_var(label, &target);
+ Label* label = FindLabelByVar(&target);
+ UseNameForVar(label, &target);
}
- Label* label = find_label_by_var(this, &expr->br_table.default_target);
- use_name_for_var(label, &expr->br_table.default_target);
+ Label* label = FindLabelByVar(&expr->br_table.default_target);
+ UseNameForVar(label, &expr->br_table.default_target);
return Result::Ok;
}
-Result Context::OnCallExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_func_var(module, &expr->call.var));
+Result NameApplier::OnCallExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForFuncVar(module_, &expr->call.var));
return Result::Ok;
}
-Result Context::OnCallIndirectExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_func_type_var(module, &expr->call_indirect.var));
+Result NameApplier::OnCallIndirectExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForFuncTypeVar(module_, &expr->call_indirect.var));
return Result::Ok;
}
-Result Context::OnGetGlobalExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_global_var(module, &expr->get_global.var));
+Result NameApplier::OnGetGlobalExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForGlobalVar(module_, &expr->get_global.var));
return Result::Ok;
}
-Result Context::OnGetLocalExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_param_and_local_var(this, current_func,
- &expr->get_local.var));
+Result NameApplier::OnGetLocalExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->get_local.var));
return Result::Ok;
}
-Result Context::BeginIfExpr(Expr* expr) {
- push_label(this, &expr->if_.true_->label);
+Result NameApplier::BeginIfExpr(Expr* expr) {
+ PushLabel(&expr->if_.true_->label);
return Result::Ok;
}
-Result Context::EndIfExpr(Expr* expr) {
- pop_label(this);
+Result NameApplier::EndIfExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::OnSetGlobalExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_global_var(module, &expr->set_global.var));
+Result NameApplier::OnSetGlobalExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForGlobalVar(module_, &expr->set_global.var));
return Result::Ok;
}
-Result Context::OnSetLocalExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_param_and_local_var(this, current_func,
- &expr->set_local.var));
+Result NameApplier::OnSetLocalExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->set_local.var));
return Result::Ok;
}
-Result Context::OnTeeLocalExpr(Expr* expr) {
- CHECK_RESULT(use_name_for_param_and_local_var(this, current_func,
- &expr->tee_local.var));
+Result NameApplier::OnTeeLocalExpr(Expr* expr) {
+ CHECK_RESULT(UseNameForParamAndLocalVar(current_func_, &expr->tee_local.var));
return Result::Ok;
}
-Result visit_func(Context* ctx, Index func_index, Func* func) {
- ctx->current_func = func;
+Result NameApplier::VisitFunc(Index func_index, Func* func) {
+ current_func_ = func;
if (decl_has_func_type(&func->decl)) {
- CHECK_RESULT(use_name_for_func_type_var(ctx->module, &func->decl.type_var));
+ CHECK_RESULT(UseNameForFuncTypeVar(module_, &func->decl.type_var));
}
- make_type_binding_reverse_mapping(func->decl.sig.param_types,
- func->param_bindings,
- &ctx->param_index_to_name);
+ make_type_binding_reverse_mapping(
+ func->decl.sig.param_types, func->param_bindings, &param_index_to_name_);
make_type_binding_reverse_mapping(func->local_types, func->local_bindings,
- &ctx->local_index_to_name);
+ &local_index_to_name_);
- CHECK_RESULT(ctx->visitor.VisitFunc(func));
- ctx->current_func = nullptr;
+ CHECK_RESULT(visitor_.VisitFunc(func));
+ current_func_ = nullptr;
return Result::Ok;
}
-Result visit_export(Context* ctx, Index export_index, Export* export_) {
+Result NameApplier::VisitExport(Index export_index, Export* export_) {
if (export_->kind == ExternalKind::Func) {
- use_name_for_func_var(ctx->module, &export_->var);
+ UseNameForFuncVar(module_, &export_->var);
}
return Result::Ok;
}
-Result visit_elem_segment(Context* ctx,
- Index elem_segment_index,
- ElemSegment* segment) {
- CHECK_RESULT(use_name_for_table_var(ctx->module, &segment->table_var));
+Result NameApplier::VisitElemSegment(Index elem_segment_index,
+ ElemSegment* segment) {
+ CHECK_RESULT(UseNameForTableVar(module_, &segment->table_var));
for (Var& var : segment->vars) {
- CHECK_RESULT(use_name_for_func_var(ctx->module, &var));
+ CHECK_RESULT(UseNameForFuncVar(module_, &var));
}
return Result::Ok;
}
-Result visit_data_segment(Context* ctx,
- Index data_segment_index,
- DataSegment* segment) {
- CHECK_RESULT(use_name_for_memory_var(ctx->module, &segment->memory_var));
+Result NameApplier::VisitDataSegment(Index data_segment_index,
+ DataSegment* segment) {
+ CHECK_RESULT(UseNameForMemoryVar(module_, &segment->memory_var));
return Result::Ok;
}
-Result visit_module(Context* ctx, Module* module) {
+Result NameApplier::VisitModule(Module* module) {
+ module_ = module;
for (size_t i = 0; i < module->funcs.size(); ++i)
- CHECK_RESULT(visit_func(ctx, i, module->funcs[i]));
+ CHECK_RESULT(VisitFunc(i, module->funcs[i]));
for (size_t i = 0; i < module->exports.size(); ++i)
- CHECK_RESULT(visit_export(ctx, i, module->exports[i]));
+ CHECK_RESULT(VisitExport(i, module->exports[i]));
for (size_t i = 0; i < module->elem_segments.size(); ++i)
- CHECK_RESULT(visit_elem_segment(ctx, i, module->elem_segments[i]));
+ CHECK_RESULT(VisitElemSegment(i, module->elem_segments[i]));
for (size_t i = 0; i < module->data_segments.size(); ++i)
- CHECK_RESULT(visit_data_segment(ctx, i, module->data_segments[i]));
+ CHECK_RESULT(VisitDataSegment(i, module->data_segments[i]));
+ module_ = nullptr;
return Result::Ok;
}
} // namespace
Result apply_names(Module* module) {
- Context ctx;
- ctx.module = module;
- Result result = visit_module(&ctx, module);
- return result;
+ NameApplier applier;
+ return applier.VisitModule(module);
}
} // namespace wabt
diff --git a/src/generate-names.cc b/src/generate-names.cc
index 667e3ecf..a2b286d2 100644
--- a/src/generate-names.cc
+++ b/src/generate-names.cc
@@ -24,36 +24,65 @@
#include "expr-visitor.h"
#include "ir.h"
-#define CHECK_RESULT(expr) \
- do { \
- if (WABT_FAILED(expr)) \
- return Result::Error; \
+#define CHECK_RESULT(expr) \
+ do { \
+ if (WABT_FAILED(expr)) \
+ return Result::Error; \
} while (0)
namespace wabt {
namespace {
-struct Context : public ExprVisitor::DelegateNop {
- Context() : module(nullptr), visitor(this), label_count(0) {}
+class NameGenerator : public ExprVisitor::DelegateNop {
+ public:
+ NameGenerator();
+ Result VisitModule(Module* module);
+
+ // Implementation of ExprVisitor::DelegateNop.
Result BeginBlockExpr(Expr* expr) override;
Result BeginLoopExpr(Expr* expr) override;
Result BeginIfExpr(Expr* expr) override;
- Module* module;
- ExprVisitor visitor;
- std::vector<std::string> index_to_name;
- Index label_count;
+ private:
+ static bool HasName(StringSlice* str);
+ static void GenerateName(const char* prefix, Index index, StringSlice* str);
+ static void MaybeGenerateName(const char* prefix,
+ Index index,
+ StringSlice* str);
+ static void GenerateAndBindName(BindingHash* bindings,
+ const char* prefix,
+ Index index,
+ StringSlice* str);
+ static void MaybeGenerateAndBindName(BindingHash* bindings,
+ const char* prefix,
+ Index index,
+ StringSlice* str);
+ void GenerateAndBindLocalNames(BindingHash* bindings, const char* prefix);
+ Result VisitFunc(Index func_index, Func* func);
+ Result VisitGlobal(Index global_index, Global* global);
+ Result VisitFuncType(Index func_type_index, FuncType* func_type);
+ Result VisitTable(Index table_index, Table* table);
+ Result VisitMemory(Index memory_index, Memory* memory);
+
+ Module* module_ = nullptr;
+ ExprVisitor visitor_;
+ std::vector<std::string> index_to_name_;
+ Index label_count_ = 0;
};
-} // namespace
+NameGenerator::NameGenerator() : visitor_(this) {}
-static bool has_name(StringSlice* str) {
+// static
+bool NameGenerator::HasName(StringSlice* str) {
return str->length > 0;
}
-static void generate_name(const char* prefix, Index index, StringSlice* str) {
+// static
+void NameGenerator::GenerateName(const char* prefix,
+ Index index,
+ StringSlice* str) {
size_t prefix_len = strlen(prefix);
size_t buffer_len = prefix_len + 20; /* add space for the number */
char* buffer = static_cast<char*>(alloca(buffer_len));
@@ -65,121 +94,124 @@ static void generate_name(const char* prefix, Index index, StringSlice* str) {
*str = dup_string_slice(buf);
}
-static void maybe_generate_name(const char* prefix,
- Index index,
- StringSlice* str) {
- if (!has_name(str))
- generate_name(prefix, index, str);
+// static
+void NameGenerator::MaybeGenerateName(const char* prefix,
+ Index index,
+ StringSlice* str) {
+ if (!HasName(str))
+ GenerateName(prefix, index, str);
}
-static void generate_and_bind_name(BindingHash* bindings,
- const char* prefix,
- Index index,
- StringSlice* str) {
- generate_name(prefix, index, str);
+// static
+void NameGenerator::GenerateAndBindName(BindingHash* bindings,
+ const char* prefix,
+ Index index,
+ StringSlice* str) {
+ GenerateName(prefix, index, str);
bindings->emplace(string_slice_to_string(*str), Binding(index));
}
-static void maybe_generate_and_bind_name(BindingHash* bindings,
- const char* prefix,
- Index index,
- StringSlice* str) {
- if (!has_name(str))
- generate_and_bind_name(bindings, prefix, index, str);
+// static
+void NameGenerator::MaybeGenerateAndBindName(BindingHash* bindings,
+ const char* prefix,
+ Index index,
+ StringSlice* str) {
+ if (!HasName(str))
+ GenerateAndBindName(bindings, prefix, index, str);
}
-static void generate_and_bind_local_names(Context* ctx,
- BindingHash* bindings,
- const char* prefix) {
- for (size_t i = 0; i < ctx->index_to_name.size(); ++i) {
- const std::string& old_name = ctx->index_to_name[i];
+void NameGenerator::GenerateAndBindLocalNames(BindingHash* bindings,
+ const char* prefix) {
+ for (size_t i = 0; i < index_to_name_.size(); ++i) {
+ const std::string& old_name = index_to_name_[i];
if (!old_name.empty())
continue;
StringSlice new_name;
- generate_and_bind_name(bindings, prefix, i, &new_name);
- ctx->index_to_name[i] = string_slice_to_string(new_name);
+ GenerateAndBindName(bindings, prefix, i, &new_name);
+ index_to_name_[i] = string_slice_to_string(new_name);
destroy_string_slice(&new_name);
}
}
-Result Context::BeginBlockExpr(Expr* expr) {
- maybe_generate_name("$B", label_count++, &expr->block->label);
+Result NameGenerator::BeginBlockExpr(Expr* expr) {
+ MaybeGenerateName("$B", label_count_++, &expr->block->label);
return Result::Ok;
}
-Result Context::BeginLoopExpr(Expr* expr) {
- maybe_generate_name("$L", label_count++, &expr->loop->label);
+Result NameGenerator::BeginLoopExpr(Expr* expr) {
+ MaybeGenerateName("$L", label_count_++, &expr->loop->label);
return Result::Ok;
}
-Result Context::BeginIfExpr(Expr* expr) {
- maybe_generate_name("$I", label_count++, &expr->if_.true_->label);
+Result NameGenerator::BeginIfExpr(Expr* expr) {
+ MaybeGenerateName("$I", label_count_++, &expr->if_.true_->label);
return Result::Ok;
}
-static Result visit_func(Context* ctx, Index func_index, Func* func) {
- maybe_generate_and_bind_name(&ctx->module->func_bindings, "$f", func_index,
- &func->name);
+Result NameGenerator::VisitFunc(Index func_index, Func* func) {
+ MaybeGenerateAndBindName(&module_->func_bindings, "$f", func_index,
+ &func->name);
make_type_binding_reverse_mapping(func->decl.sig.param_types,
- func->param_bindings, &ctx->index_to_name);
- generate_and_bind_local_names(ctx, &func->param_bindings, "$p");
+ func->param_bindings, &index_to_name_);
+ GenerateAndBindLocalNames(&func->param_bindings, "$p");
make_type_binding_reverse_mapping(func->local_types, func->local_bindings,
- &ctx->index_to_name);
- generate_and_bind_local_names(ctx, &func->local_bindings, "$l");
+ &index_to_name_);
+ GenerateAndBindLocalNames(&func->local_bindings, "$l");
- ctx->label_count = 0;
- CHECK_RESULT(ctx->visitor.VisitFunc(func));
+ label_count_ = 0;
+ CHECK_RESULT(visitor_.VisitFunc(func));
return Result::Ok;
}
-static Result visit_global(Context* ctx, Index global_index, Global* global) {
- maybe_generate_and_bind_name(&ctx->module->global_bindings, "$g",
- global_index, &global->name);
+Result NameGenerator::VisitGlobal(Index global_index, Global* global) {
+ MaybeGenerateAndBindName(&module_->global_bindings, "$g", global_index,
+ &global->name);
return Result::Ok;
}
-static Result visit_func_type(Context* ctx,
- Index func_type_index,
- FuncType* func_type) {
- maybe_generate_and_bind_name(&ctx->module->func_type_bindings, "$t",
- func_type_index, &func_type->name);
+Result NameGenerator::VisitFuncType(Index func_type_index,
+ FuncType* func_type) {
+ MaybeGenerateAndBindName(&module_->func_type_bindings, "$t", func_type_index,
+ &func_type->name);
return Result::Ok;
}
-static Result visit_table(Context* ctx, Index table_index, Table* table) {
- maybe_generate_and_bind_name(&ctx->module->table_bindings, "$T", table_index,
- &table->name);
+Result NameGenerator::VisitTable(Index table_index, Table* table) {
+ MaybeGenerateAndBindName(&module_->table_bindings, "$T", table_index,
+ &table->name);
return Result::Ok;
}
-static Result visit_memory(Context* ctx, Index memory_index, Memory* memory) {
- maybe_generate_and_bind_name(&ctx->module->memory_bindings, "$M",
- memory_index, &memory->name);
+Result NameGenerator::VisitMemory(Index memory_index, Memory* memory) {
+ MaybeGenerateAndBindName(&module_->memory_bindings, "$M", memory_index,
+ &memory->name);
return Result::Ok;
}
-static Result visit_module(Context* ctx, Module* module) {
+Result NameGenerator::VisitModule(Module* module) {
+ module_ = module;
for (Index i = 0; i < module->globals.size(); ++i)
- CHECK_RESULT(visit_global(ctx, i, module->globals[i]));
+ CHECK_RESULT(VisitGlobal(i, module->globals[i]));
for (Index i = 0; i < module->func_types.size(); ++i)
- CHECK_RESULT(visit_func_type(ctx, i, module->func_types[i]));
+ CHECK_RESULT(VisitFuncType(i, module->func_types[i]));
for (Index i = 0; i < module->funcs.size(); ++i)
- CHECK_RESULT(visit_func(ctx, i, module->funcs[i]));
+ CHECK_RESULT(VisitFunc(i, module->funcs[i]));
for (Index i = 0; i < module->tables.size(); ++i)
- CHECK_RESULT(visit_table(ctx, i, module->tables[i]));
+ CHECK_RESULT(VisitTable(i, module->tables[i]));
for (Index i = 0; i < module->memories.size(); ++i)
- CHECK_RESULT(visit_memory(ctx, i, module->memories[i]));
+ CHECK_RESULT(VisitMemory(i, module->memories[i]));
+ module_ = nullptr;
return Result::Ok;
}
+} // namespace
+
Result generate_names(Module* module) {
- Context ctx;
- ctx.module = module;
- Result result = visit_module(&ctx, module);
- return result;
+ NameGenerator generator;
+ return generator.VisitModule(module);
}
} // namespace wabt
diff --git a/src/resolve-names.cc b/src/resolve-names.cc
index 70eff09c..b5958f4a 100644
--- a/src/resolve-names.cc
+++ b/src/resolve-names.cc
@@ -29,9 +29,16 @@ namespace {
typedef Label* LabelPtr;
-struct Context : ExprVisitor::DelegateNop {
- Context();
+class NameResolver : public ExprVisitor::DelegateNop {
+ public:
+ NameResolver(WastLexer* lexer,
+ Script* script,
+ SourceErrorHandler* error_handler);
+ Result VisitModule(Module* module);
+ Result VisitScript(Script* script);
+
+ // Implementation of ExprVisitor::DelegateNop.
Result BeginBlockExpr(Expr*) override;
Result EndBlockExpr(Expr*) override;
Result OnBrExpr(Expr*) override;
@@ -49,91 +56,119 @@ struct Context : ExprVisitor::DelegateNop {
Result OnSetLocalExpr(Expr*) override;
Result OnTeeLocalExpr(Expr*) override;
- SourceErrorHandler* error_handler = nullptr;
- WastLexer* lexer = nullptr;
- Script* script = nullptr;
- Module* current_module = nullptr;
- Func* current_func = nullptr;
- ExprVisitor visitor;
- std::vector<Label*> labels;
- Result result = Result::Ok;
+ private:
+ void PrintError(const Location* loc, const char* fmt, ...);
+ void PushLabel(Label* label);
+ void PopLabel();
+ static void OnDuplicateBinding(const BindingHash::value_type& a,
+ const BindingHash::value_type& b,
+ void* user_data);
+ void CheckDuplicateBindings(const BindingHash* bindings, const char* desc);
+ void ResolveLabelVar(Var* var);
+ void ResolveVar(const BindingHash* bindings, Var* var, const char* desc);
+ void ResolveFuncVar(Var* var);
+ void ResolveGlobalVar(Var* var);
+ void ResolveFuncTypeVar(Var* var);
+ void ResolveTableVar(Var* var);
+ void ResolveMemoryVar(Var* var);
+ void ResolveLocalVar(Var* var);
+ void VisitFunc(Func* func);
+ void VisitExport(Export* export_);
+ void VisitGlobal(Global* global);
+ void VisitElemSegment(ElemSegment* segment);
+ void VisitDataSegment(DataSegment* segment);
+ void VisitRawModule(RawModule* raw_module);
+ void VisitCommand(Command* command);
+
+ SourceErrorHandler* error_handler_ = nullptr;
+ WastLexer* lexer_ = nullptr;
+ Script* script_ = nullptr;
+ Module* current_module_ = nullptr;
+ Func* current_func_ = nullptr;
+ ExprVisitor visitor_;
+ std::vector<Label*> labels_;
+ Result result_ = Result::Ok;
};
-Context::Context() : visitor(this) {}
+NameResolver::NameResolver(WastLexer* lexer,
+ Script* script,
+ SourceErrorHandler* error_handler)
+ : error_handler_(error_handler),
+ lexer_(lexer),
+ script_(script),
+ visitor_(this) {}
} // namespace
-static void WABT_PRINTF_FORMAT(3, 4)
- print_error(Context* ctx, const Location* loc, const char* fmt, ...) {
- ctx->result = Result::Error;
+void WABT_PRINTF_FORMAT(3, 4) NameResolver::PrintError(const Location* loc,
+ const char* fmt,
+ ...) {
+ result_ = Result::Error;
va_list args;
va_start(args, fmt);
- wast_format_error(ctx->error_handler, loc, ctx->lexer, fmt, args);
+ wast_format_error(error_handler_, loc, lexer_, fmt, args);
va_end(args);
}
-static void push_label(Context* ctx, Label* label) {
- ctx->labels.push_back(label);
+void NameResolver::PushLabel(Label* label) {
+ labels_.push_back(label);
}
-static void pop_label(Context* ctx) {
- ctx->labels.pop_back();
+void NameResolver::PopLabel() {
+ labels_.pop_back();
}
struct FindDuplicateBindingContext {
- Context* ctx;
+ NameResolver* resolver;
const char* desc;
};
-static void on_duplicate_binding(const BindingHash::value_type& a,
- const BindingHash::value_type& b,
- void* user_data) {
+// static
+void NameResolver::OnDuplicateBinding(const BindingHash::value_type& a,
+ const BindingHash::value_type& b,
+ void* user_data) {
FindDuplicateBindingContext* fdbc =
static_cast<FindDuplicateBindingContext*>(user_data);
/* choose the location that is later in the file */
const Location& a_loc = a.second.loc;
const Location& b_loc = b.second.loc;
const Location& loc = a_loc.line > b_loc.line ? a_loc : b_loc;
- print_error(fdbc->ctx, &loc, "redefinition of %s \"%s\"", fdbc->desc,
- a.first.c_str());
+ fdbc->resolver->PrintError(&loc, "redefinition of %s \"%s\"", fdbc->desc,
+ a.first.c_str());
}
-static void check_duplicate_bindings(Context* ctx,
- const BindingHash* bindings,
- const char* desc) {
+void NameResolver::CheckDuplicateBindings(const BindingHash* bindings,
+ const char* desc) {
FindDuplicateBindingContext fdbc;
- fdbc.ctx = ctx;
+ fdbc.resolver = this;
fdbc.desc = desc;
- bindings->find_duplicates(on_duplicate_binding, &fdbc);
+ bindings->find_duplicates(OnDuplicateBinding, &fdbc);
}
-static void resolve_label_var(Context* ctx, Var* var) {
+void NameResolver::ResolveLabelVar(Var* var) {
if (var->type == VarType::Name) {
- for (int i = ctx->labels.size() - 1; i >= 0; --i) {
- Label* label = ctx->labels[i];
+ for (int i = labels_.size() - 1; i >= 0; --i) {
+ Label* label = labels_[i];
if (string_slices_are_equal(label, &var->name)) {
destroy_string_slice(&var->name);
var->type = VarType::Index;
- var->index = ctx->labels.size() - i - 1;
+ var->index = labels_.size() - i - 1;
return;
}
}
- print_error(ctx, &var->loc,
- "undefined label variable \"" PRIstringslice "\"",
- WABT_PRINTF_STRING_SLICE_ARG(var->name));
+ PrintError(&var->loc, "undefined label variable \"" PRIstringslice "\"",
+ WABT_PRINTF_STRING_SLICE_ARG(var->name));
}
}
-static void resolve_var(Context* ctx,
- const BindingHash* bindings,
- Var* var,
- const char* desc) {
+void NameResolver::ResolveVar(const BindingHash* bindings,
+ Var* var,
+ const char* desc) {
if (var->type == VarType::Name) {
int index = get_index_from_var(bindings, var);
if (index == -1) {
- print_error(ctx, &var->loc,
- "undefined %s variable \"" PRIstringslice "\"", desc,
- WABT_PRINTF_STRING_SLICE_ARG(var->name));
+ PrintError(&var->loc, "undefined %s variable \"" PRIstringslice "\"",
+ desc, WABT_PRINTF_STRING_SLICE_ARG(var->name));
return;
}
@@ -143,37 +178,35 @@ static void resolve_var(Context* ctx,
}
}
-static void resolve_func_var(Context* ctx, Var* var) {
- resolve_var(ctx, &ctx->current_module->func_bindings, var, "function");
+void NameResolver::ResolveFuncVar(Var* var) {
+ ResolveVar(&current_module_->func_bindings, var, "function");
}
-static void resolve_global_var(Context* ctx, Var* var) {
- resolve_var(ctx, &ctx->current_module->global_bindings, var, "global");
+void NameResolver::ResolveGlobalVar(Var* var) {
+ ResolveVar(&current_module_->global_bindings, var, "global");
}
-static void resolve_func_type_var(Context* ctx, Var* var) {
- resolve_var(ctx, &ctx->current_module->func_type_bindings, var,
- "function type");
+void NameResolver::ResolveFuncTypeVar(Var* var) {
+ ResolveVar(&current_module_->func_type_bindings, var, "function type");
}
-static void resolve_table_var(Context* ctx, Var* var) {
- resolve_var(ctx, &ctx->current_module->table_bindings, var, "table");
+void NameResolver::ResolveTableVar(Var* var) {
+ ResolveVar(&current_module_->table_bindings, var, "table");
}
-static void resolve_memory_var(Context* ctx, Var* var) {
- resolve_var(ctx, &ctx->current_module->memory_bindings, var, "memory");
+void NameResolver::ResolveMemoryVar(Var* var) {
+ ResolveVar(&current_module_->memory_bindings, var, "memory");
}
-static void resolve_local_var(Context* ctx, Var* var) {
+void NameResolver::ResolveLocalVar(Var* var) {
if (var->type == VarType::Name) {
- if (!ctx->current_func)
+ if (!current_func_)
return;
- int index = get_local_index_by_var(ctx->current_func, var);
+ int index = get_local_index_by_var(current_func_, var);
if (index == -1) {
- print_error(ctx, &var->loc,
- "undefined local variable \"" PRIstringslice "\"",
- WABT_PRINTF_STRING_SLICE_ARG(var->name));
+ PrintError(&var->loc, "undefined local variable \"" PRIstringslice "\"",
+ WABT_PRINTF_STRING_SLICE_ARG(var->name));
return;
}
@@ -183,168 +216,169 @@ static void resolve_local_var(Context* ctx, Var* var) {
}
}
-Result Context::BeginBlockExpr(Expr* expr) {
- push_label(this, &expr->block->label);
+Result NameResolver::BeginBlockExpr(Expr* expr) {
+ PushLabel(&expr->block->label);
return Result::Ok;
}
-Result Context::EndBlockExpr(Expr* expr) {
- pop_label(this);
+Result NameResolver::EndBlockExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::BeginLoopExpr(Expr* expr) {
- push_label(this, &expr->loop->label);
+Result NameResolver::BeginLoopExpr(Expr* expr) {
+ PushLabel(&expr->loop->label);
return Result::Ok;
}
-Result Context::EndLoopExpr(Expr* expr) {
- pop_label(this);
+Result NameResolver::EndLoopExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::OnBrExpr(Expr* expr) {
- resolve_label_var(this, &expr->br.var);
+Result NameResolver::OnBrExpr(Expr* expr) {
+ ResolveLabelVar(&expr->br.var);
return Result::Ok;
}
-Result Context::OnBrIfExpr(Expr* expr) {
- resolve_label_var(this, &expr->br_if.var);
+Result NameResolver::OnBrIfExpr(Expr* expr) {
+ ResolveLabelVar(&expr->br_if.var);
return Result::Ok;
}
-Result Context::OnBrTableExpr(Expr* expr) {
- for (Var& target: *expr->br_table.targets)
- resolve_label_var(this, &target);
- resolve_label_var(this, &expr->br_table.default_target);
+Result NameResolver::OnBrTableExpr(Expr* expr) {
+ for (Var& target : *expr->br_table.targets)
+ ResolveLabelVar(&target);
+ ResolveLabelVar(&expr->br_table.default_target);
return Result::Ok;
}
-Result Context::OnCallExpr(Expr* expr) {
- resolve_func_var(this, &expr->call.var);
+Result NameResolver::OnCallExpr(Expr* expr) {
+ ResolveFuncVar(&expr->call.var);
return Result::Ok;
}
-Result Context::OnCallIndirectExpr(Expr* expr) {
- resolve_func_type_var(this, &expr->call_indirect.var);
+Result NameResolver::OnCallIndirectExpr(Expr* expr) {
+ ResolveFuncTypeVar(&expr->call_indirect.var);
return Result::Ok;
}
-Result Context::OnGetGlobalExpr(Expr* expr) {
- resolve_global_var(this, &expr->get_global.var);
+Result NameResolver::OnGetGlobalExpr(Expr* expr) {
+ ResolveGlobalVar(&expr->get_global.var);
return Result::Ok;
}
-Result Context::OnGetLocalExpr(Expr* expr) {
- resolve_local_var(this, &expr->get_local.var);
+Result NameResolver::OnGetLocalExpr(Expr* expr) {
+ ResolveLocalVar(&expr->get_local.var);
return Result::Ok;
}
-Result Context::BeginIfExpr(Expr* expr) {
- push_label(this, &expr->if_.true_->label);
+Result NameResolver::BeginIfExpr(Expr* expr) {
+ PushLabel(&expr->if_.true_->label);
return Result::Ok;
}
-Result Context::EndIfExpr(Expr* expr) {
- pop_label(this);
+Result NameResolver::EndIfExpr(Expr* expr) {
+ PopLabel();
return Result::Ok;
}
-Result Context::OnSetGlobalExpr(Expr* expr) {
- resolve_global_var(this, &expr->set_global.var);
+Result NameResolver::OnSetGlobalExpr(Expr* expr) {
+ ResolveGlobalVar(&expr->set_global.var);
return Result::Ok;
}
-Result Context::OnSetLocalExpr(Expr* expr) {
- resolve_local_var(this, &expr->set_local.var);
+Result NameResolver::OnSetLocalExpr(Expr* expr) {
+ ResolveLocalVar(&expr->set_local.var);
return Result::Ok;
}
-Result Context::OnTeeLocalExpr(Expr* expr) {
- resolve_local_var(this, &expr->tee_local.var);
+Result NameResolver::OnTeeLocalExpr(Expr* expr) {
+ ResolveLocalVar(&expr->tee_local.var);
return Result::Ok;
}
-static void visit_func(Context* ctx, Func* func) {
- ctx->current_func = func;
+void NameResolver::VisitFunc(Func* func) {
+ current_func_ = func;
if (decl_has_func_type(&func->decl))
- resolve_func_type_var(ctx, &func->decl.type_var);
+ ResolveFuncTypeVar(&func->decl.type_var);
- check_duplicate_bindings(ctx, &func->param_bindings, "parameter");
- check_duplicate_bindings(ctx, &func->local_bindings, "local");
+ CheckDuplicateBindings(&func->param_bindings, "parameter");
+ CheckDuplicateBindings(&func->local_bindings, "local");
- ctx->visitor.VisitFunc(func);
- ctx->current_func = nullptr;
+ visitor_.VisitFunc(func);
+ current_func_ = nullptr;
}
-static void visit_export(Context* ctx, Export* export_) {
+void NameResolver::VisitExport(Export* export_) {
switch (export_->kind) {
case ExternalKind::Func:
- resolve_func_var(ctx, &export_->var);
+ ResolveFuncVar(&export_->var);
break;
case ExternalKind::Table:
- resolve_table_var(ctx, &export_->var);
+ ResolveTableVar(&export_->var);
break;
case ExternalKind::Memory:
- resolve_memory_var(ctx, &export_->var);
+ ResolveMemoryVar(&export_->var);
break;
case ExternalKind::Global:
- resolve_global_var(ctx, &export_->var);
+ ResolveGlobalVar(&export_->var);
break;
}
}
-static void visit_global(Context* ctx, Global* global) {
- ctx->visitor.VisitExprList(global->init_expr);
+void NameResolver::VisitGlobal(Global* global) {
+ visitor_.VisitExprList(global->init_expr);
}
-static void visit_elem_segment(Context* ctx, ElemSegment* segment) {
- resolve_table_var(ctx, &segment->table_var);
- ctx->visitor.VisitExprList(segment->offset);
- for (Var& var: segment->vars)
- resolve_func_var(ctx, &var);
+void NameResolver::VisitElemSegment(ElemSegment* segment) {
+ ResolveTableVar(&segment->table_var);
+ visitor_.VisitExprList(segment->offset);
+ for (Var& var : segment->vars)
+ ResolveFuncVar(&var);
}
-static void visit_data_segment(Context* ctx, DataSegment* segment) {
- resolve_memory_var(ctx, &segment->memory_var);
- ctx->visitor.VisitExprList(segment->offset);
+void NameResolver::VisitDataSegment(DataSegment* segment) {
+ ResolveMemoryVar(&segment->memory_var);
+ visitor_.VisitExprList(segment->offset);
}
-static void visit_module(Context* ctx, Module* module) {
- ctx->current_module = module;
- check_duplicate_bindings(ctx, &module->func_bindings, "function");
- check_duplicate_bindings(ctx, &module->global_bindings, "global");
- check_duplicate_bindings(ctx, &module->func_type_bindings, "function type");
- check_duplicate_bindings(ctx, &module->table_bindings, "table");
- check_duplicate_bindings(ctx, &module->memory_bindings, "memory");
+Result NameResolver::VisitModule(Module* module) {
+ current_module_ = module;
+ CheckDuplicateBindings(&module->func_bindings, "function");
+ CheckDuplicateBindings(&module->global_bindings, "global");
+ CheckDuplicateBindings(&module->func_type_bindings, "function type");
+ CheckDuplicateBindings(&module->table_bindings, "table");
+ CheckDuplicateBindings(&module->memory_bindings, "memory");
for (Func* func : module->funcs)
- visit_func(ctx, func);
+ VisitFunc(func);
for (Export* export_ : module->exports)
- visit_export(ctx, export_);
+ VisitExport(export_);
for (Global* global : module->globals)
- visit_global(ctx, global);
+ VisitGlobal(global);
for (ElemSegment* elem_segment : module->elem_segments)
- visit_elem_segment(ctx, elem_segment);
+ VisitElemSegment(elem_segment);
for (DataSegment* data_segment : module->data_segments)
- visit_data_segment(ctx, data_segment);
+ VisitDataSegment(data_segment);
if (module->start)
- resolve_func_var(ctx, module->start);
- ctx->current_module = nullptr;
+ ResolveFuncVar(module->start);
+ current_module_ = nullptr;
+ return result_;
}
-static void visit_raw_module(Context* ctx, RawModule* raw_module) {
+void NameResolver::VisitRawModule(RawModule* raw_module) {
if (raw_module->type == RawModuleType::Text)
- visit_module(ctx, raw_module->text);
+ VisitModule(raw_module->text);
}
-static void visit_command(Context* ctx, Command* command) {
+void NameResolver::VisitCommand(Command* command) {
switch (command->type) {
case CommandType::Module:
- visit_module(ctx, command->module);
+ VisitModule(command->module);
break;
case CommandType::Action:
@@ -369,13 +403,9 @@ static void visit_command(Context* ctx, Command* command) {
* should try to resolve names when possible. */
SourceErrorHandlerNop new_error_handler;
- Context new_ctx;
- new_ctx.error_handler = &new_error_handler;
- new_ctx.lexer = ctx->lexer;
- new_ctx.result = Result::Ok;
-
- visit_raw_module(&new_ctx, command->assert_invalid.module);
- if (WABT_FAILED(new_ctx.result)) {
+ NameResolver new_resolver(lexer_, script_, &new_error_handler);
+ new_resolver.VisitRawModule(command->assert_invalid.module);
+ if (WABT_FAILED(new_resolver.result_)) {
command->type = CommandType::AssertInvalidNonBinary;
}
break;
@@ -388,46 +418,33 @@ static void visit_command(Context* ctx, Command* command) {
break;
case CommandType::AssertUnlinkable:
- visit_raw_module(ctx, command->assert_unlinkable.module);
+ VisitRawModule(command->assert_unlinkable.module);
break;
case CommandType::AssertUninstantiable:
- visit_raw_module(ctx, command->assert_uninstantiable.module);
+ VisitRawModule(command->assert_uninstantiable.module);
break;
}
}
-static void visit_script(Context* ctx, Script* script) {
- for (const std::unique_ptr<Command>& command: script->commands)
- visit_command(ctx, command.get());
-}
-
-static void init_context(Context* ctx,
- WastLexer* lexer,
- Script* script,
- SourceErrorHandler* error_handler) {
- ctx->lexer = lexer;
- ctx->error_handler = error_handler;
- ctx->result = Result::Ok;
- ctx->script = script;
+Result NameResolver::VisitScript(Script* script) {
+ for (const std::unique_ptr<Command>& command : script->commands)
+ VisitCommand(command.get());
+ return result_;
}
Result resolve_names_module(WastLexer* lexer,
Module* module,
SourceErrorHandler* error_handler) {
- Context ctx;
- init_context(&ctx, lexer, nullptr, error_handler);
- visit_module(&ctx, module);
- return ctx.result;
+ NameResolver resolver(lexer, nullptr, error_handler);
+ return resolver.VisitModule(module);
}
Result resolve_names_script(WastLexer* lexer,
Script* script,
SourceErrorHandler* error_handler) {
- Context ctx;
- init_context(&ctx, lexer, script, error_handler);
- visit_script(&ctx, script);
- return ctx.result;
+ NameResolver resolver(lexer, script, error_handler);
+ return resolver.VisitScript(script);
}
} // namespace wabt