summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ir.cc47
-rw-r--r--src/ir.h7
-rw-r--r--src/opcode.h1
-rw-r--r--src/tracing.cc70
-rw-r--r--src/tracing.h73
-rw-r--r--src/wat-writer.cc71
6 files changed, 263 insertions, 6 deletions
diff --git a/src/ir.cc b/src/ir.cc
index dcc9aec1..cc91a27d 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -19,8 +19,55 @@
#include <cassert>
#include <cstddef>
+namespace {
+
+const char* ExprTypeName[] = {
+ "Binary",
+ "Block",
+ "Br",
+ "BrIf",
+ "BrTable",
+ "Call",
+ "CallIndirect",
+ "Compare",
+ "Const",
+ "Convert",
+ "CurrentMemory",
+ "Drop",
+ "GetGlobal",
+ "GetLocal",
+ "GrowMemory",
+ "If",
+ "Load",
+ "Loop",
+ "Nop",
+ "Rethrow",
+ "Return",
+ "Select",
+ "SetGlobal",
+ "SetLocal",
+ "Store",
+ "TeeLocal",
+ "Throw",
+ "TryBlock",
+ "Unary",
+ "Unreachable"
+};
+
+} // end of anonymous namespace
+
namespace wabt {
+const char* GetExprTypeName(ExprType type) {
+ static_assert(WABT_ENUM_COUNT(ExprType) == WABT_ARRAY_SIZE(ExprTypeName),
+ "Malformed ExprTypeName array");
+ return ExprTypeName[size_t(type)];
+}
+
+const char* GetExprTypeName(const Expr& expr) {
+ return GetExprTypeName(expr.type);
+}
+
bool FuncSignature::operator==(const FuncSignature& rhs) const {
return param_types == rhs.param_types && result_types == rhs.result_types;
}
diff --git a/src/ir.h b/src/ir.h
index 8d391d74..9369b66e 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -120,8 +120,13 @@ enum class ExprType {
TryBlock,
Unary,
Unreachable,
+
+ First = Binary,
+ Last = Unreachable
};
+const char* GetExprTypeName(ExprType type);
+
typedef TypeVector BlockSignature;
class Expr;
@@ -167,6 +172,8 @@ class Expr {
explicit Expr(ExprType);
};
+const char* GetExprTypeName(const Expr& expr);
+
template <ExprType TypeEnum>
class ExprMixin : public Expr {
public:
diff --git a/src/opcode.h b/src/opcode.h
index ce2cd13b..8ae7e160 100644
--- a/src/opcode.h
+++ b/src/opcode.h
@@ -45,7 +45,6 @@ struct Opcode {
operator Enum() const { return enum_; }
static Opcode FromCode(uint32_t);
-
uint32_t GetCode() const { return GetInfo().code; }
const char* GetName() const { return GetInfo().name; }
Type GetResultType() const { return GetInfo().result_type; }
diff --git a/src/tracing.cc b/src/tracing.cc
new file mode 100644
index 00000000..f4669894
--- /dev/null
+++ b/src/tracing.cc
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#define WABT_TRACING 1
+#include "tracing.h"
+
+namespace {
+
+size_t indent = 0;
+const char* indent_text = " ";
+
+void Fill() {
+ for (size_t i = 0; i < indent; ++i)
+ fputs(indent_text, stderr);
+}
+
+void Indent() {
+ Fill();
+ ++indent;
+}
+
+void Dedent() {
+ if (indent)
+ --indent;
+ Fill();
+}
+
+} // end of anonymous namespace
+
+namespace wabt {
+
+// static
+
+TraceScope::TraceScope(const char* method) : method_(method) {
+ PrintEnter(method);
+ PrintNewline();
+}
+
+TraceScope::~TraceScope() {
+ Dedent();
+ fputs("<- ", stderr);
+ fputs(method_, stderr);
+ fputc('\n', stderr);
+}
+
+void TraceScope::PrintEnter(const char* method) {
+ Indent();
+ fputs("-> ", stderr);
+ fputs(method, stderr);
+ fputs("(", stderr);
+}
+
+void TraceScope::PrintNewline() {
+ fputs(")\n", stderr);
+}
+
+} // end of namespace wabt
diff --git a/src/tracing.h b/src/tracing.h
new file mode 100644
index 00000000..f1e741c5
--- /dev/null
+++ b/src/tracing.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2017 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.
+ */
+
+#ifndef WABT_TRACING_H_
+#define WABT_TRACING_H_
+
+// Provides a simple tracing class that automatically generates enter/exit
+// messages using the scope of the instance.
+//
+// It also assumes that this file is only included in .cc files.
+// Immediately before the inclusion of this file, there is a define of
+// for WABT_TRACING, defining whether tracing should be compiled in for
+// that source file.
+
+#ifndef WABT_TRACING
+#define WABT_TRACING 0
+#endif
+
+#include "common.h"
+
+namespace wabt {
+
+#if WABT_TRACING
+
+// Scoped class that automatically prints enter("->") and exit("<-")
+// lines, indented by trace level.
+struct TraceScope {
+ WABT_DISALLOW_COPY_AND_ASSIGN(TraceScope);
+ TraceScope() = delete;
+ TraceScope(const char* method);
+ template<typename... Args>
+ TraceScope(const char* method, const char* format, Args... args)
+ : method_(method) {
+ PrintEnter(method);
+ fprintf(stderr, format, args...);
+ PrintNewline();
+ }
+ ~TraceScope();
+
+ private:
+ const char* method_;
+ void PrintEnter(const char* method);
+ void PrintNewline();
+};
+
+#define WABT_TRACE(method_name) TraceScope _func_(#method_name)
+
+#define WABT_TRACE_ARGS(method_name, format, ...) \
+ TraceScope _func_(#method_name, format, __VA_ARGS__)
+
+#else
+
+#define WABT_TRACE(method)
+#define WABT_TRACE_ARGS(method_name, format, ...)
+
+#endif
+
+} // end namespace wabt
+
+#endif // WABT_TRACING_H_
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index 9b411b8a..5f5cd05c 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -33,6 +33,9 @@
#include "stream.h"
#include "writer.h"
+#define WABT_TRACING 0
+#include "tracing.h"
+
#define INDENT_SIZE 2
#define NO_FORCE_NEWLINE 0
#define FORCE_NEWLINE 1
@@ -62,7 +65,14 @@ enum class NextChar {
};
struct ExprTree {
- explicit ExprTree(const Expr* expr) : expr(expr) {}
+ explicit ExprTree(const Expr* expr = nullptr) : expr(expr) {}
+ // For debugging.
+ std::string describe() const {
+ std::string result("ExprTree(");
+ if (expr)
+ result.append(GetExprTypeName(*expr));
+ return result + ")";
+ }
const Expr* expr;
std::vector<ExprTree> children;
@@ -465,6 +475,7 @@ void WatWriter::WriteConst(const Const* const_) {
}
void WatWriter::WriteExpr(const Expr* expr) {
+ WABT_TRACE_ARGS(WriteExpr, "%s", GetExprTypeName(*expr));
switch (expr->type) {
case ExprType::Binary:
WritePutsNewline(cast<BinaryExpr>(expr)->opcode.GetName());
@@ -647,13 +658,14 @@ void WatWriter::WriteExpr(const Expr* expr) {
break;
default:
- fprintf(stderr, "bad expr type: %d\n", static_cast<int>(expr->type));
+ fprintf(stderr, "bad expr type: %s\n", GetExprTypeName(*expr));
assert(0);
break;
}
}
void WatWriter::WriteExprList(const Expr* first) {
+ WABT_TRACE(WriteExprList);
for (const Expr* expr = first; expr; expr = expr->next)
WriteExpr(expr);
}
@@ -699,6 +711,7 @@ Index WatWriter::GetFuncSigResultCount(const Var* var) {
}
void WatWriter::WriteFoldedExpr(const Expr* expr) {
+ WABT_TRACE_ARGS(WriteFoldedExpr, "%s", GetExprTypeName(*expr));
switch (expr->type) {
case ExprType::Binary:
case ExprType::Compare:
@@ -776,18 +789,37 @@ void WatWriter::WriteFoldedExpr(const Expr* expr) {
PushExpr(expr, current_func_->decl.sig.result_types.size(), 1);
break;
+ case ExprType::Rethrow:
+ PushExpr(expr, 0, 0);
+ break;
+
case ExprType::Select:
PushExpr(expr, 3, 1);
break;
+ case ExprType::Throw: {
+ auto throw_ = cast<ThrowExpr>(expr);
+ Index operand_count = 0;
+ if (Exception* except = module_->GetExcept(throw_->var)) {
+ operand_count = except->sig.size();
+ }
+ PushExpr(expr, operand_count, 0);
+ break;
+ }
+
+ case ExprType::TryBlock:
+ PushExpr(expr, 0, cast<TryExpr>(expr)->block->sig.size());
+ break;
+
default:
- fprintf(stderr, "bad expr type: %d\n", static_cast<int>(expr->type));
+ fprintf(stderr, "bad expr type: %s\n", GetExprTypeName(*expr));
assert(0);
break;
}
}
void WatWriter::WriteFoldedExprList(const Expr* first) {
+ WABT_TRACE(WriteFoldedExprList);
for (const Expr* expr = first; expr; expr = expr->next)
WriteFoldedExpr(expr);
}
@@ -795,13 +827,15 @@ void WatWriter::WriteFoldedExprList(const Expr* first) {
void WatWriter::PushExpr(const Expr* expr,
Index operand_count,
Index result_count) {
+ WABT_TRACE_ARGS(PushExpr, "%s, %" PRIindex ", %" PRIindex "",
+ GetExprTypeName(*expr), operand_count, result_count);
if (operand_count <= expr_tree_stack_.size()) {
auto last_operand = expr_tree_stack_.end();
auto first_operand = last_operand - operand_count;
ExprTree tree(expr);
std::move(first_operand, last_operand, std::back_inserter(tree.children));
expr_tree_stack_.erase(first_operand, last_operand);
- expr_tree_stack_.push_back(std::move(tree));
+ expr_tree_stack_.emplace_back(tree);
if (result_count == 0)
FlushExprTreeStack();
} else {
@@ -811,6 +845,7 @@ void WatWriter::PushExpr(const Expr* expr,
}
void WatWriter::FlushExprTree(const ExprTree& expr_tree) {
+ WABT_TRACE_ARGS(FlushExprTree, "%s", GetExprTypeName(*expr_tree.expr));
switch (expr_tree.expr->type) {
case ExprType::Block:
WritePuts("(", NextChar::None);
@@ -850,6 +885,31 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) {
break;
}
+ case ExprType::TryBlock: {
+ auto try_ = cast<TryExpr>(expr_tree.expr);
+ WritePuts("(", NextChar::None);
+ WriteBeginBlock(LabelType::Try, try_->block,
+ Opcode::Try_Opcode.GetName());
+ WriteFoldedExprList(try_->block->first);
+ FlushExprTreeStack();
+ for (const Catch* catch_ : try_->catches) {
+ WritePuts("(", NextChar::None);
+ if (catch_->IsCatchAll()) {
+ WritePutsNewline(Opcode::CatchAll_Opcode.GetName());
+ } else {
+ WritePutsSpace(Opcode::Catch_Opcode.GetName());
+ WriteVar(&catch_->var, NextChar::Newline);
+ }
+ Indent();
+ label_stack_.back().label_type = LabelType::Catch;
+ WriteFoldedExprList(catch_->first);
+ FlushExprTreeStack();
+ WriteCloseNewline();
+ }
+ WriteCloseNewline();
+ break;
+ }
+
default: {
WritePuts("(", NextChar::None);
WriteExpr(expr_tree.expr);
@@ -862,8 +922,9 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) {
}
void WatWriter::FlushExprTreeVector(const std::vector<ExprTree>& expr_trees) {
+ WABT_TRACE_ARGS(FlushExprTreeVector, "%zu", expr_trees.size());
for (auto expr_tree : expr_trees)
- FlushExprTree(expr_tree);
+ FlushExprTree(expr_tree);
}
void WatWriter::FlushExprTreeStack() {