diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ir.cc | 47 | ||||
-rw-r--r-- | src/ir.h | 7 | ||||
-rw-r--r-- | src/opcode.h | 1 | ||||
-rw-r--r-- | src/tracing.cc | 70 | ||||
-rw-r--r-- | src/tracing.h | 73 | ||||
-rw-r--r-- | src/wat-writer.cc | 71 |
6 files changed, 263 insertions, 6 deletions
@@ -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; } @@ -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() { |