summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-interpreter.cc13
-rw-r--r--src/binary-writer-spec.cc5
-rw-r--r--src/binary-writer-spec.h1
-rw-r--r--src/binary-writer.cc321
-rw-r--r--src/binary-writer.h4
-rw-r--r--src/emscripten-helpers.cc18
-rw-r--r--src/interpreter.h4
-rw-r--r--src/stream.cc152
-rw-r--r--src/stream.h60
-rw-r--r--src/tools/wasm-link.cc1
-rw-r--r--src/tools/wasm-objdump.cc1
-rw-r--r--src/tools/wasm2wast.cc7
-rw-r--r--src/tools/wast-desugar.cc5
-rw-r--r--src/tools/wast2wasm.cc9
-rw-r--r--src/wat-writer.cc23
-rw-r--r--src/wat-writer.h4
-rw-r--r--src/writer.cc164
-rw-r--r--src/writer.h84
18 files changed, 382 insertions, 494 deletions
diff --git a/src/binary-reader-interpreter.cc b/src/binary-reader-interpreter.cc
index 4cac588f..8cf4effa 100644
--- a/src/binary-reader-interpreter.cc
+++ b/src/binary-reader-interpreter.cc
@@ -26,8 +26,8 @@
#include "src/cast.h"
#include "src/error-handler.h"
#include "src/interpreter.h"
+#include "src/stream.h"
#include "src/type-checker.h"
-#include "src/writer.h"
namespace wabt {
@@ -265,7 +265,7 @@ class BinaryReaderInterpreter : public BinaryReaderNop {
std::vector<Label> label_stack;
IstreamOffsetVectorVector func_fixups;
IstreamOffsetVectorVector depth_fixups;
- MemoryWriter istream_writer;
+ MemoryStream istream_;
IstreamOffset istream_offset = 0;
/* mappings from module index space to env index space; this won't just be a
* translation, because imported values will be resolved as well */
@@ -295,14 +295,14 @@ BinaryReaderInterpreter::BinaryReaderInterpreter(
: error_handler(error_handler),
env(env),
module(module),
- istream_writer(std::move(istream)),
- istream_offset(istream_writer.output_buffer().size()) {
+ istream_(std::move(istream)),
+ istream_offset(istream_.output_buffer().size()) {
typechecker.set_error_callback(
[this](const char* msg) { PrintError("%s", msg); });
}
std::unique_ptr<OutputBuffer> BinaryReaderInterpreter::ReleaseOutputBuffer() {
- return istream_writer.ReleaseOutputBuffer();
+ return istream_.ReleaseOutputBuffer();
}
Label* BinaryReaderInterpreter::GetLabel(Index depth) {
@@ -374,7 +374,8 @@ IstreamOffset BinaryReaderInterpreter::GetIstreamOffset() {
wabt::Result BinaryReaderInterpreter::EmitDataAt(IstreamOffset offset,
const void* data,
IstreamOffset size) {
- return istream_writer.WriteData(offset, data, size);
+ istream_.WriteDataAt(offset, data, size);
+ return istream_.result();
}
wabt::Result BinaryReaderInterpreter::EmitData(const void* data,
diff --git a/src/binary-writer-spec.cc b/src/binary-writer-spec.cc
index d8cfd175..1c585780 100644
--- a/src/binary-writer-spec.cc
+++ b/src/binary-writer-spec.cc
@@ -27,7 +27,6 @@
#include "src/ir.h"
#include "src/stream.h"
#include "src/string-view.h"
-#include "src/writer.h"
namespace wabt {
@@ -304,8 +303,8 @@ void BinaryWriterSpec::WriteActionResultType(const Script& script,
}
void BinaryWriterSpec::WriteModule(string_view filename, const Module& module) {
- MemoryStream memory_stream;
- result_ = WriteBinaryModule(&memory_stream.writer(), &module,
+ MemoryStream memory_stream(spec_options_->log_stream);
+ result_ = WriteBinaryModule(&memory_stream, &module,
&spec_options_->write_binary_options);
if (Succeeded(result_) && write_modules_)
result_ = memory_stream.WriteToFile(filename);
diff --git a/src/binary-writer-spec.h b/src/binary-writer-spec.h
index 3d39c289..e939752e 100644
--- a/src/binary-writer-spec.h
+++ b/src/binary-writer-spec.h
@@ -24,6 +24,7 @@
namespace wabt {
struct WriteBinarySpecOptions {
+ Stream* log_stream = nullptr;
const char* json_filename = nullptr;
WriteBinaryOptions write_binary_options;
};
diff --git a/src/binary-writer.cc b/src/binary-writer.cc
index 7eec73b6..6fc94893 100644
--- a/src/binary-writer.cc
+++ b/src/binary-writer.cc
@@ -31,7 +31,6 @@
#include "src/leb128.h"
#include "src/stream.h"
#include "src/string-view.h"
-#include "src/writer.h"
#define PRINT_HEADER_NO_INDEX -1
#define MAX_U32_LEB128_BYTES 5
@@ -101,7 +100,7 @@ class BinaryWriter {
WABT_DISALLOW_COPY_AND_ASSIGN(BinaryWriter);
public:
- BinaryWriter(Writer*, const WriteBinaryOptions* options);
+ BinaryWriter(Stream*, const WriteBinaryOptions* options);
Result WriteModule(const Module* module);
@@ -138,7 +137,7 @@ class BinaryWriter {
void WriteExceptType(const TypeVector* except_types);
void WriteRelocSection(const RelocSection* reloc_section);
- Stream stream_;
+ Stream* stream_;
const WriteBinaryOptions* options_ = nullptr;
std::vector<RelocSection> reloc_sections_;
@@ -163,15 +162,15 @@ static uint8_t log2_u32(uint32_t x) {
return result;
}
-BinaryWriter::BinaryWriter(Writer* writer, const WriteBinaryOptions* options)
- : stream_(writer, options->log_stream), options_(options) {}
+BinaryWriter::BinaryWriter(Stream* stream, const WriteBinaryOptions* options)
+ : stream_(stream), options_(options) {}
void BinaryWriter::WriteHeader(const char* name, int index) {
- if (stream_.has_log_stream()) {
+ if (stream_->has_log_stream()) {
if (index == PRINT_HEADER_NO_INDEX) {
- stream_.log_stream().Writef("; %s\n", name);
+ stream_->log_stream().Writef("; %s\n", name);
} else {
- stream_.log_stream().Writef("; %s %d\n", name, index);
+ stream_->log_stream().Writef("; %s %d\n", name, index);
}
}
}
@@ -181,10 +180,10 @@ Offset BinaryWriter::WriteU32Leb128Space(Offset leb_size_guess,
const char* desc) {
assert(leb_size_guess <= MAX_U32_LEB128_BYTES);
uint8_t data[MAX_U32_LEB128_BYTES] = {0};
- Offset result = stream_.offset();
+ Offset result = stream_->offset();
Offset bytes_to_write =
options_->canonicalize_lebs ? leb_size_guess : MAX_U32_LEB128_BYTES;
- stream_.WriteData(data, bytes_to_write, desc);
+ stream_->WriteData(data, bytes_to_write, desc);
return result;
}
@@ -192,20 +191,20 @@ Offset BinaryWriter::WriteFixupU32Leb128Size(Offset offset,
Offset leb_size_guess,
const char* desc) {
if (options_->canonicalize_lebs) {
- Offset size = stream_.offset() - offset - leb_size_guess;
+ Offset size = stream_->offset() - offset - leb_size_guess;
Offset leb_size = U32Leb128Length(size);
Offset delta = leb_size - leb_size_guess;
if (delta != 0) {
Offset src_offset = offset + leb_size_guess;
Offset dst_offset = offset + leb_size;
- stream_.MoveData(dst_offset, src_offset, size);
+ stream_->MoveData(dst_offset, src_offset, size);
}
- WriteU32Leb128At(&stream_, offset, size, desc);
- stream_.AddOffset(delta);
+ WriteU32Leb128At(stream_, offset, size, desc);
+ stream_->AddOffset(delta);
return delta;
} else {
- Offset size = stream_.offset() - offset - MAX_U32_LEB128_BYTES;
- WriteFixedU32Leb128At(&stream_, offset, size, desc);
+ Offset size = stream_->offset() - offset - MAX_U32_LEB128_BYTES;
+ WriteFixedU32Leb128At(stream_, offset, size, desc);
return 0;
}
}
@@ -230,12 +229,12 @@ void BinaryWriter::BeginKnownSection(BinarySection section_code,
GetSectionName(section_code),
static_cast<unsigned>(section_code));
WriteHeader(desc, PRINT_HEADER_NO_INDEX);
- stream_.WriteU8Enum(section_code, "section code");
+ stream_->WriteU8Enum(section_code, "section code");
last_section_type_ = section_code;
last_section_leb_size_guess_ = leb_size_guess;
last_section_offset_ =
WriteU32Leb128Space(leb_size_guess, "section size (guess)");
- last_section_payload_offset_ = stream_.offset();
+ last_section_payload_offset_ = stream_->offset();
}
void BinaryWriter::BeginCustomSection(const char* name, size_t leb_size_guess) {
@@ -243,13 +242,13 @@ void BinaryWriter::BeginCustomSection(const char* name, size_t leb_size_guess) {
char desc[100];
wabt_snprintf(desc, sizeof(desc), "section \"%s\"", name);
WriteHeader(desc, PRINT_HEADER_NO_INDEX);
- stream_.WriteU8Enum(BinarySection::Custom, "custom section code");
+ stream_->WriteU8Enum(BinarySection::Custom, "custom section code");
last_section_type_ = BinarySection::Custom;
last_section_leb_size_guess_ = leb_size_guess;
last_section_offset_ =
WriteU32Leb128Space(leb_size_guess, "section size (guess)");
- last_section_payload_offset_ = stream_.offset();
- WriteStr(&stream_, name, "custom section name", PrintChars::Yes);
+ last_section_payload_offset_ = stream_->offset();
+ WriteStr(stream_, name, "custom section name", PrintChars::Yes);
}
void BinaryWriter::EndSection() {
@@ -268,7 +267,7 @@ void BinaryWriter::BeginSubsection(const char* name, size_t leb_size_guess) {
last_subsection_leb_size_guess_ = leb_size_guess;
last_subsection_offset_ =
WriteU32Leb128Space(leb_size_guess, "subsection size (guess)");
- last_subsection_payload_offset_ = stream_.offset();
+ last_subsection_payload_offset_ = stream_->offset();
}
void BinaryWriter::EndSubsection() {
@@ -297,7 +296,7 @@ void BinaryWriter::AddReloc(RelocType reloc_type, Index index) {
}
// Add a new relocation to the curent reloc section
- size_t offset = stream_.offset() - last_section_payload_offset_;
+ size_t offset = stream_->offset() - last_section_payload_offset_;
current_reloc_section_->relocations.emplace_back(reloc_type, offset, index);
}
@@ -306,9 +305,9 @@ void BinaryWriter::WriteU32Leb128WithReloc(Index index,
RelocType reloc_type) {
if (options_->relocatable) {
AddReloc(reloc_type, index);
- WriteFixedU32Leb128(&stream_, index, desc);
+ WriteFixedU32Leb128(stream_, index, desc);
} else {
- WriteU32Leb128(&stream_, index, desc);
+ WriteU32Leb128(stream_, index, desc);
}
}
@@ -329,73 +328,73 @@ void BinaryWriter::WriteExpr(const Module* module,
const Expr* expr) {
switch (expr->type()) {
case ExprType::Binary:
- WriteOpcode(&stream_, cast<BinaryExpr>(expr)->opcode);
+ WriteOpcode(stream_, cast<BinaryExpr>(expr)->opcode);
break;
case ExprType::Block:
- WriteOpcode(&stream_, Opcode::Block);
- write_inline_signature_type(&stream_, cast<BlockExpr>(expr)->block.sig);
+ WriteOpcode(stream_, Opcode::Block);
+ write_inline_signature_type(stream_, cast<BlockExpr>(expr)->block.sig);
WriteExprList(module, func, cast<BlockExpr>(expr)->block.exprs);
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
break;
case ExprType::Br:
- WriteOpcode(&stream_, Opcode::Br);
- WriteU32Leb128(&stream_, GetLabelVarDepth(&cast<BrExpr>(expr)->var),
+ WriteOpcode(stream_, Opcode::Br);
+ WriteU32Leb128(stream_, GetLabelVarDepth(&cast<BrExpr>(expr)->var),
"break depth");
break;
case ExprType::BrIf:
- WriteOpcode(&stream_, Opcode::BrIf);
- WriteU32Leb128(&stream_, GetLabelVarDepth(&cast<BrIfExpr>(expr)->var),
+ WriteOpcode(stream_, Opcode::BrIf);
+ WriteU32Leb128(stream_, GetLabelVarDepth(&cast<BrIfExpr>(expr)->var),
"break depth");
break;
case ExprType::BrTable: {
auto br_table_expr = cast<BrTableExpr>(expr);
- WriteOpcode(&stream_, Opcode::BrTable);
- WriteU32Leb128(&stream_, br_table_expr->targets.size(), "num targets");
+ WriteOpcode(stream_, Opcode::BrTable);
+ WriteU32Leb128(stream_, br_table_expr->targets.size(), "num targets");
Index depth;
for (const Var& var : br_table_expr->targets) {
depth = GetLabelVarDepth(&var);
- WriteU32Leb128(&stream_, depth, "break depth");
+ WriteU32Leb128(stream_, depth, "break depth");
}
depth = GetLabelVarDepth(&br_table_expr->default_target);
- WriteU32Leb128(&stream_, depth, "break depth for default");
+ WriteU32Leb128(stream_, depth, "break depth for default");
break;
}
case ExprType::Call: {
Index index = module->GetFuncIndex(cast<CallExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::Call);
+ WriteOpcode(stream_, Opcode::Call);
WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB);
break;
}
case ExprType::CallIndirect: {
Index index = module->GetFuncTypeIndex(cast<CallIndirectExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::CallIndirect);
+ WriteOpcode(stream_, Opcode::CallIndirect);
WriteU32Leb128WithReloc(index, "signature index",
RelocType::TypeIndexLEB);
- WriteU32Leb128(&stream_, 0, "call_indirect reserved");
+ WriteU32Leb128(stream_, 0, "call_indirect reserved");
break;
}
case ExprType::Compare:
- WriteOpcode(&stream_, cast<CompareExpr>(expr)->opcode);
+ WriteOpcode(stream_, cast<CompareExpr>(expr)->opcode);
break;
case ExprType::Const: {
const Const& const_ = cast<ConstExpr>(expr)->const_;
switch (const_.type) {
case Type::I32: {
- WriteOpcode(&stream_, Opcode::I32Const);
- WriteS32Leb128(&stream_, const_.u32, "i32 literal");
+ WriteOpcode(stream_, Opcode::I32Const);
+ WriteS32Leb128(stream_, const_.u32, "i32 literal");
break;
}
case Type::I64:
- WriteOpcode(&stream_, Opcode::I64Const);
- WriteS64Leb128(&stream_, const_.u64, "i64 literal");
+ WriteOpcode(stream_, Opcode::I64Const);
+ WriteS64Leb128(stream_, const_.u64, "i64 literal");
break;
case Type::F32:
- WriteOpcode(&stream_, Opcode::F32Const);
- stream_.WriteU32(const_.f32_bits, "f32 literal");
+ WriteOpcode(stream_, Opcode::F32Const);
+ stream_->WriteU32(const_.f32_bits, "f32 literal");
break;
case Type::F64:
- WriteOpcode(&stream_, Opcode::F64Const);
- stream_.WriteU64(const_.f64_bits, "f64 literal");
+ WriteOpcode(stream_, Opcode::F64Const);
+ stream_->WriteU64(const_.f64_bits, "f64 literal");
break;
default:
assert(0);
@@ -403,125 +402,125 @@ void BinaryWriter::WriteExpr(const Module* module,
break;
}
case ExprType::Convert:
- WriteOpcode(&stream_, cast<ConvertExpr>(expr)->opcode);
+ WriteOpcode(stream_, cast<ConvertExpr>(expr)->opcode);
break;
case ExprType::CurrentMemory:
- WriteOpcode(&stream_, Opcode::CurrentMemory);
- WriteU32Leb128(&stream_, 0, "current_memory reserved");
+ WriteOpcode(stream_, Opcode::CurrentMemory);
+ WriteU32Leb128(stream_, 0, "current_memory reserved");
break;
case ExprType::Drop:
- WriteOpcode(&stream_, Opcode::Drop);
+ WriteOpcode(stream_, Opcode::Drop);
break;
case ExprType::GetGlobal: {
Index index = module->GetGlobalIndex(cast<GetGlobalExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::GetGlobal);
+ WriteOpcode(stream_, Opcode::GetGlobal);
WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB);
break;
}
case ExprType::GetLocal: {
Index index = GetLocalIndex(func, cast<GetLocalExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::GetLocal);
- WriteU32Leb128(&stream_, index, "local index");
+ WriteOpcode(stream_, Opcode::GetLocal);
+ WriteU32Leb128(stream_, index, "local index");
break;
}
case ExprType::GrowMemory:
- WriteOpcode(&stream_, Opcode::GrowMemory);
- WriteU32Leb128(&stream_, 0, "grow_memory reserved");
+ WriteOpcode(stream_, Opcode::GrowMemory);
+ WriteU32Leb128(stream_, 0, "grow_memory reserved");
break;
case ExprType::If: {
auto if_expr = cast<IfExpr>(expr);
- WriteOpcode(&stream_, Opcode::If);
- write_inline_signature_type(&stream_, if_expr->true_.sig);
+ WriteOpcode(stream_, Opcode::If);
+ write_inline_signature_type(stream_, if_expr->true_.sig);
WriteExprList(module, func, if_expr->true_.exprs);
if (!if_expr->false_.empty()) {
- WriteOpcode(&stream_, Opcode::Else);
+ WriteOpcode(stream_, Opcode::Else);
WriteExprList(module, func, if_expr->false_);
}
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
break;
}
case ExprType::Load: {
auto load_expr = cast<LoadExpr>(expr);
- WriteOpcode(&stream_, load_expr->opcode);
+ WriteOpcode(stream_, load_expr->opcode);
Address align = load_expr->opcode.GetAlignment(load_expr->align);
- stream_.WriteU8(log2_u32(align), "alignment");
- WriteU32Leb128(&stream_, load_expr->offset, "load offset");
+ stream_->WriteU8(log2_u32(align), "alignment");
+ WriteU32Leb128(stream_, load_expr->offset, "load offset");
break;
}
case ExprType::Loop:
- WriteOpcode(&stream_, Opcode::Loop);
- write_inline_signature_type(&stream_, cast<LoopExpr>(expr)->block.sig);
+ WriteOpcode(stream_, Opcode::Loop);
+ write_inline_signature_type(stream_, cast<LoopExpr>(expr)->block.sig);
WriteExprList(module, func, cast<LoopExpr>(expr)->block.exprs);
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
break;
case ExprType::Nop:
- WriteOpcode(&stream_, Opcode::Nop);
+ WriteOpcode(stream_, Opcode::Nop);
break;
case ExprType::Rethrow:
- WriteOpcode(&stream_, Opcode::Rethrow);
- WriteU32Leb128(&stream_, GetLabelVarDepth(&cast<RethrowExpr>(expr)->var),
+ WriteOpcode(stream_, Opcode::Rethrow);
+ WriteU32Leb128(stream_, GetLabelVarDepth(&cast<RethrowExpr>(expr)->var),
"rethrow depth");
break;
case ExprType::Return:
- WriteOpcode(&stream_, Opcode::Return);
+ WriteOpcode(stream_, Opcode::Return);
break;
case ExprType::Select:
- WriteOpcode(&stream_, Opcode::Select);
+ WriteOpcode(stream_, Opcode::Select);
break;
case ExprType::SetGlobal: {
Index index = module->GetGlobalIndex(cast<SetGlobalExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::SetGlobal);
+ WriteOpcode(stream_, Opcode::SetGlobal);
WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB);
break;
}
case ExprType::SetLocal: {
Index index = GetLocalIndex(func, cast<SetLocalExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::SetLocal);
- WriteU32Leb128(&stream_, index, "local index");
+ WriteOpcode(stream_, Opcode::SetLocal);
+ WriteU32Leb128(stream_, index, "local index");
break;
}
case ExprType::Store: {
auto store_expr = cast<StoreExpr>(expr);
- WriteOpcode(&stream_, store_expr->opcode);
+ WriteOpcode(stream_, store_expr->opcode);
Address align = store_expr->opcode.GetAlignment(store_expr->align);
- stream_.WriteU8(log2_u32(align), "alignment");
- WriteU32Leb128(&stream_, store_expr->offset, "store offset");
+ stream_->WriteU8(log2_u32(align), "alignment");
+ WriteU32Leb128(stream_, store_expr->offset, "store offset");
break;
}
case ExprType::TeeLocal: {
Index index = GetLocalIndex(func, cast<TeeLocalExpr>(expr)->var);
- WriteOpcode(&stream_, Opcode::TeeLocal);
- WriteU32Leb128(&stream_, index, "local index");
+ WriteOpcode(stream_, Opcode::TeeLocal);
+ WriteU32Leb128(stream_, index, "local index");
break;
}
case ExprType::Throw:
- WriteOpcode(&stream_, Opcode::Throw);
- WriteU32Leb128(&stream_, GetExceptVarDepth(&cast<ThrowExpr>(expr)->var),
+ WriteOpcode(stream_, Opcode::Throw);
+ WriteU32Leb128(stream_, GetExceptVarDepth(&cast<ThrowExpr>(expr)->var),
"throw exception");
break;
case ExprType::TryBlock: {
auto try_expr = cast<TryExpr>(expr);
- WriteOpcode(&stream_, Opcode::Try);
- write_inline_signature_type(&stream_, try_expr->block.sig);
+ WriteOpcode(stream_, Opcode::Try);
+ write_inline_signature_type(stream_, try_expr->block.sig);
WriteExprList(module, func, try_expr->block.exprs);
for (const Catch& catch_ : try_expr->catches) {
if (catch_.IsCatchAll()) {
- WriteOpcode(&stream_, Opcode::CatchAll);
+ WriteOpcode(stream_, Opcode::CatchAll);
} else {
- WriteOpcode(&stream_, Opcode::Catch);
- WriteU32Leb128(&stream_, GetExceptVarDepth(&catch_.var),
+ WriteOpcode(stream_, Opcode::Catch);
+ WriteU32Leb128(stream_, GetExceptVarDepth(&catch_.var),
"catch exception");
}
WriteExprList(module, func, catch_.exprs);
}
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
break;
}
case ExprType::Unary:
- WriteOpcode(&stream_, cast<UnaryExpr>(expr)->opcode);
+ WriteOpcode(stream_, cast<UnaryExpr>(expr)->opcode);
break;
case ExprType::Unreachable:
- WriteOpcode(&stream_, Opcode::Unreachable);
+ WriteOpcode(stream_, Opcode::Unreachable);
break;
}
}
@@ -535,14 +534,14 @@ void BinaryWriter::WriteExprList(const Module* module,
void BinaryWriter::WriteInitExpr(const Module* module, const ExprList& expr) {
WriteExprList(module, nullptr, expr);
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
}
void BinaryWriter::WriteFuncLocals(const Module* module,
const Func* func,
const TypeVector& local_types) {
if (local_types.size() == 0) {
- WriteU32Leb128(&stream_, 0, "local decl count");
+ WriteU32Leb128(stream_, 0, "local decl count");
return;
}
@@ -564,7 +563,7 @@ void BinaryWriter::WriteFuncLocals(const Module* module,
}
/* loop through again to write everything out */
- WriteU32Leb128(&stream_, local_decl_count, "local decl count");
+ WriteU32Leb128(stream_, local_decl_count, "local decl count");
current_type = GET_LOCAL_TYPE(FIRST_LOCAL_INDEX);
Index local_type_count = 1;
for (Index i = FIRST_LOCAL_INDEX + 1; i <= LAST_LOCAL_INDEX; ++i) {
@@ -573,8 +572,8 @@ void BinaryWriter::WriteFuncLocals(const Module* module,
if (current_type == type) {
local_type_count++;
} else {
- WriteU32Leb128(&stream_, local_type_count, "local type count");
- WriteType(&stream_, current_type);
+ WriteU32Leb128(stream_, local_type_count, "local type count");
+ WriteType(stream_, current_type);
local_type_count = 1;
current_type = type;
}
@@ -584,27 +583,27 @@ void BinaryWriter::WriteFuncLocals(const Module* module,
void BinaryWriter::WriteFunc(const Module* module, const Func* func) {
WriteFuncLocals(module, func, func->local_types);
WriteExprList(module, func, func->exprs);
- WriteOpcode(&stream_, Opcode::End);
+ WriteOpcode(stream_, Opcode::End);
}
void BinaryWriter::WriteTable(const Table* table) {
- WriteType(&stream_, Type::Anyfunc);
- WriteLimits(&stream_, &table->elem_limits);
+ WriteType(stream_, Type::Anyfunc);
+ WriteLimits(stream_, &table->elem_limits);
}
void BinaryWriter::WriteMemory(const Memory* memory) {
- WriteLimits(&stream_, &memory->page_limits);
+ WriteLimits(stream_, &memory->page_limits);
}
void BinaryWriter::WriteGlobalHeader(const Global* global) {
- WriteType(&stream_, global->type);
- stream_.WriteU8(global->mutable_, "global mutability");
+ WriteType(stream_, global->type);
+ stream_->WriteU8(global->mutable_, "global mutability");
}
void BinaryWriter::WriteExceptType(const TypeVector* except_types) {
- WriteU32Leb128(&stream_, except_types->size(), "exception type count");
+ WriteU32Leb128(stream_, except_types->size(), "exception type count");
for (Type ty : *except_types)
- WriteType(&stream_, ty);
+ WriteType(stream_, ty);
}
void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) {
@@ -612,19 +611,19 @@ void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) {
wabt_snprintf(section_name, sizeof(section_name), "%s.%s",
WABT_BINARY_SECTION_RELOC, reloc_section->name);
BeginCustomSection(section_name, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, reloc_section->section_code, "reloc section type");
+ WriteU32Leb128(stream_, reloc_section->section_code, "reloc section type");
const std::vector<Reloc>& relocs = reloc_section->relocations;
- WriteU32Leb128(&stream_, relocs.size(), "num relocs");
+ WriteU32Leb128(stream_, relocs.size(), "num relocs");
for (const Reloc& reloc : relocs) {
- WriteU32Leb128(&stream_, reloc.type, "reloc type");
- WriteU32Leb128(&stream_, reloc.offset, "reloc offset");
- WriteU32Leb128(&stream_, reloc.index, "reloc index");
+ WriteU32Leb128(stream_, reloc.type, "reloc type");
+ WriteU32Leb128(stream_, reloc.offset, "reloc offset");
+ WriteU32Leb128(stream_, reloc.index, "reloc index");
switch (reloc.type) {
case RelocType::MemoryAddressLEB:
case RelocType::MemoryAddressSLEB:
case RelocType::MemoryAddressI32:
- WriteU32Leb128(&stream_, reloc.addend, "reloc addend");
+ WriteU32Leb128(stream_, reloc.addend, "reloc addend");
break;
default:
break;
@@ -635,46 +634,46 @@ void BinaryWriter::WriteRelocSection(const RelocSection* reloc_section) {
}
Result BinaryWriter::WriteModule(const Module* module) {
- stream_.WriteU32(WABT_BINARY_MAGIC, "WASM_BINARY_MAGIC");
- stream_.WriteU32(WABT_BINARY_VERSION, "WASM_BINARY_VERSION");
+ stream_->WriteU32(WABT_BINARY_MAGIC, "WASM_BINARY_MAGIC");
+ stream_->WriteU32(WABT_BINARY_VERSION, "WASM_BINARY_VERSION");
if (module->func_types.size()) {
BeginKnownSection(BinarySection::Type, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->func_types.size(), "num types");
+ WriteU32Leb128(stream_, module->func_types.size(), "num types");
for (size_t i = 0; i < module->func_types.size(); ++i) {
const FuncType* func_type = module->func_types[i];
const FuncSignature* sig = &func_type->sig;
WriteHeader("type", i);
- WriteType(&stream_, Type::Func);
+ WriteType(stream_, Type::Func);
Index num_params = sig->param_types.size();
Index num_results = sig->result_types.size();
- WriteU32Leb128(&stream_, num_params, "num params");
+ WriteU32Leb128(stream_, num_params, "num params");
for (size_t j = 0; j < num_params; ++j)
- WriteType(&stream_, sig->param_types[j]);
+ WriteType(stream_, sig->param_types[j]);
- WriteU32Leb128(&stream_, num_results, "num results");
+ WriteU32Leb128(stream_, num_results, "num results");
for (size_t j = 0; j < num_results; ++j)
- WriteType(&stream_, sig->result_types[j]);
+ WriteType(stream_, sig->result_types[j]);
}
EndSection();
}
if (module->imports.size()) {
BeginKnownSection(BinarySection::Import, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->imports.size(), "num imports");
+ WriteU32Leb128(stream_, module->imports.size(), "num imports");
for (size_t i = 0; i < module->imports.size(); ++i) {
const Import* import = module->imports[i];
WriteHeader("import header", i);
- WriteStr(&stream_, import->module_name, "import module name",
+ WriteStr(stream_, import->module_name, "import module name",
PrintChars::Yes);
- WriteStr(&stream_, import->field_name, "import field name",
+ WriteStr(stream_, import->field_name, "import field name",
PrintChars::Yes);
- stream_.WriteU8Enum(import->kind(), "import kind");
+ stream_->WriteU8Enum(import->kind(), "import kind");
switch (import->kind()) {
case ExternalKind::Func:
- WriteU32Leb128(&stream_, module->GetFuncTypeIndex(
+ WriteU32Leb128(stream_, module->GetFuncTypeIndex(
cast<FuncImport>(import)->func.decl),
"import signature index");
break;
@@ -703,14 +702,14 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index num_funcs = module->funcs.size() - module->num_func_imports;
if (num_funcs) {
BeginKnownSection(BinarySection::Function, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_funcs, "num functions");
+ WriteU32Leb128(stream_, num_funcs, "num functions");
for (size_t i = 0; i < num_funcs; ++i) {
const Func* func = module->funcs[i + module->num_func_imports];
char desc[100];
wabt_snprintf(desc, sizeof(desc), "function %" PRIzd " signature index",
i);
- WriteU32Leb128(&stream_, module->GetFuncTypeIndex(func->decl), desc);
+ WriteU32Leb128(stream_, module->GetFuncTypeIndex(func->decl), desc);
}
EndSection();
}
@@ -719,7 +718,7 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index num_tables = module->tables.size() - module->num_table_imports;
if (num_tables) {
BeginKnownSection(BinarySection::Table, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_tables, "num tables");
+ WriteU32Leb128(stream_, num_tables, "num tables");
for (size_t i = 0; i < num_tables; ++i) {
const Table* table = module->tables[i + module->num_table_imports];
WriteHeader("table", i);
@@ -732,7 +731,7 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index num_memories = module->memories.size() - module->num_memory_imports;
if (num_memories) {
BeginKnownSection(BinarySection::Memory, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_memories, "num memories");
+ WriteU32Leb128(stream_, num_memories, "num memories");
for (size_t i = 0; i < num_memories; ++i) {
const Memory* memory = module->memories[i + module->num_memory_imports];
WriteHeader("memory", i);
@@ -745,7 +744,7 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index num_globals = module->globals.size() - module->num_global_imports;
if (num_globals) {
BeginKnownSection(BinarySection::Global, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_globals, "num globals");
+ WriteU32Leb128(stream_, num_globals, "num globals");
for (size_t i = 0; i < num_globals; ++i) {
const Global* global = module->globals[i + module->num_global_imports];
@@ -757,35 +756,35 @@ Result BinaryWriter::WriteModule(const Module* module) {
if (module->exports.size()) {
BeginKnownSection(BinarySection::Export, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->exports.size(), "num exports");
+ WriteU32Leb128(stream_, module->exports.size(), "num exports");
for (const Export* export_ : module->exports) {
- WriteStr(&stream_, export_->name, "export name", PrintChars::Yes);
- stream_.WriteU8Enum(export_->kind, "export kind");
+ WriteStr(stream_, export_->name, "export name", PrintChars::Yes);
+ stream_->WriteU8Enum(export_->kind, "export kind");
switch (export_->kind) {
case ExternalKind::Func: {
Index index = module->GetFuncIndex(export_->var);
- WriteU32Leb128(&stream_, index, "export func index");
+ WriteU32Leb128(stream_, index, "export func index");
break;
}
case ExternalKind::Table: {
Index index = module->GetTableIndex(export_->var);
- WriteU32Leb128(&stream_, index, "export table index");
+ WriteU32Leb128(stream_, index, "export table index");
break;
}
case ExternalKind::Memory: {
Index index = module->GetMemoryIndex(export_->var);
- WriteU32Leb128(&stream_, index, "export memory index");
+ WriteU32Leb128(stream_, index, "export memory index");
break;
}
case ExternalKind::Global: {
Index index = module->GetGlobalIndex(export_->var);
- WriteU32Leb128(&stream_, index, "export global index");
+ WriteU32Leb128(stream_, index, "export global index");
break;
}
case ExternalKind::Except: {
Index index = module->GetExceptIndex(export_->var);
- WriteU32Leb128(&stream_, index, "export exception index");
+ WriteU32Leb128(stream_, index, "export exception index");
break;
}
}
@@ -797,21 +796,21 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index start_func_index = module->GetFuncIndex(*module->start);
if (start_func_index != kInvalidIndex) {
BeginKnownSection(BinarySection::Start, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, start_func_index, "start func index");
+ WriteU32Leb128(stream_, start_func_index, "start func index");
EndSection();
}
}
if (module->elem_segments.size()) {
BeginKnownSection(BinarySection::Elem, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->elem_segments.size(), "num elem segments");
+ WriteU32Leb128(stream_, module->elem_segments.size(), "num elem segments");
for (size_t i = 0; i < module->elem_segments.size(); ++i) {
ElemSegment* segment = module->elem_segments[i];
Index table_index = module->GetTableIndex(segment->table_var);
WriteHeader("elem segment header", i);
- WriteU32Leb128(&stream_, table_index, "table index");
+ WriteU32Leb128(stream_, table_index, "table index");
WriteInitExpr(module, segment->offset);
- WriteU32Leb128(&stream_, segment->vars.size(), "num function indices");
+ WriteU32Leb128(stream_, segment->vars.size(), "num function indices");
for (const Var& var : segment->vars) {
Index index = module->GetFuncIndex(var);
WriteU32Leb128WithReloc(index, "function index",
@@ -825,7 +824,7 @@ Result BinaryWriter::WriteModule(const Module* module) {
Index num_exceptions = module->excepts.size() - module->num_except_imports;
if (num_exceptions) {
BeginCustomSection("exception", LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_exceptions, "exception count");
+ WriteU32Leb128(stream_, num_exceptions, "exception count");
for (Index i = module->num_except_imports; i < num_exceptions; ++i) {
WriteExceptType(&module->excepts[i]->sig);
}
@@ -834,7 +833,7 @@ Result BinaryWriter::WriteModule(const Module* module) {
if (num_funcs) {
BeginKnownSection(BinarySection::Code, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, num_funcs, "num functions");
+ WriteU32Leb128(stream_, num_funcs, "num functions");
for (size_t i = 0; i < num_funcs; ++i) {
WriteHeader("function body", i);
@@ -853,16 +852,16 @@ Result BinaryWriter::WriteModule(const Module* module) {
if (module->data_segments.size()) {
BeginKnownSection(BinarySection::Data, LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->data_segments.size(), "num data segments");
+ WriteU32Leb128(stream_, module->data_segments.size(), "num data segments");
for (size_t i = 0; i < module->data_segments.size(); ++i) {
const DataSegment* segment = module->data_segments[i];
WriteHeader("data segment header", i);
Index memory_index = module->GetMemoryIndex(segment->memory_var);
- WriteU32Leb128(&stream_, memory_index, "memory index");
+ WriteU32Leb128(stream_, memory_index, "memory index");
WriteInitExpr(module, segment->offset);
- WriteU32Leb128(&stream_, segment->data.size(), "data segment size");
+ WriteU32Leb128(stream_, segment->data.size(), "data segment size");
WriteHeader("data segment data", i);
- stream_.WriteData(segment->data, "data segment data");
+ stream_->WriteData(segment->data, "data segment data");
}
EndSection();
}
@@ -880,41 +879,41 @@ Result BinaryWriter::WriteModule(const Module* module) {
}
if (named_functions > 0) {
- WriteU32Leb128(&stream_, 1, "function name type");
+ WriteU32Leb128(stream_, 1, "function name type");
BeginSubsection("function name subsection", LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, named_functions, "num functions");
+ WriteU32Leb128(stream_, named_functions, "num functions");
for (size_t i = 0; i < module->funcs.size(); ++i) {
const Func* func = module->funcs[i];
if (func->name.empty())
continue;
- WriteU32Leb128(&stream_, i, "function index");
+ WriteU32Leb128(stream_, i, "function index");
wabt_snprintf(desc, sizeof(desc), "func name %" PRIzd, i);
- WriteDebugName(&stream_, func->name, desc);
+ WriteDebugName(stream_, func->name, desc);
}
EndSubsection();
}
- WriteU32Leb128(&stream_, 2, "local name type");
+ WriteU32Leb128(stream_, 2, "local name type");
BeginSubsection("local name subsection", LEB_SECTION_SIZE_GUESS);
- WriteU32Leb128(&stream_, module->funcs.size(), "num functions");
+ 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");
+ WriteU32Leb128(stream_, i, "function index");
+ WriteU32Leb128(stream_, num_params_and_locals, "num locals");
MakeTypeBindingReverseMapping(func->decl.sig.param_types,
func->param_bindings, &index_to_name);
for (size_t j = 0; j < num_params; ++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);
+ WriteU32Leb128(stream_, j, "local index");
+ WriteDebugName(stream_, name, desc);
}
MakeTypeBindingReverseMapping(func->local_types, func->local_bindings,
@@ -922,8 +921,8 @@ Result BinaryWriter::WriteModule(const Module* module) {
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);
+ WriteU32Leb128(stream_, num_params + j, "local index");
+ WriteDebugName(stream_, name, desc);
}
}
EndSubsection();
@@ -936,15 +935,15 @@ Result BinaryWriter::WriteModule(const Module* module) {
}
}
- return stream_.result();
+ return stream_->result();
}
} // end anonymous namespace
-Result WriteBinaryModule(Writer* writer,
+Result WriteBinaryModule(Stream* stream,
const Module* module,
const WriteBinaryOptions* options) {
- BinaryWriter binary_writer(writer, options);
+ BinaryWriter binary_writer(stream, options);
return binary_writer.WriteModule(module);
}
diff --git a/src/binary-writer.h b/src/binary-writer.h
index 1dff83fa..aae02d3c 100644
--- a/src/binary-writer.h
+++ b/src/binary-writer.h
@@ -23,18 +23,16 @@
namespace wabt {
-class Writer;
struct Module;
struct Script;
struct WriteBinaryOptions {
- Stream* log_stream = nullptr;
bool canonicalize_lebs = true;
bool relocatable = false;
bool write_debug_names = false;
};
-Result WriteBinaryModule(Writer*, const Module*, const WriteBinaryOptions*);
+Result WriteBinaryModule(Stream*, const Module*, const WriteBinaryOptions*);
void WriteType(Stream* stream, Type type);
diff --git a/src/emscripten-helpers.cc b/src/emscripten-helpers.cc
index 4d80b230..48513fdd 100644
--- a/src/emscripten-helpers.cc
+++ b/src/emscripten-helpers.cc
@@ -35,7 +35,6 @@
#include "src/wast-lexer.h"
#include "src/wast-parser.h"
#include "src/wat-writer.h"
-#include "src/writer.h"
struct WabtParseWastResult {
wabt::Result result;
@@ -78,7 +77,6 @@ WabtReadBinaryResult* wabt_read_binary(
int read_debug_names,
wabt::ErrorHandlerBuffer* error_handler) {
wabt::ReadBinaryOptions options;
- options.log_stream = nullptr;
options.read_debug_names = read_debug_names;
WabtReadBinaryResult* result = new WabtReadBinaryResult();
@@ -128,18 +126,17 @@ WabtWriteModuleResult* wabt_write_binary_module(wabt::Module* module,
int canonicalize_lebs,
int relocatable,
int write_debug_names) {
- wabt::MemoryStream stream;
+ wabt::MemoryStream log_stream;
wabt::WriteBinaryOptions options;
- options.log_stream = log ? &stream : nullptr;
options.canonicalize_lebs = canonicalize_lebs;
options.relocatable = relocatable;
options.write_debug_names = write_debug_names;
- wabt::MemoryWriter writer;
+ wabt::MemoryStream stream(log ? &log_stream : nullptr);
WabtWriteModuleResult* result = new WabtWriteModuleResult();
- result->result = WriteBinaryModule(&writer, module, &options);
+ result->result = WriteBinaryModule(&stream, module, &options);
if (result->result == wabt::Result::Ok) {
- result->buffer = writer.ReleaseOutputBuffer();
+ result->buffer = stream.ReleaseOutputBuffer();
result->log_buffer = log ? stream.ReleaseOutputBuffer() : nullptr;
}
return result;
@@ -148,16 +145,15 @@ WabtWriteModuleResult* wabt_write_binary_module(wabt::Module* module,
WabtWriteModuleResult* wabt_write_text_module(wabt::Module* module,
int fold_exprs,
int inline_export) {
- wabt::MemoryStream stream;
wabt::WriteWatOptions options;
options.fold_exprs = fold_exprs;
options.inline_export = inline_export;
- wabt::MemoryWriter writer;
+ wabt::MemoryStream stream;
WabtWriteModuleResult* result = new WabtWriteModuleResult();
- result->result = WriteWat(&writer, module, &options);
+ result->result = WriteWat(&stream, module, &options);
if (result->result == wabt::Result::Ok) {
- result->buffer = writer.ReleaseOutputBuffer();
+ result->buffer = stream.ReleaseOutputBuffer();
}
return result;
}
diff --git a/src/interpreter.h b/src/interpreter.h
index 6db47fc4..8466bb2d 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -26,12 +26,10 @@
#include "src/binding-hash.h"
#include "src/common.h"
#include "src/opcode.h"
-#include "src/writer.h"
+#include "src/stream.h"
namespace wabt {
-class Stream;
-
namespace interpreter {
#define FOREACH_INTERPRETER_RESULT(V) \
diff --git a/src/stream.cc b/src/stream.cc
index e976e82a..90d4e913 100644
--- a/src/stream.cc
+++ b/src/stream.cc
@@ -18,17 +18,19 @@
#include <cassert>
#include <cctype>
+#include <cerrno>
#define DUMP_OCTETS_PER_LINE 16
#define DUMP_OCTETS_PER_GROUP 2
+#define ERROR0(msg) fprintf(stderr, "%s:%d: " msg, __FILE__, __LINE__)
+#define ERROR(fmt, ...) \
+ fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__)
+
namespace wabt {
-Stream::Stream(Writer* writer, Stream* log_stream)
- : writer_(writer),
- offset_(0),
- result_(Result::Ok),
- log_stream_(log_stream) {}
+Stream::Stream(Stream* log_stream)
+ : offset_(0), result_(Result::Ok), log_stream_(log_stream) {}
void Stream::AddOffset(ssize_t delta) {
offset_ += delta;
@@ -44,7 +46,7 @@ void Stream::WriteDataAt(size_t at,
if (log_stream_) {
log_stream_->WriteMemoryDump(src, size, at, print_chars, nullptr, desc);
}
- result_ = writer_->WriteData(at, src, size);
+ result_ = WriteDataImpl(at, src, size);
}
void Stream::WriteData(const void* src,
@@ -63,7 +65,7 @@ void Stream::MoveData(size_t dst_offset, size_t src_offset, size_t size) {
"; move data: [%" PRIzx ", %" PRIzx ") -> [%" PRIzx ", %" PRIzx ")\n",
src_offset, src_offset + size, dst_offset, dst_offset + size);
}
- result_ = writer_->MoveData(dst_offset, src_offset, size);
+ result_ = MoveDataImpl(dst_offset, src_offset, size);
}
void Stream::Writef(const char* format, ...) {
@@ -112,21 +114,143 @@ void Stream::WriteMemoryDump(const void* start,
}
}
-MemoryStream::MemoryStream() : Stream(&writer_) {}
+Result OutputBuffer::WriteToFile(string_view filename) const {
+ std::string filename_str = filename.to_string();
+ FILE* file = fopen(filename_str.c_str(), "wb");
+ if (!file) {
+ ERROR("unable to open %s for writing\n", filename_str.c_str());
+ return Result::Error;
+ }
+
+ if (data.empty()) {
+ fclose(file);
+ return Result::Ok;
+ }
+
+ ssize_t bytes = fwrite(data.data(), 1, data.size(), file);
+ if (bytes < 0 || static_cast<size_t>(bytes) != data.size()) {
+ ERROR("failed to write %" PRIzd " bytes to %s\n", data.size(),
+ filename_str.c_str());
+ fclose(file);
+ return Result::Error;
+ }
+
+ fclose(file);
+ return Result::Ok;
+}
+
+MemoryStream::MemoryStream(Stream* log_stream)
+ : Stream(log_stream), buf_(new OutputBuffer()) {}
+
+MemoryStream::MemoryStream(std::unique_ptr<OutputBuffer>&& buf,
+ Stream* log_stream)
+ : Stream(log_stream), buf_(std::move(buf)) {}
+
+std::unique_ptr<OutputBuffer> MemoryStream::ReleaseOutputBuffer() {
+ return std::move(buf_);
+}
+
+Result MemoryStream::WriteDataImpl(size_t dst_offset,
+ const void* src,
+ size_t size) {
+ if (size == 0)
+ return Result::Ok;
+ size_t end = dst_offset + size;
+ if (end > buf_->data.size()) {
+ buf_->data.resize(end);
+ }
+ uint8_t* dst = &buf_->data[dst_offset];
+ memcpy(dst, src, size);
+ return Result::Ok;
+}
+
+Result MemoryStream::MoveDataImpl(size_t dst_offset,
+ size_t src_offset,
+ size_t size) {
+ if (size == 0)
+ return Result::Ok;
+ size_t src_end = src_offset + size;
+ size_t dst_end = dst_offset + size;
+ size_t end = src_end > dst_end ? src_end : dst_end;
+ if (end > buf_->data.size()) {
+ buf_->data.resize(end);
+ }
+
+ uint8_t* dst = &buf_->data[dst_offset];
+ uint8_t* src = &buf_->data[src_offset];
+ memmove(dst, src, size);
+ return Result::Ok;
+}
+
+FileStream::FileStream(string_view filename, Stream* log_stream)
+ : Stream(log_stream), file_(nullptr), offset_(0), should_close_(false) {
+ std::string filename_str = filename.to_string();
+ file_ = fopen(filename_str.c_str(), "wb");
-FileStream::FileStream(string_view filename)
- : Stream(&writer_), writer_(filename) {}
+ // TODO(binji): this is pretty cheesy, should come up with a better API.
+ if (file_) {
+ should_close_ = true;
+ } else {
+ ERROR("fopen name=\"%s\" failed, errno=%d\n", filename_str.c_str(), errno);
+ }
+}
-FileStream::FileStream(FILE* file) : Stream(&writer_), writer_(file) {}
+FileStream::FileStream(FILE* file, Stream* log_stream)
+ : Stream(log_stream), file_(file), offset_(0), should_close_(false) {}
-FileStream::FileStream(FileStream&& other)
- : Stream(&writer_), writer_(std::move(other.writer_)) {}
+FileStream::FileStream(FileStream&& other) {
+ *this = std::move(other);
+}
FileStream& FileStream::operator=(FileStream&& other) {
- writer_ = std::move(other.writer_);
+ file_ = other.file_;
+ offset_ = other.offset_;
+ should_close_ = other.should_close_;
+ other.file_ = nullptr;
+ other.offset_ = 0;
+ other.should_close_ = false;
return *this;
}
+FileStream::~FileStream() {
+ // We don't want to close existing files (stdout/sterr, for example).
+ if (should_close_) {
+ fclose(file_);
+ }
+}
+
+Result FileStream::WriteDataImpl(size_t at, const void* data, size_t size) {
+ if (!file_)
+ return Result::Error;
+ if (size == 0)
+ return Result::Ok;
+ if (at != offset_) {
+ if (fseek(file_, at, SEEK_SET) != 0) {
+ ERROR("fseek offset=%" PRIzd " failed, errno=%d\n", size, errno);
+ return Result::Error;
+ }
+ offset_ = at;
+ }
+ if (fwrite(data, size, 1, file_) != 1) {
+ ERROR("fwrite size=%" PRIzd " failed, errno=%d\n", size, errno);
+ return Result::Error;
+ }
+ offset_ += size;
+ return Result::Ok;
+}
+
+Result FileStream::MoveDataImpl(size_t dst_offset,
+ size_t src_offset,
+ size_t size) {
+ if (!file_)
+ return Result::Error;
+ if (size == 0)
+ return Result::Ok;
+ // TODO(binji): implement if needed.
+ ERROR0("FileWriter::MoveData not implemented!\n");
+ return Result::Error;
+}
+
// static
std::unique_ptr<FileStream> FileStream::CreateStdout() {
return std::unique_ptr<FileStream>(new FileStream(stdout));
diff --git a/src/stream.h b/src/stream.h
index 666d830b..5fa3443d 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -22,7 +22,6 @@
#include <vector>
#include "src/common.h"
-#include "src/writer.h"
namespace wabt {
@@ -35,7 +34,7 @@ enum class PrintChars {
class Stream {
public:
- Stream(Writer* writer, Stream* log_stream = nullptr);
+ Stream(Stream* log_stream = nullptr);
size_t offset() { return offset_; }
Result result() { return result_; }
@@ -117,55 +116,82 @@ class Stream {
WriteU8(static_cast<uint32_t>(value), desc, print_chars);
}
+ protected:
+ virtual Result WriteDataImpl(size_t offset,
+ const void* data,
+ size_t size) = 0;
+ virtual Result MoveDataImpl(size_t dst_offset,
+ size_t src_offset,
+ size_t size) = 0;
+
private:
template <typename T>
void Write(const T& data, const char* desc, PrintChars print_chars) {
WriteData(&data, sizeof(data), desc, print_chars);
}
- Writer* writer_; // Not owned.
size_t offset_;
Result result_;
// Not owned. If non-null, log all writes to this stream.
Stream* log_stream_;
};
+struct OutputBuffer {
+ Result WriteToFile(string_view filename) const;
+
+ size_t size() const { return data.size(); }
+
+ std::vector<uint8_t> data;
+};
+
class MemoryStream : public Stream {
public:
WABT_DISALLOW_COPY_AND_ASSIGN(MemoryStream);
- MemoryStream();
+ explicit MemoryStream(Stream* log_stream = nullptr);
+ explicit MemoryStream(std::unique_ptr<OutputBuffer>&&,
+ Stream* log_stream = nullptr);
- MemoryWriter& writer() { return writer_; }
-
- std::unique_ptr<OutputBuffer> ReleaseOutputBuffer() {
- return writer_.ReleaseOutputBuffer();
- }
+ OutputBuffer& output_buffer() { return *buf_; }
+ std::unique_ptr<OutputBuffer> ReleaseOutputBuffer();
Result WriteToFile(string_view filename) {
- return writer_.output_buffer().WriteToFile(filename);
+ return buf_->WriteToFile(filename);
}
+ protected:
+ Result WriteDataImpl(size_t offset, const void* data, size_t size) override;
+ Result MoveDataImpl(size_t dst_offset,
+ size_t src_offset,
+ size_t size) override;
+
private:
- MemoryWriter writer_;
+ std::unique_ptr<OutputBuffer> buf_;
};
class FileStream : public Stream {
public:
WABT_DISALLOW_COPY_AND_ASSIGN(FileStream);
- explicit FileStream(string_view filename);
- explicit FileStream(FILE*);
+ explicit FileStream(string_view filename, Stream* log_stream = nullptr);
+ explicit FileStream(FILE*, Stream* log_stream = nullptr);
FileStream(FileStream&&);
FileStream& operator=(FileStream&&);
-
- FileWriter& writer() { return writer_; }
+ ~FileStream();
static std::unique_ptr<FileStream> CreateStdout();
static std::unique_ptr<FileStream> CreateStderr();
- bool is_open() const { return writer_.is_open(); }
+ bool is_open() const { return file_ != nullptr; }
+
+ protected:
+ Result WriteDataImpl(size_t offset, const void* data, size_t size) override;
+ Result MoveDataImpl(size_t dst_offset,
+ size_t src_offset,
+ size_t size) override;
private:
- FileWriter writer_;
+ FILE* file_;
+ size_t offset_;
+ bool should_close_;
};
} // namespace wabt
diff --git a/src/tools/wasm-link.cc b/src/tools/wasm-link.cc
index 5d6350c4..d3c7c20f 100644
--- a/src/tools/wasm-link.cc
+++ b/src/tools/wasm-link.cc
@@ -25,7 +25,6 @@
#include "src/leb128.h"
#include "src/option-parser.h"
#include "src/stream.h"
-#include "src/writer.h"
#include "src/binary-reader-linker.h"
#define FIRST_KNOWN_SECTION static_cast<size_t>(BinarySection::Type)
diff --git a/src/tools/wasm-objdump.cc b/src/tools/wasm-objdump.cc
index 578f5c31..64ecef6d 100644
--- a/src/tools/wasm-objdump.cc
+++ b/src/tools/wasm-objdump.cc
@@ -22,7 +22,6 @@
#include "src/feature.h"
#include "src/option-parser.h"
#include "src/stream.h"
-#include "src/writer.h"
#include "src/binary-reader.h"
#include "src/binary-reader-objdump.h"
diff --git a/src/tools/wasm2wast.cc b/src/tools/wasm2wast.cc
index 213324ff..8b2957fa 100644
--- a/src/tools/wasm2wast.cc
+++ b/src/tools/wasm2wast.cc
@@ -31,7 +31,6 @@
#include "src/validator.h"
#include "src/wast-lexer.h"
#include "src/wat-writer.h"
-#include "src/writer.h"
using namespace wabt;
@@ -125,9 +124,9 @@ int ProgramMain(int argc, char** argv) {
}
if (Succeeded(result)) {
- FileWriter writer(!s_outfile.empty() ? FileWriter(s_outfile.c_str())
- : FileWriter(stdout));
- result = WriteWat(&writer, &module, &s_write_wat_options);
+ FileStream stream(!s_outfile.empty() ? FileStream(s_outfile.c_str())
+ : FileStream(stdout));
+ result = WriteWat(&stream, &module, &s_write_wat_options);
}
}
}
diff --git a/src/tools/wast-desugar.cc b/src/tools/wast-desugar.cc
index ad989fcc..03bdc4b8 100644
--- a/src/tools/wast-desugar.cc
+++ b/src/tools/wast-desugar.cc
@@ -32,7 +32,6 @@
#include "src/stream.h"
#include "src/wast-parser.h"
#include "src/wat-writer.h"
-#include "src/writer.h"
using namespace wabt;
@@ -104,8 +103,8 @@ int ProgramMain(int argc, char** argv) {
result = ApplyNames(module);
if (Succeeded(result)) {
- FileWriter writer(s_outfile ? FileWriter(s_outfile) : FileWriter(stdout));
- result = WriteWat(&writer, module, &s_write_wat_options);
+ FileStream stream(s_outfile ? FileStream(s_outfile) : FileStream(stdout));
+ result = WriteWat(&stream, module, &s_write_wat_options);
}
}
diff --git a/src/tools/wast2wasm.cc b/src/tools/wast2wasm.cc
index 3f6d0a1f..bed3437f 100644
--- a/src/tools/wast2wasm.cc
+++ b/src/tools/wast2wasm.cc
@@ -34,7 +34,6 @@
#include "src/stream.h"
#include "src/validator.h"
#include "src/wast-parser.h"
-#include "src/writer.h"
using namespace wabt;
@@ -76,7 +75,6 @@ static void ParseOptions(int argc, char* argv[]) {
parser.AddOption('v', "verbose", "Use multiple times for more info", []() {
s_verbose++;
s_log_stream = FileStream::CreateStdout();
- s_write_binary_options.log_stream = s_log_stream.get();
});
parser.AddHelpOption();
parser.AddOption("debug-parser", "Turn on debugging the parser of wast files",
@@ -149,21 +147,22 @@ int ProgramMain(int argc, char** argv) {
if (Succeeded(result)) {
if (s_spec) {
WriteBinarySpecOptions write_binary_spec_options;
+ write_binary_spec_options.log_stream = s_log_stream.get();
write_binary_spec_options.json_filename = s_outfile;
write_binary_spec_options.write_binary_options = s_write_binary_options;
result = WriteBinarySpecScript(script.get(), s_infile,
&write_binary_spec_options);
} else {
- MemoryWriter writer;
+ MemoryStream stream(s_log_stream.get());
const Module* module = script->GetFirstModule();
if (module) {
- result = WriteBinaryModule(&writer, module, &s_write_binary_options);
+ result = WriteBinaryModule(&stream, module, &s_write_binary_options);
} else {
WABT_FATAL("no module found\n");
}
if (Succeeded(result))
- WriteBufferToFile(s_outfile, writer.output_buffer());
+ WriteBufferToFile(s_outfile, stream.output_buffer());
}
}
}
diff --git a/src/wat-writer.cc b/src/wat-writer.cc
index c674645a..47c60d3c 100644
--- a/src/wat-writer.cc
+++ b/src/wat-writer.cc
@@ -31,7 +31,6 @@
#include "src/ir.h"
#include "src/literal.h"
#include "src/stream.h"
-#include "src/writer.h"
#define WABT_TRACING 0
#include "src/tracing.h"
@@ -91,8 +90,8 @@ struct Label {
class WatWriter {
public:
- WatWriter(Writer* writer, const WriteWatOptions* options)
- : options_(options), stream_(writer) {}
+ WatWriter(Stream* stream, const WriteWatOptions* options)
+ : options_(options), stream_(stream) {}
Result WriteModule(const Module& module);
@@ -175,7 +174,7 @@ class WatWriter {
const WriteWatOptions* options_ = nullptr;
const Module* module_ = nullptr;
const Func* current_func_ = nullptr;
- Stream stream_;
+ Stream* stream_;
Result result_ = Result::Ok;
int indent_ = 0;
NextChar next_char_ = NextChar::None;
@@ -208,22 +207,22 @@ void WatWriter::WriteIndent() {
static size_t s_indent_len = sizeof(s_indent) - 1;
size_t to_write = indent_;
while (to_write >= s_indent_len) {
- stream_.WriteData(s_indent, s_indent_len);
+ stream_->WriteData(s_indent, s_indent_len);
to_write -= s_indent_len;
}
if (to_write > 0) {
- stream_.WriteData(s_indent, to_write);
+ stream_->WriteData(s_indent, to_write);
}
}
void WatWriter::WriteNextChar() {
switch (next_char_) {
case NextChar::Space:
- stream_.WriteChar(' ');
+ stream_->WriteChar(' ');
break;
case NextChar::Newline:
case NextChar::ForceNewline:
- stream_.WriteChar('\n');
+ stream_->WriteChar('\n');
WriteIndent();
break;
case NextChar::None:
@@ -234,7 +233,7 @@ void WatWriter::WriteNextChar() {
void WatWriter::WriteDataWithNextChar(const void* src, size_t size) {
WriteNextChar();
- stream_.WriteData(src, size);
+ stream_->WriteData(src, size);
}
void WABT_PRINTF_FORMAT(2, 3) WatWriter::Writef(const char* format, ...) {
@@ -245,7 +244,7 @@ void WABT_PRINTF_FORMAT(2, 3) WatWriter::Writef(const char* format, ...) {
}
void WatWriter::WritePutc(char c) {
- stream_.WriteChar(c);
+ stream_->WriteChar(c);
}
void WatWriter::WritePuts(const char* s, NextChar next_char) {
@@ -1231,10 +1230,10 @@ void WatWriter::WriteInlineExport(const Export* export_) {
} // end anonymous namespace
-Result WriteWat(Writer* writer,
+Result WriteWat(Stream* stream,
const Module* module,
const WriteWatOptions* options) {
- WatWriter wat_writer(writer, options);
+ WatWriter wat_writer(stream, options);
return wat_writer.WriteModule(*module);
}
diff --git a/src/wat-writer.h b/src/wat-writer.h
index a8ec8a5c..c99fc3f4 100644
--- a/src/wat-writer.h
+++ b/src/wat-writer.h
@@ -22,14 +22,14 @@
namespace wabt {
struct Module;
-class Writer;
+class Stream;
struct WriteWatOptions {
bool fold_exprs = false; // Write folded expressions.
bool inline_export = false;
};
-Result WriteWat(Writer*, const Module*, const WriteWatOptions*);
+Result WriteWat(Stream*, const Module*, const WriteWatOptions*);
} // namespace wabt
diff --git a/src/writer.cc b/src/writer.cc
deleted file mode 100644
index 319ddb7f..00000000
--- a/src/writer.cc
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2016 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.
- */
-
-#include "src/writer.h"
-
-#include <cassert>
-#include <cerrno>
-#include <cstdio>
-#include <cstdlib>
-#include <utility>
-
-#define ERROR0(msg) fprintf(stderr, "%s:%d: " msg, __FILE__, __LINE__)
-#define ERROR(fmt, ...) \
- fprintf(stderr, "%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__)
-
-namespace wabt {
-
-Result OutputBuffer::WriteToFile(string_view filename) const {
- std::string filename_str = filename.to_string();
- FILE* file = fopen(filename_str.c_str(), "wb");
- if (!file) {
- ERROR("unable to open %s for writing\n", filename_str.c_str());
- return Result::Error;
- }
-
- if (data.empty()) {
- fclose(file);
- return Result::Ok;
- }
-
- ssize_t bytes = fwrite(data.data(), 1, data.size(), file);
- if (bytes < 0 || static_cast<size_t>(bytes) != data.size()) {
- ERROR("failed to write %" PRIzd " bytes to %s\n", data.size(),
- filename_str.c_str());
- fclose(file);
- return Result::Error;
- }
-
- fclose(file);
- return Result::Ok;
-}
-
-MemoryWriter::MemoryWriter() : buf_(new OutputBuffer()) {}
-
-MemoryWriter::MemoryWriter(std::unique_ptr<OutputBuffer> buf)
- : buf_(std::move(buf)) {}
-
-std::unique_ptr<OutputBuffer> MemoryWriter::ReleaseOutputBuffer() {
- return std::move(buf_);
-}
-
-Result MemoryWriter::WriteData(size_t dst_offset,
- const void* src,
- size_t size) {
- if (size == 0)
- return Result::Ok;
- size_t end = dst_offset + size;
- if (end > buf_->data.size()) {
- buf_->data.resize(end);
- }
- uint8_t* dst = &buf_->data[dst_offset];
- memcpy(dst, src, size);
- return Result::Ok;
-}
-
-Result MemoryWriter::MoveData(size_t dst_offset,
- size_t src_offset,
- size_t size) {
- if (size == 0)
- return Result::Ok;
- size_t src_end = src_offset + size;
- size_t dst_end = dst_offset + size;
- size_t end = src_end > dst_end ? src_end : dst_end;
- if (end > buf_->data.size()) {
- buf_->data.resize(end);
- }
-
- uint8_t* dst = &buf_->data[dst_offset];
- uint8_t* src = &buf_->data[src_offset];
- memmove(dst, src, size);
- return Result::Ok;
-}
-
-FileWriter::FileWriter(FILE* file)
- : file_(file), offset_(0), should_close_(false) {}
-
-FileWriter::FileWriter(string_view filename)
- : file_(nullptr), offset_(0), should_close_(false) {
- std::string filename_str = filename.to_string();
- file_ = fopen(filename_str.c_str(), "wb");
-
- // TODO(binji): this is pretty cheesy, should come up with a better API.
- if (file_) {
- should_close_ = true;
- } else {
- ERROR("fopen name=\"%s\" failed, errno=%d\n", filename_str.c_str(), errno);
- }
-}
-
-FileWriter::FileWriter(FileWriter&& other) {
- *this = std::move(other);
-}
-
-FileWriter& FileWriter::operator=(FileWriter&& other) {
- file_ = other.file_;
- offset_ = other.offset_;
- should_close_ = other.should_close_;
- other.file_ = nullptr;
- other.offset_ = 0;
- other.should_close_ = false;
- return *this;
-}
-
-FileWriter::~FileWriter() {
- // We don't want to close existing files (stdout/sterr, for example).
- if (should_close_) {
- fclose(file_);
- }
-}
-
-Result FileWriter::WriteData(size_t at, const void* data, size_t size) {
- if (!file_)
- return Result::Error;
- if (size == 0)
- return Result::Ok;
- if (at != offset_) {
- if (fseek(file_, at, SEEK_SET) != 0) {
- ERROR("fseek offset=%" PRIzd " failed, errno=%d\n", size, errno);
- return Result::Error;
- }
- offset_ = at;
- }
- if (fwrite(data, size, 1, file_) != 1) {
- ERROR("fwrite size=%" PRIzd " failed, errno=%d\n", size, errno);
- return Result::Error;
- }
- offset_ += size;
- return Result::Ok;
-}
-
-Result FileWriter::MoveData(size_t dst_offset, size_t src_offset, size_t size) {
- if (!file_)
- return Result::Error;
- if (size == 0)
- return Result::Ok;
- // TODO(binji): implement if needed.
- ERROR0("FileWriter::MoveData not implemented!\n");
- return Result::Error;
-}
-
-} // namespace wabt
diff --git a/src/writer.h b/src/writer.h
deleted file mode 100644
index 2d199ee4..00000000
--- a/src/writer.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2016 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_WRITER_H_
-#define WABT_WRITER_H_
-
-#include <stdio.h>
-
-#include "src/common.h"
-
-#include <memory>
-#include <vector>
-
-namespace wabt {
-
-struct OutputBuffer {
- Result WriteToFile(string_view filename) const;
-
- size_t size() const { return data.size(); }
-
- std::vector<uint8_t> data;
-};
-
-class Writer {
- public:
- virtual ~Writer() {}
- virtual Result WriteData(size_t offset, const void* data, size_t size) = 0;
- virtual Result MoveData(size_t dst_offset,
- size_t src_offset,
- size_t size) = 0;
-};
-
-class MemoryWriter : public Writer {
- public:
- MemoryWriter();
- explicit MemoryWriter(std::unique_ptr<OutputBuffer>);
-
- OutputBuffer& output_buffer() { return *buf_; }
- std::unique_ptr<OutputBuffer> ReleaseOutputBuffer();
-
- virtual Result WriteData(size_t offset, const void* data, size_t size);
- virtual Result MoveData(size_t dst_offset, size_t src_offset, size_t size);
-
- private:
- std::unique_ptr<OutputBuffer> buf_;
-};
-
-class FileWriter : public Writer {
- WABT_DISALLOW_COPY_AND_ASSIGN(FileWriter);
-
- public:
- explicit FileWriter(string_view filename);
- explicit FileWriter(FILE* file);
- FileWriter(FileWriter&&);
- FileWriter& operator=(FileWriter&&);
- ~FileWriter();
-
- bool is_open() const { return file_ != nullptr; }
-
- virtual Result WriteData(size_t offset, const void* data, size_t size);
- virtual Result MoveData(size_t dst_offset, size_t src_offset, size_t size);
-
- private:
- FILE* file_;
- size_t offset_;
- bool should_close_;
-};
-
-} // namespace wabt
-
-#endif /* WABT_WRITER_H_ */