summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apply-names.cc31
-rw-r--r--src/binary-reader-ir.cc16
-rw-r--r--src/binary-writer.cc17
-rw-r--r--src/c-writer.cc32
-rw-r--r--src/generate-names.cc28
-rw-r--r--src/ir.cc14
-rw-r--r--src/ir.h3
-rw-r--r--src/resolve-names.cc27
-rw-r--r--src/wast-parser.cc16
-rw-r--r--src/wast-parser.h5
-rw-r--r--src/wat-writer.cc22
11 files changed, 88 insertions, 123 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc
index 4a3b0042..e03b2377 100644
--- a/src/apply-names.cc
+++ b/src/apply-names.cc
@@ -86,9 +86,7 @@ class NameApplier : public ExprVisitor::DelegateNop {
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<std::string> param_and_local_index_to_name_;
std::vector<std::string> labels_;
};
@@ -208,26 +206,14 @@ Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) {
return Result::Error;
}
- Index num_params = func->GetNumParams();
- std::string* name;
- if (local_index < num_params) {
- /* param */
- assert(local_index < param_index_to_name_.size());
- name = &param_index_to_name_[local_index];
- } else {
- /* local */
- local_index -= num_params;
- assert(local_index < local_index_to_name_.size());
- name = &local_index_to_name_[local_index];
- }
-
+ std::string name = param_and_local_index_to_name_[local_index];
if (var->is_name()) {
- assert(*name == var->name());
+ assert(name == var->name());
return Result::Ok;
}
- if (!name->empty()) {
- var->set_name(*name);
+ if (!name.empty()) {
+ var->set_name(name);
}
return Result::Ok;
}
@@ -386,11 +372,8 @@ Result NameApplier::VisitFunc(Index func_index, Func* func) {
CHECK_RESULT(UseNameForFuncTypeVar(&func->decl.type_var));
}
- MakeTypeBindingReverseMapping(func->decl.sig.param_types.size(),
- func->param_bindings, &param_index_to_name_);
-
- MakeTypeBindingReverseMapping(func->local_types.size(), func->local_bindings,
- &local_index_to_name_);
+ MakeTypeBindingReverseMapping(func->GetNumParamsAndLocals(), func->bindings,
+ &param_and_local_index_to_name_);
CHECK_RESULT(visitor_.VisitFunc(func));
current_func_ = nullptr;
diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc
index 7c4b9699..24828f2e 100644
--- a/src/binary-reader-ir.cc
+++ b/src/binary-reader-ir.cc
@@ -1144,20 +1144,8 @@ Result BinaryReaderIR::OnLocalName(Index func_index,
}
Func* func = module_->funcs[func_index];
- Index num_params = func->GetNumParams();
- BindingHash* bindings;
- Index index;
- if (local_index < num_params) {
- // param name
- bindings = &func->param_bindings;
- index = local_index;
- } else {
- // local name
- bindings = &func->local_bindings;
- index = local_index - num_params;
- }
- bindings->emplace(GetUniqueName(bindings, MakeDollarName(name)),
- Binding(index));
+ func->bindings.emplace(GetUniqueName(&func->bindings, MakeDollarName(name)),
+ Binding(local_index));
return Result::Ok;
}
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index 9be23410..dc26128d 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -1075,30 +1075,19 @@ Result BinaryWriter::WriteModule() {
WriteU32Leb128(stream_, module_->funcs.size(), "num functions");
for (size_t i = 0; i < module_->funcs.size(); ++i) {
const Func* func = module_->funcs[i];
- Index num_params = func->GetNumParams();
- Index num_locals = func->local_types.size();
Index num_params_and_locals = func->GetNumParamsAndLocals();
WriteU32Leb128(stream_, i, "function index");
WriteU32Leb128(stream_, num_params_and_locals, "num locals");
- MakeTypeBindingReverseMapping(func->decl.sig.param_types.size(),
- func->param_bindings, &index_to_name);
- for (size_t j = 0; j < num_params; ++j) {
+ MakeTypeBindingReverseMapping(num_params_and_locals, func->bindings,
+ &index_to_name);
+ for (size_t j = 0; j < num_params_and_locals; ++j) {
const std::string& name = index_to_name[j];
wabt_snprintf(desc, sizeof(desc), "local name %" PRIzd, j);
WriteU32Leb128(stream_, j, "local index");
WriteDebugName(stream_, name, desc);
}
-
- MakeTypeBindingReverseMapping(func->local_types.size(),
- func->local_bindings, &index_to_name);
- for (size_t j = 0; j < num_locals; ++j) {
- const std::string& name = index_to_name[j];
- wabt_snprintf(desc, sizeof(desc), "local name %" PRIzd, num_params + j);
- WriteU32Leb128(stream_, num_params + j, "local index");
- WriteDebugName(stream_, name, desc);
- }
}
EndSubsection();
EndSection();
diff --git a/src/c-writer.cc b/src/c-writer.cc
index 280ef5f7..0e8d6f91 100644
--- a/src/c-writer.cc
+++ b/src/c-writer.cc
@@ -240,8 +240,9 @@ class CWriter {
void WriteInit();
void WriteFuncs();
void Write(const Func&);
- void WriteParams();
- void WriteLocals();
+ void WriteParamsAndLocals();
+ void WriteParams(const std::vector<std::string>& index_to_name);
+ void WriteLocals(const std::vector<std::string>& index_to_name);
void WriteStackVarDeclarations();
void Write(const ExprList&);
@@ -1281,8 +1282,7 @@ void CWriter::Write(const Func& func) {
Write("static ", ResultType(func.decl.sig.result_types), " ",
GlobalName(func.name), "(");
- WriteParams();
- WriteLocals();
+ WriteParamsAndLocals();
Write("FUNC_PROLOGUE;", Newline());
stream_ = &func_stream_;
@@ -1316,13 +1316,18 @@ void CWriter::Write(const Func& func) {
func_ = nullptr;
}
-void CWriter::WriteParams() {
- if (func_->decl.sig.param_types.empty()) {
+void CWriter::WriteParamsAndLocals() {
+ std::vector<std::string> index_to_name;
+ MakeTypeBindingReverseMapping(func_->GetNumParamsAndLocals(), func_->bindings,
+ &index_to_name);
+ WriteParams(index_to_name);
+ WriteLocals(index_to_name);
+}
+
+void CWriter::WriteParams(const std::vector<std::string>& index_to_name) {
+ if (func_->GetNumParams() == 0) {
Write("void");
} else {
- std::vector<std::string> index_to_name;
- MakeTypeBindingReverseMapping(func_->decl.sig.param_types.size(),
- func_->param_bindings, &index_to_name);
Indent(4);
for (Index i = 0; i < func_->GetNumParams(); ++i) {
if (i != 0) {
@@ -1338,10 +1343,8 @@ void CWriter::WriteParams() {
Write(") ", OpenBrace());
}
-void CWriter::WriteLocals() {
- std::vector<std::string> index_to_name;
- MakeTypeBindingReverseMapping(func_->local_types.size(),
- func_->local_bindings, &index_to_name);
+void CWriter::WriteLocals(const std::vector<std::string>& index_to_name) {
+ Index num_params = func_->GetNumParams();
for (Type type : {Type::I32, Type::I64, Type::F32, Type::F64}) {
Index local_index = 0;
size_t count = 0;
@@ -1356,7 +1359,8 @@ void CWriter::WriteLocals() {
Write(Newline());
}
- Write(DefineLocalScopeName(index_to_name[local_index]), " = 0");
+ Write(DefineLocalScopeName(index_to_name[num_params + local_index]),
+ " = 0");
++count;
}
++local_index;
diff --git a/src/generate-names.cc b/src/generate-names.cc
index 875f684f..b7760886 100644
--- a/src/generate-names.cc
+++ b/src/generate-names.cc
@@ -79,7 +79,8 @@ class NameGenerator : public ExprVisitor::DelegateNop {
Index index,
std::string* out_str);
- void GenerateAndBindLocalNames(BindingHash* bindings, const char* prefix);
+ void GenerateAndBindLocalNames(Func* func);
+
template <typename T>
Result VisitAll(const std::vector<T*>& items,
Result (NameGenerator::*func)(Index, T*));
@@ -97,7 +98,6 @@ class NameGenerator : public ExprVisitor::DelegateNop {
Module* module_ = nullptr;
ExprVisitor visitor_;
- std::vector<std::string> index_to_name_;
Index label_count_ = 0;
Index num_func_imports_ = 0;
@@ -185,17 +185,20 @@ void NameGenerator::MaybeUseAndBindName(BindingHash* bindings,
}
}
-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];
+void NameGenerator::GenerateAndBindLocalNames(Func* func) {
+ std::vector<std::string> index_to_name;
+ MakeTypeBindingReverseMapping(func->GetNumParamsAndLocals(), func->bindings,
+ &index_to_name);
+ 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;
}
+ const char* prefix = i < func->GetNumParams() ? "$p" : "$l";
std::string new_name;
- GenerateAndBindName(bindings, prefix, i, &new_name);
- index_to_name_[i] = new_name;
+ GenerateAndBindName(&func->bindings, prefix, i, &new_name);
+ index_to_name[i] = new_name;
}
}
@@ -222,14 +225,7 @@ Result NameGenerator::BeginIfExceptExpr(IfExceptExpr* expr) {
Result NameGenerator::VisitFunc(Index func_index, Func* func) {
MaybeGenerateAndBindName(&module_->func_bindings, "$f", func_index,
&func->name);
-
- MakeTypeBindingReverseMapping(func->decl.sig.param_types.size(),
- func->param_bindings, &index_to_name_);
- GenerateAndBindLocalNames(&func->param_bindings, "$p");
-
- MakeTypeBindingReverseMapping(func->local_types.size(), func->local_bindings,
- &index_to_name_);
- GenerateAndBindLocalNames(&func->local_bindings, "$l");
+ GenerateAndBindLocalNames(func);
label_count_ = 0;
CHECK_RESULT(visitor_.VisitFunc(func));
diff --git a/src/ir.cc b/src/ir.cc
index 13530ac4..52bea0cc 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -213,19 +213,7 @@ Index Func::GetLocalIndex(const Var& var) const {
if (var.is_index()) {
return var.index();
}
-
- Index result = param_bindings.FindIndex(var);
- if (result != kInvalidIndex) {
- return result;
- }
-
- result = local_bindings.FindIndex(var);
- if (result == kInvalidIndex) {
- return result;
- }
-
- // The locals start after all the params.
- return decl.GetNumParams() + result;
+ return bindings.FindIndex(var);
}
const Func* Module::GetFunc(const Var& var) const {
diff --git a/src/ir.h b/src/ir.h
index 168e856c..9aec0da3 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -510,8 +510,7 @@ struct Func {
std::string name;
FuncDeclaration decl;
LocalTypes local_types;
- BindingHash param_bindings;
- BindingHash local_bindings;
+ BindingHash bindings;
ExprList exprs;
};
diff --git a/src/resolve-names.cc b/src/resolve-names.cc
index 9d24f2a7..1a6ec79f 100644
--- a/src/resolve-names.cc
+++ b/src/resolve-names.cc
@@ -69,6 +69,9 @@ class NameResolver : public ExprVisitor::DelegateNop {
void PushLabel(const std::string& label);
void PopLabel();
void CheckDuplicateBindings(const BindingHash* bindings, const char* desc);
+ void PrintDuplicateBindingsError(const BindingHash::value_type&,
+ const BindingHash::value_type&,
+ const char* desc);
void ResolveLabelVar(Var* var);
void ResolveVar(const BindingHash* bindings, Var* var, const char* desc);
void ResolveFuncVar(Var* var);
@@ -125,14 +128,20 @@ void NameResolver::CheckDuplicateBindings(const BindingHash* bindings,
const char* desc) {
bindings->FindDuplicates([this, desc](const BindingHash::value_type& a,
const BindingHash::value_type& b) {
- // 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;
- PrintError(&loc, "redefinition of %s \"%s\"", desc, a.first.c_str());
+ PrintDuplicateBindingsError(a, b, desc);
});
}
+void NameResolver::PrintDuplicateBindingsError(const BindingHash::value_type& a,
+ const BindingHash::value_type& b,
+ const char* desc) {
+ // 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;
+ PrintError(&loc, "redefinition of %s \"%s\"", desc, a.first.c_str());
+}
+
void NameResolver::ResolveLabelVar(Var* var) {
if (var->is_name()) {
for (int i = labels_.size() - 1; i >= 0; --i) {
@@ -370,8 +379,12 @@ void NameResolver::VisitFunc(Func* func) {
ResolveFuncTypeVar(&func->decl.type_var);
}
- CheckDuplicateBindings(&func->param_bindings, "parameter");
- CheckDuplicateBindings(&func->local_bindings, "local");
+ func->bindings.FindDuplicates(
+ [=](const BindingHash::value_type& a, const BindingHash::value_type& b) {
+ const char* desc =
+ (a.second.index < func->GetNumParams()) ? "parameter" : "local";
+ PrintDuplicateBindingsError(a, b, desc);
+ });
visitor_.VisitFunc(func);
current_func_ = nullptr;
diff --git a/src/wast-parser.cc b/src/wast-parser.cc
index 7b3b6e48..f9e89151 100644
--- a/src/wast-parser.cc
+++ b/src/wast-parser.cc
@@ -887,7 +887,7 @@ Result WastParser::ParseFuncModuleField(Module* module) {
Func& func = import->func;
CHECK_RESULT(ParseInlineImport(import.get()));
CHECK_RESULT(ParseTypeUseOpt(&func.decl));
- CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.param_bindings));
+ CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.bindings));
CHECK_RESULT(ErrorIfLpar({"type", "param", "result"}));
auto field =
MakeUnique<ImportModuleField>(std::move(import), GetLocation());
@@ -896,10 +896,10 @@ Result WastParser::ParseFuncModuleField(Module* module) {
auto field = MakeUnique<FuncModuleField>(loc, name);
Func& func = field->func;
CHECK_RESULT(ParseTypeUseOpt(&func.decl));
- CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.param_bindings));
+ CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.bindings));
TypeVector local_types;
CHECK_RESULT(ParseBoundValueTypeList(TokenType::Local, &local_types,
- &func.local_bindings));
+ &func.bindings, func.GetNumParams()));
func.local_types.Set(local_types);
CHECK_RESULT(ParseTerminatingInstrList(&func.exprs));
module->AppendField(std::move(field));
@@ -985,8 +985,8 @@ Result WastParser::ParseImportModuleField(Module* module) {
CHECK_RESULT(ParseTypeUseOpt(&import->func.decl));
EXPECT(Rpar);
} else {
- CHECK_RESULT(ParseFuncSignature(&import->func.decl.sig,
- &import->func.param_bindings));
+ CHECK_RESULT(
+ ParseFuncSignature(&import->func.decl.sig, &import->func.bindings));
CHECK_RESULT(ErrorIfLpar({"param", "result"}));
EXPECT(Rpar);
}
@@ -1232,7 +1232,8 @@ Result WastParser::ParseUnboundFuncSignature(FuncSignature* sig) {
Result WastParser::ParseBoundValueTypeList(TokenType token,
TypeVector* types,
- BindingHash* bindings) {
+ BindingHash* bindings,
+ Index binding_index_offset) {
WABT_TRACE(ParseBoundValueTypeList);
while (MatchLpar(token)) {
if (PeekMatch(TokenType::Var)) {
@@ -1241,7 +1242,8 @@ Result WastParser::ParseBoundValueTypeList(TokenType token,
Location loc = GetLocation();
ParseBindVarOpt(&name);
CHECK_RESULT(ParseValueType(&type));
- bindings->emplace(name, Binding(loc, types->size()));
+ bindings->emplace(name,
+ Binding(loc, binding_index_offset + types->size()));
types->push_back(type);
} else {
CHECK_RESULT(ParseValueTypeList(types));
diff --git a/src/wast-parser.h b/src/wast-parser.h
index 8a1b0a69..09e19e55 100644
--- a/src/wast-parser.h
+++ b/src/wast-parser.h
@@ -149,7 +149,10 @@ class WastParser {
Result ParseTypeUseOpt(FuncDeclaration*);
Result ParseFuncSignature(FuncSignature*, BindingHash* param_bindings);
Result ParseUnboundFuncSignature(FuncSignature*);
- Result ParseBoundValueTypeList(TokenType, TypeVector*, BindingHash*);
+ Result ParseBoundValueTypeList(TokenType,
+ TypeVector*,
+ BindingHash*,
+ Index binding_index_offset = 0);
Result ParseUnboundValueTypeList(TokenType, TypeVector*);
Result ParseResultList(TypeVector*);
Result ParseInstrList(ExprList*);
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index 9297b14a..9f646e50 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -157,9 +157,9 @@ class WatWriter {
void WriteInitExpr(const ExprList& expr);
template <typename T>
void WriteTypeBindings(const char* prefix,
- const Func& func,
const T& types,
- const BindingHash& bindings);
+ const std::vector<std::string>& index_to_name,
+ Index binding_index_offset = 0);
void WriteBeginFunc(const Func& func);
void WriteFunc(const Func& func);
void WriteBeginGlobal(const Global& global);
@@ -203,7 +203,6 @@ class WatWriter {
Result result_ = Result::Ok;
int indent_ = 0;
NextChar next_char_ = NextChar::None;
- std::vector<std::string> index_to_name_;
std::vector<Label> label_stack_;
std::vector<ExprTree> expr_tree_stack_;
std::multimap<std::pair<ExternalKind, Index>, const Export*>
@@ -1325,11 +1324,9 @@ void WatWriter::WriteInitExpr(const ExprList& expr) {
template <typename T>
void WatWriter::WriteTypeBindings(const char* prefix,
- const Func& func,
const T& types,
- const BindingHash& bindings) {
- MakeTypeBindingReverseMapping(types.size(), bindings, &index_to_name_);
-
+ const std::vector<std::string>& index_to_name,
+ Index binding_index_offset) {
/* named params/locals must be specified by themselves, but nameless
* params/locals can be compressed, e.g.:
* (param $foo i32)
@@ -1343,7 +1340,7 @@ void WatWriter::WriteTypeBindings(const char* prefix,
is_open = true;
}
- const std::string& name = index_to_name_[index];
+ const std::string& name = index_to_name[binding_index_offset + index];
if (!name.empty()) {
WriteString(name, NextChar::Space);
}
@@ -1390,12 +1387,15 @@ void WatWriter::WriteBeginFunc(const Func& func) {
void WatWriter::WriteFunc(const Func& func) {
WriteBeginFunc(func);
- WriteTypeBindings("param", func, func.decl.sig.param_types,
- func.param_bindings);
+ std::vector<std::string> index_to_name;
+ MakeTypeBindingReverseMapping(func.GetNumParamsAndLocals(), func.bindings,
+ &index_to_name);
+ WriteTypeBindings("param", func.decl.sig.param_types, index_to_name);
WriteTypes(func.decl.sig.result_types, "result");
WriteNewline(NO_FORCE_NEWLINE);
if (func.local_types.size()) {
- WriteTypeBindings("local", func, func.local_types, func.local_bindings);
+ WriteTypeBindings("local", func.local_types, index_to_name,
+ func.GetNumParams());
}
WriteNewline(NO_FORCE_NEWLINE);
label_stack_.clear();