diff options
author | Ben Smith <binjimin@gmail.com> | 2017-03-30 14:17:29 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-30 14:17:29 -0700 |
commit | ca9ccccd10d1975eb117dd9ce05a189270f2fb01 (patch) | |
tree | 91bd0c8d5fb961fb5287eb77b0a34c199ac07357 /src/binary-reader-linker.cc | |
parent | 2e9e6ce3f5f4ccf2983338fb5353013d2a5bb94d (diff) | |
download | wabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.tar.gz wabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.tar.bz2 wabt-ca9ccccd10d1975eb117dd9ce05a189270f2fb01.zip |
Use classes + virtual functions for BinaryReader (#376)
This adds a few new classes:
* BinaryReader: the abstract base class
* BinaryReaderNop: implements all of BinaryReader, but does nothing
* BinaryReaderLogging: logs calls through BinaryReader, and forwards to
another BinaryReader
Typically this means we can remove the Context structs from these
implementations, since that data can just move into the BinaryReader
subclasses.
I also took the opportunity to rename the new member functions to
MixedCase instead of snake_case, since that's more common in C++.
Diffstat (limited to 'src/binary-reader-linker.cc')
-rw-r--r-- | src/binary-reader-linker.cc | 305 |
1 files changed, 149 insertions, 156 deletions
diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc index 026c2f9d..40d3c420 100644 --- a/src/binary-reader-linker.cc +++ b/src/binary-reader-linker.cc @@ -18,7 +18,7 @@ #include <vector> -#include "binary-reader.h" +#include "binary-reader-nop.h" #include "wasm-link.h" #define RELOC_SIZE 5 @@ -28,21 +28,74 @@ namespace link { namespace { -struct Context { +class BinaryReaderLinker : public BinaryReaderNop { + public: + explicit BinaryReaderLinker(LinkerInputBinary* binary); + + virtual Result BeginSection(BinarySection section_type, uint32_t size); + + virtual Result BeginCustomSection(uint32_t size, StringSlice section_name); + + virtual Result OnImport(uint32_t index, + StringSlice module_name, + StringSlice field_name); + virtual Result OnImportFunc(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t func_index, + uint32_t sig_index); + virtual Result OnImportGlobal(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + Type type, + bool mutable_); + + virtual Result OnTable(uint32_t index, + Type elem_type, + const Limits* elem_limits); + + virtual Result OnMemory(uint32_t index, const Limits* limits); + + virtual Result OnExport(uint32_t index, + ExternalKind kind, + uint32_t item_index, + StringSlice name); + + virtual Result OnElemSegmentFunctionIndexCount(uint32_t index, + uint32_t count); + + virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index); + virtual Result OnDataSegmentData(uint32_t index, + const void* data, + uint32_t size); + + virtual Result OnFunctionName(uint32_t function_index, + StringSlice function_name); + + virtual Result OnRelocCount(uint32_t count, + BinarySection section_code, + StringSlice section_name); + virtual Result OnReloc(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend); + + virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value); + + private: LinkerInputBinary* binary; - Section* reloc_section; - Section* current_section; + Section* reloc_section = nullptr; + Section* current_section = nullptr; }; -} // namespace +BinaryReaderLinker::BinaryReaderLinker(LinkerInputBinary* binary) + : binary(binary) {} -static Result on_reloc_count(uint32_t count, - BinarySection section_code, - StringSlice section_name, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - LinkerInputBinary* binary = ctx->binary; +Result BinaryReaderLinker::OnRelocCount(uint32_t count, + BinarySection section_code, + StringSlice section_name) { if (section_code == BinarySection::Custom) { WABT_FATAL("relocation for custom sections not yet supported\n"); } @@ -50,7 +103,7 @@ static Result on_reloc_count(uint32_t count, for (const std::unique_ptr<Section>& section : binary->sections) { if (section->section_code != section_code) continue; - ctx->reloc_section = section.get(); + reloc_section = section.get(); return Result::Ok; } @@ -58,26 +111,22 @@ static Result on_reloc_count(uint32_t count, return Result::Error; } -static Result on_reloc(RelocType type, - uint32_t offset, - uint32_t index, - int32_t addend, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - - if (offset + RELOC_SIZE > ctx->reloc_section->size) { +Result BinaryReaderLinker::OnReloc(RelocType type, + uint32_t offset, + uint32_t index, + int32_t addend) { + if (offset + RELOC_SIZE > reloc_section->size) { WABT_FATAL("invalid relocation offset: %#x\n", offset); } - ctx->reloc_section->relocations.emplace_back(type, offset, index, addend); + reloc_section->relocations.emplace_back(type, offset, index, addend); return Result::Ok; } -static Result on_import(uint32_t index, - StringSlice module_name, - StringSlice field_name, - void* user_data) { +Result BinaryReaderLinker::OnImport(uint32_t index, + StringSlice module_name, + StringSlice field_name) { if (!string_slice_eq_cstr(&module_name, WABT_LINK_MODULE_NAME)) { WABT_FATAL("unsupported import module: " PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(module_name)); @@ -85,50 +134,43 @@ static Result on_import(uint32_t index, return Result::Ok; } -static Result on_import_func(uint32_t import_index, - StringSlice module_name, - StringSlice field_name, - uint32_t global_index, - uint32_t sig_index, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->function_imports.emplace_back(); - FunctionImport* import = &ctx->binary->function_imports.back(); +Result BinaryReaderLinker::OnImportFunc(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + uint32_t sig_index) { + binary->function_imports.emplace_back(); + FunctionImport* import = &binary->function_imports.back(); import->name = field_name; import->sig_index = sig_index; import->active = true; - ctx->binary->active_function_imports++; + binary->active_function_imports++; return Result::Ok; } -static Result on_import_global(uint32_t import_index, - StringSlice module_name, - StringSlice field_name, - uint32_t global_index, - Type type, - bool mutable_, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->global_imports.emplace_back(); - GlobalImport* import = &ctx->binary->global_imports.back(); +Result BinaryReaderLinker::OnImportGlobal(uint32_t import_index, + StringSlice module_name, + StringSlice field_name, + uint32_t global_index, + Type type, + bool mutable_) { + binary->global_imports.emplace_back(); + GlobalImport* import = &binary->global_imports.back(); import->name = field_name; import->type = type; import->mutable_ = mutable_; - ctx->binary->active_global_imports++; + binary->active_global_imports++; return Result::Ok; } -static Result begin_section(BinaryReaderContext* ctx, - BinarySection section_code, - uint32_t size) { - Context* context = static_cast<Context*>(ctx->user_data); - LinkerInputBinary* binary = context->binary; +Result BinaryReaderLinker::BeginSection(BinarySection section_code, + uint32_t size) { Section* sec = new Section(); binary->sections.emplace_back(sec); - context->current_section = sec; + current_section = sec; sec->section_code = section_code; sec->size = size; - sec->offset = ctx->offset; + sec->offset = state->offset; sec->binary = binary; if (sec->section_code != BinarySection::Custom && @@ -143,16 +185,13 @@ static Result begin_section(BinaryReaderContext* ctx, return Result::Ok; } -static Result begin_custom_section(BinaryReaderContext* ctx, - uint32_t size, - StringSlice section_name) { - Context* context = static_cast<Context*>(ctx->user_data); - LinkerInputBinary* binary = context->binary; - Section* sec = context->current_section; - sec->data_custom.name = section_name; +Result BinaryReaderLinker::BeginCustomSection(uint32_t size, + StringSlice section_name) { + Section* sec = current_section; + sec->data.custom.name = section_name; /* Modify section size and offset to not include the name itself. */ - size_t delta = ctx->offset - sec->offset; + size_t delta = state->offset - sec->offset; sec->offset = sec->offset + delta; sec->size = sec->size - delta; sec->payload_offset = sec->offset; @@ -164,7 +203,8 @@ static Result begin_custom_section(BinaryReaderContext* ctx, size_t bytes_read = read_u32_leb128( &binary->data[sec->offset], &binary->data[binary->size], &name_type); - if (static_cast<NameSectionSubsection>(name_type) != NameSectionSubsection::Function) { + if (static_cast<NameSectionSubsection>(name_type) != + NameSectionSubsection::Function) { WABT_FATAL("no function name section"); } @@ -172,14 +212,14 @@ static Result begin_custom_section(BinaryReaderContext* ctx, sec->payload_size -= bytes_read; uint32_t subsection_size; - bytes_read = read_u32_leb128( - &binary->data[sec->offset], &binary->data[binary->size], &subsection_size); + bytes_read = read_u32_leb128(&binary->data[sec->offset], + &binary->data[binary->size], &subsection_size); sec->payload_offset += bytes_read; sec->payload_size -= bytes_read; - bytes_read = read_u32_leb128( - &binary->data[sec->payload_offset], &binary->data[binary->size], &sec->count); + bytes_read = read_u32_leb128(&binary->data[sec->payload_offset], + &binary->data[binary->size], &sec->count); sec->payload_offset += bytes_read; sec->payload_size -= bytes_read; @@ -201,144 +241,97 @@ static Result begin_custom_section(BinaryReaderContext* ctx, return Result::Ok; } -static Result on_table(uint32_t index, - Type elem_type, - const Limits* elem_limits, - void* user_data) { +Result BinaryReaderLinker::OnTable(uint32_t index, + Type elem_type, + const Limits* elem_limits) { if (elem_limits->has_max && (elem_limits->max != elem_limits->initial)) WABT_FATAL("Tables with max != initial not supported by wabt-link\n"); - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->table_elem_count = elem_limits->initial; + binary->table_elem_count = elem_limits->initial; return Result::Ok; } -static Result on_elem_segment_function_index_count(BinaryReaderContext* ctx, - uint32_t index, - uint32_t count) { - Context* context = static_cast<Context*>(ctx->user_data); - Section* sec = context->current_section; +Result BinaryReaderLinker::OnElemSegmentFunctionIndexCount(uint32_t index, + uint32_t count) { + Section* sec = current_section; /* Modify the payload to include only the actual function indexes */ - size_t delta = ctx->offset - sec->payload_offset; + size_t delta = state->offset - sec->payload_offset; sec->payload_offset += delta; sec->payload_size -= delta; return Result::Ok; } -static Result on_memory(uint32_t index, - const Limits* page_limits, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; - sec->memory_limits = *page_limits; - ctx->binary->memory_page_count = page_limits->initial; +Result BinaryReaderLinker::OnMemory(uint32_t index, const Limits* page_limits) { + Section* sec = current_section; + sec->data.memory_limits = *page_limits; + binary->memory_page_count = page_limits->initial; return Result::Ok; } -static Result begin_data_segment(uint32_t index, - uint32_t memory_index, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; - if (!sec->data_segments) { - sec->data_segments = new std::vector<DataSegment>(); +Result BinaryReaderLinker::BeginDataSegment(uint32_t index, + uint32_t memory_index) { + Section* sec = current_section; + if (!sec->data.data_segments) { + sec->data.data_segments = new std::vector<DataSegment>(); } - sec->data_segments->emplace_back(); - DataSegment& segment = sec->data_segments->back(); + sec->data.data_segments->emplace_back(); + DataSegment& segment = sec->data.data_segments->back(); segment.memory_index = memory_index; return Result::Ok; } -static Result on_init_expr_i32_const_expr(uint32_t index, - uint32_t value, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; +Result BinaryReaderLinker::OnInitExprI32ConstExpr(uint32_t index, + uint32_t value) { + Section* sec = current_section; if (sec->section_code != BinarySection::Data) return Result::Ok; - DataSegment& segment = sec->data_segments->back(); + DataSegment& segment = sec->data.data_segments->back(); segment.offset = value; return Result::Ok; } -static Result on_data_segment_data(uint32_t index, - const void* src_data, - uint32_t size, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - Section* sec = ctx->current_section; - DataSegment& segment = sec->data_segments->back(); +Result BinaryReaderLinker::OnDataSegmentData(uint32_t index, + const void* src_data, + uint32_t size) { + Section* sec = current_section; + DataSegment& segment = sec->data.data_segments->back(); segment.data = static_cast<const uint8_t*>(src_data); segment.size = size; return Result::Ok; } -static Result on_export(uint32_t index, - ExternalKind kind, - uint32_t item_index, - StringSlice name, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - ctx->binary->exports.emplace_back(); - Export* export_ = &ctx->binary->exports.back(); +Result BinaryReaderLinker::OnExport(uint32_t index, + ExternalKind kind, + uint32_t item_index, + StringSlice name) { + binary->exports.emplace_back(); + Export* export_ = &binary->exports.back(); export_->name = name; export_->kind = kind; export_->index = item_index; return Result::Ok; } -static Result on_function_name(uint32_t index, - StringSlice name, - void* user_data) { - Context* ctx = static_cast<Context*>(user_data); - while (ctx->binary->debug_names.size() < index) { - ctx->binary->debug_names.emplace_back(); +Result BinaryReaderLinker::OnFunctionName(uint32_t index, StringSlice name) { + while (binary->debug_names.size() < index) { + binary->debug_names.emplace_back(); } - if (ctx->binary->debug_names.size() == index) { - ctx->binary->debug_names.push_back(string_slice_to_string(name)); + if (binary->debug_names.size() == index) { + binary->debug_names.push_back(string_slice_to_string(name)); } return Result::Ok; } -Result read_binary_linker(LinkerInputBinary* input_info, - LinkOptions* options) { - Context context; - WABT_ZERO_MEMORY(context); - context.binary = input_info; - - BinaryReader reader; - WABT_ZERO_MEMORY(reader); - reader.user_data = &context; - reader.begin_section = begin_section; - reader.begin_custom_section = begin_custom_section; - - reader.on_reloc_count = on_reloc_count; - reader.on_reloc = on_reloc; - - reader.on_import = on_import; - reader.on_import_func = on_import_func; - reader.on_import_global = on_import_global; - - reader.on_export = on_export; - - reader.on_table = on_table; - - reader.on_memory = on_memory; - - reader.begin_data_segment = begin_data_segment; - reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr; - reader.on_data_segment_data = on_data_segment_data; - - reader.on_elem_segment_function_index_count = - on_elem_segment_function_index_count; +} // namespace - reader.on_function_name = on_function_name; +Result read_binary_linker(LinkerInputBinary* input_info, LinkOptions* options) { + BinaryReaderLinker reader(input_info); ReadBinaryOptions read_options = WABT_READ_BINARY_OPTIONS_DEFAULT; read_options.read_debug_names = true; read_options.log_stream = options->log_stream; - return read_binary(input_info->data, input_info->size, &reader, 1, + return read_binary(input_info->data, input_info->size, &reader, &read_options); } |