summaryrefslogtreecommitdiff
path: root/src/binary-reader.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2017-05-23 12:22:10 -0700
committerGitHub <noreply@github.com>2017-05-23 12:22:10 -0700
commitcb60a587dae48ec973fb8f59f48e34d58d569f5a (patch)
treeb26d7e1ae31043231ff532560c843f4c40f3b8ba /src/binary-reader.cc
parent6f21c9537c59321ac9b3b7a8368e346573b02dfc (diff)
downloadwabt-cb60a587dae48ec973fb8f59f48e34d58d569f5a.tar.gz
wabt-cb60a587dae48ec973fb8f59f48e34d58d569f5a.tar.bz2
wabt-cb60a587dae48ec973fb8f59f48e34d58d569f5a.zip
Clean up BinaryReader; rename to BinaryReaderDelegate (#451)
This removes the use of setjmp/longjmp as well.
Diffstat (limited to 'src/binary-reader.cc')
-rw-r--r--src/binary-reader.cc1089
1 files changed, 582 insertions, 507 deletions
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index be59691e..48e0fbed 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -18,7 +18,6 @@
#include <cassert>
#include <cinttypes>
-#include <csetjmp>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
@@ -35,85 +34,30 @@
#include <alloca.h>
#endif
-namespace wabt {
+#define CHECK_RESULT(expr) \
+ do { \
+ if (WABT_FAILED(expr)) \
+ return Result::Error; \
+ } while (0)
-namespace {
+#define ERROR_UNLESS(expr, ...) \
+ do { \
+ if (!(expr)) { \
+ PrintError(__VA_ARGS__); \
+ return Result::Error; \
+ } \
+ } while (0)
#define CALLBACK0(member) \
- RAISE_ERROR_UNLESS(WABT_SUCCEEDED(ctx->reader->member()), \
- #member " callback failed")
-
-#define CALLBACK(member, ...) \
- RAISE_ERROR_UNLESS(WABT_SUCCEEDED(ctx->reader->member(__VA_ARGS__)), \
- #member " callback failed")
-
-#define RAISE_ERROR(...) raise_error(ctx, __VA_ARGS__)
-
-#define RAISE_ERROR_UNLESS(cond, ...) \
- if (!(cond)) \
- RAISE_ERROR(__VA_ARGS__);
-
-struct Context {
- size_t read_end = 0; /* Either the section end or data_size. */
- BinaryReader* reader = nullptr;
- BinaryReader::State state;
- jmp_buf error_jmp_buf;
- TypeVector param_types;
- std::vector<Index> target_depths;
- const ReadBinaryOptions* options = nullptr;
- BinarySection last_known_section = BinarySection::Invalid;
- Index num_signatures = 0;
- Index num_imports = 0;
- Index num_func_imports = 0;
- Index num_table_imports = 0;
- Index num_memory_imports = 0;
- Index num_global_imports = 0;
- Index num_function_signatures = 0;
- Index num_tables = 0;
- Index num_memories = 0;
- Index num_globals = 0;
- Index num_exports = 0;
- Index num_function_bodies = 0;
-};
-
-} // namespace
-
-static void WABT_PRINTF_FORMAT(2, 3)
- raise_error(Context* ctx, const char* format, ...) {
- WABT_SNPRINTF_ALLOCA(buffer, length, format);
- bool handled = ctx->reader->OnError(buffer);
-
- if (!handled) {
- /* Not great to just print, but we don't want to eat the error either. */
- fprintf(stderr, "*ERROR*: @0x%08zx: %s\n", ctx->state.offset, buffer);
- }
- longjmp(ctx->error_jmp_buf, 1);
-}
-
-#define IN_SIZE(type) \
- if (ctx->state.offset + sizeof(type) > ctx->read_end) { \
- RAISE_ERROR("unable to read " #type ": %s", desc); \
- } \
- memcpy(out_value, ctx->state.data + ctx->state.offset, sizeof(type)); \
- ctx->state.offset += sizeof(type)
-
-static void in_u8(Context* ctx, uint8_t* out_value, const char* desc) {
- IN_SIZE(uint8_t);
-}
-
-static void in_u32(Context* ctx, uint32_t* out_value, const char* desc) {
- IN_SIZE(uint32_t);
-}
+ ERROR_UNLESS(WABT_SUCCEEDED(delegate_->member()), #member \
+ " callback " \
+ "failed")
-static void in_f32(Context* ctx, uint32_t* out_value, const char* desc) {
- IN_SIZE(float);
-}
+#define CALLBACK(member, ...) \
+ ERROR_UNLESS(WABT_SUCCEEDED(delegate_->member(__VA_ARGS__)), \
+ #member " callback failed")
-static void in_f64(Context* ctx, uint64_t* out_value, const char* desc) {
- IN_SIZE(double);
-}
-
-#undef IN_SIZE
+namespace wabt {
#define BYTE_AT(type, i, shift) ((static_cast<type>(p[i]) & 0x7f) << (shift))
@@ -133,6 +77,7 @@ static void in_f64(Context* ctx, uint64_t* out_value, const char* desc) {
(static_cast<type>((value) << SHIFT_AMOUNT(type, sign_bit)) >> \
SHIFT_AMOUNT(type, sign_bit))
+// TODO(binji): move LEB functions elsewhere
size_t read_u32_leb128(const uint8_t* p,
const uint8_t* end,
uint32_t* out_value) {
@@ -161,15 +106,6 @@ size_t read_u32_leb128(const uint8_t* p,
}
}
-static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
- const uint8_t* p = ctx->state.data + ctx->state.offset;
- const uint8_t* end = ctx->state.data + ctx->read_end;
- size_t bytes_read = read_u32_leb128(p, end, out_value);
- if (!bytes_read)
- RAISE_ERROR("unable to read u32 leb128: %s", desc);
- ctx->state.offset += bytes_read;
-}
-
size_t read_i32_leb128(const uint8_t* p,
const uint8_t* end,
uint32_t* out_value) {
@@ -206,70 +142,210 @@ size_t read_i32_leb128(const uint8_t* p,
}
}
-static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
- const uint8_t* p = ctx->state.data + ctx->state.offset;
- const uint8_t* end = ctx->state.data + ctx->read_end;
+namespace {
+
+class BinaryReader {
+ public:
+ BinaryReader(const void* data,
+ size_t size,
+ BinaryReaderDelegate* delegate,
+ const ReadBinaryOptions* options);
+
+ Result ReadModule();
+
+ private:
+ void WABT_PRINTF_FORMAT(2, 3) PrintError(const char* format, ...);
+ Result ReadU8(uint8_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadU32(uint32_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadF32(uint32_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadF64(uint64_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadU32Leb128(uint32_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadI32Leb128(uint32_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadI64Leb128(uint64_t* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadType(Type* out_value, const char* desc) WABT_WARN_UNUSED;
+ Result ReadStr(StringSlice* out_str, const char* desc) WABT_WARN_UNUSED;
+ Result ReadBytes(const void** out_data,
+ Address* out_data_size,
+ const char* desc) WABT_WARN_UNUSED;
+ Result ReadIndex(Index* index, const char* desc) WABT_WARN_UNUSED;
+ Result ReadOffset(Offset* offset, const char* desc) WABT_WARN_UNUSED;
+
+ Index NumTotalFuncs();
+ Index NumTotalTables();
+ Index NumTotalMemories();
+ Index NumTotalGlobals();
+
+ Result ReadInitExpr(Index index) WABT_WARN_UNUSED;
+ Result ReadTable(Type* out_elem_type,
+ Limits* out_elem_limits) WABT_WARN_UNUSED;
+ Result ReadMemory(Limits* out_page_limits) WABT_WARN_UNUSED;
+ Result ReadGlobalHeader(Type* out_type, bool* out_mutable) WABT_WARN_UNUSED;
+ Result ReadFunctionBody(Offset end_offset) WABT_WARN_UNUSED;
+ Result ReadNamesSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadRelocSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadCustomSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadTypeSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadImportSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadFunctionSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadTableSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadMemorySection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadGlobalSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadExportSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadStartSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadElemSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadCodeSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadDataSection(Offset section_size) WABT_WARN_UNUSED;
+ Result ReadSections() WABT_WARN_UNUSED;
+
+ size_t read_end_ = 0; /* Either the section end or data_size. */
+ BinaryReaderDelegate::State state_;
+ BinaryReaderLogging logging_delegate_;
+ BinaryReaderDelegate* delegate_ = nullptr;
+ TypeVector param_types_;
+ std::vector<Index> target_depths_;
+ const ReadBinaryOptions* options_ = nullptr;
+ BinarySection last_known_section_ = BinarySection::Invalid;
+ Index num_signatures_ = 0;
+ Index num_imports_ = 0;
+ Index num_func_imports_ = 0;
+ Index num_table_imports_ = 0;
+ Index num_memory_imports_ = 0;
+ Index num_global_imports_ = 0;
+ Index num_function_signatures_ = 0;
+ Index num_tables_ = 0;
+ Index num_memories_ = 0;
+ Index num_globals_ = 0;
+ Index num_exports_ = 0;
+ Index num_function_bodies_ = 0;
+};
+
+BinaryReader::BinaryReader(const void* data,
+ size_t size,
+ BinaryReaderDelegate* delegate,
+ const ReadBinaryOptions* options)
+ : read_end_(size),
+ state_(static_cast<const uint8_t*>(data), size),
+ logging_delegate_(options->log_stream, delegate),
+ delegate_(options->log_stream ? &logging_delegate_ : delegate),
+ options_(options),
+ last_known_section_(BinarySection::Invalid) {
+ delegate->OnSetState(&state_);
+}
+
+void WABT_PRINTF_FORMAT(2, 3) BinaryReader::PrintError(const char* format,
+ ...) {
+ WABT_SNPRINTF_ALLOCA(buffer, length, format);
+ bool handled = delegate_->OnError(buffer);
+
+ if (!handled) {
+ /* Not great to just print, but we don't want to eat the error either. */
+ fprintf(stderr, "*ERROR*: @0x%08zx: %s\n", state_.offset, buffer);
+ }
+}
+
+#define IN_SIZE(type) \
+ if (state_.offset + sizeof(type) > read_end_) { \
+ PrintError("unable to read " #type ": %s", desc); \
+ return Result::Error; \
+ } \
+ memcpy(out_value, state_.data + state_.offset, sizeof(type)); \
+ state_.offset += sizeof(type); \
+ return Result::Ok
+
+Result BinaryReader::ReadU8(uint8_t* out_value, const char* desc) {
+ IN_SIZE(uint8_t);
+}
+
+Result BinaryReader::ReadU32(uint32_t* out_value, const char* desc) {
+ IN_SIZE(uint32_t);
+}
+
+Result BinaryReader::ReadF32(uint32_t* out_value, const char* desc) {
+ IN_SIZE(float);
+}
+
+Result BinaryReader::ReadF64(uint64_t* out_value, const char* desc) {
+ IN_SIZE(double);
+}
+
+#undef IN_SIZE
+
+Result BinaryReader::ReadU32Leb128(uint32_t* out_value, const char* desc) {
+ const uint8_t* p = state_.data + state_.offset;
+ const uint8_t* end = state_.data + read_end_;
+ size_t bytes_read = read_u32_leb128(p, end, out_value);
+ ERROR_UNLESS(bytes_read > 0, "unable to read u32 leb128: %s", desc);
+ state_.offset += bytes_read;
+ return Result::Ok;
+}
+
+Result BinaryReader::ReadI32Leb128(uint32_t* out_value, const char* desc) {
+ const uint8_t* p = state_.data + state_.offset;
+ const uint8_t* end = state_.data + read_end_;
size_t bytes_read = read_i32_leb128(p, end, out_value);
- if (!bytes_read)
- RAISE_ERROR("unable to read i32 leb128: %s", desc);
- ctx->state.offset += bytes_read;
+ ERROR_UNLESS(bytes_read > 0, "unable to read i32 leb128: %s", desc);
+ state_.offset += bytes_read;
+ return Result::Ok;
}
-static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) {
- const uint8_t* p = ctx->state.data + ctx->state.offset;
- const uint8_t* end = ctx->state.data + ctx->read_end;
+Result BinaryReader::ReadI64Leb128(uint64_t* out_value, const char* desc) {
+ const uint8_t* p = state_.data + state_.offset;
+ const uint8_t* end = state_.data + read_end_;
if (p < end && (p[0] & 0x80) == 0) {
uint64_t result = LEB128_1(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 6);
- ctx->state.offset += 1;
+ state_.offset += 1;
} else if (p + 1 < end && (p[1] & 0x80) == 0) {
uint64_t result = LEB128_2(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 13);
- ctx->state.offset += 2;
+ state_.offset += 2;
} else if (p + 2 < end && (p[2] & 0x80) == 0) {
uint64_t result = LEB128_3(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 20);
- ctx->state.offset += 3;
+ state_.offset += 3;
} else if (p + 3 < end && (p[3] & 0x80) == 0) {
uint64_t result = LEB128_4(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 27);
- ctx->state.offset += 4;
+ state_.offset += 4;
} else if (p + 4 < end && (p[4] & 0x80) == 0) {
uint64_t result = LEB128_5(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 34);
- ctx->state.offset += 5;
+ state_.offset += 5;
} else if (p + 5 < end && (p[5] & 0x80) == 0) {
uint64_t result = LEB128_6(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 41);
- ctx->state.offset += 6;
+ state_.offset += 6;
} else if (p + 6 < end && (p[6] & 0x80) == 0) {
uint64_t result = LEB128_7(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 48);
- ctx->state.offset += 7;
+ state_.offset += 7;
} else if (p + 7 < end && (p[7] & 0x80) == 0) {
uint64_t result = LEB128_8(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 55);
- ctx->state.offset += 8;
+ state_.offset += 8;
} else if (p + 8 < end && (p[8] & 0x80) == 0) {
uint64_t result = LEB128_9(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 62);
- ctx->state.offset += 9;
+ state_.offset += 9;
} else if (p + 9 < end && (p[9] & 0x80) == 0) {
/* the top bits should be a sign-extension of the sign bit */
bool sign_bit_set = (p[9] & 0x1);
int top_bits = p[9] & 0xfe;
if ((sign_bit_set && top_bits != 0x7e) ||
(!sign_bit_set && top_bits != 0)) {
- RAISE_ERROR("invalid i64 leb128: %s", desc);
+ PrintError("invalid i64 leb128: %s", desc);
+ return Result::Error;
}
uint64_t result = LEB128_10(uint64_t);
*out_value = result;
- ctx->state.offset += 10;
+ state_.offset += 10;
} else {
/* past the end */
- RAISE_ERROR("unable to read i64 leb128: %s", desc);
+ PrintError("unable to read i64 leb128: %s", desc);
+ return Result::Error;
}
+ return Result::Ok;
}
#undef BYTE_AT
@@ -286,57 +362,60 @@ static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) {
#undef SHIFT_AMOUNT
#undef SIGN_EXTEND
-static void in_type(Context* ctx, Type* out_value, const char* desc) {
+Result BinaryReader::ReadType(Type* out_value, const char* desc) {
uint32_t type = 0;
- in_i32_leb128(ctx, &type, desc);
+ CHECK_RESULT(ReadI32Leb128(&type, desc));
/* Must be in the vs7 range: [-128, 127). */
- if (static_cast<int32_t>(type) < -128 || static_cast<int32_t>(type) > 127)
- RAISE_ERROR("invalid type: %d", type);
+ ERROR_UNLESS(
+ static_cast<int32_t>(type) >= -128 && static_cast<int32_t>(type) <= 127,
+ "invalid type: %d", type);
*out_value = static_cast<Type>(type);
+ return Result::Ok;
}
-static void in_str(Context* ctx, StringSlice* out_str, const char* desc) {
+Result BinaryReader::ReadStr(StringSlice* out_str, const char* desc) {
uint32_t str_len = 0;
- in_u32_leb128(ctx, &str_len, "string length");
+ CHECK_RESULT(ReadU32Leb128(&str_len, "string length"));
- if (ctx->state.offset + str_len > ctx->read_end)
- RAISE_ERROR("unable to read string: %s", desc);
+ ERROR_UNLESS(state_.offset + str_len <= read_end_,
+ "unable to read string: %s", desc);
- out_str->start =
- reinterpret_cast<const char*>(ctx->state.data) + ctx->state.offset;
+ out_str->start = reinterpret_cast<const char*>(state_.data) + state_.offset;
out_str->length = str_len;
- ctx->state.offset += str_len;
+ state_.offset += str_len;
- RAISE_ERROR_UNLESS(is_valid_utf8(out_str->start, out_str->length),
- "invalid utf-8 encoding: %s", desc);
+ ERROR_UNLESS(is_valid_utf8(out_str->start, out_str->length),
+ "invalid utf-8 encoding: %s", desc);
+ return Result::Ok;
}
-static void in_bytes(Context* ctx,
- const void** out_data,
- Address* out_data_size,
- const char* desc) {
+Result BinaryReader::ReadBytes(const void** out_data,
+ Address* out_data_size,
+ const char* desc) {
uint32_t data_size = 0;
- in_u32_leb128(ctx, &data_size, "data size");
+ CHECK_RESULT(ReadU32Leb128(&data_size, "data size"));
- if (ctx->state.offset + data_size > ctx->read_end)
- RAISE_ERROR("unable to read data: %s", desc);
+ ERROR_UNLESS(state_.offset + data_size <= read_end_,
+ "unable to read data: %s", desc);
- *out_data =
- static_cast<const uint8_t*>(ctx->state.data) + ctx->state.offset;
+ *out_data = static_cast<const uint8_t*>(state_.data) + state_.offset;
*out_data_size = data_size;
- ctx->state.offset += data_size;
+ state_.offset += data_size;
+ return Result::Ok;
}
-static void in_index(Context* ctx, Index* index, const char* desc) {
+Result BinaryReader::ReadIndex(Index* index, const char* desc) {
uint32_t value;
- in_u32_leb128(ctx, &value, desc);
+ CHECK_RESULT(ReadU32Leb128(&value, desc));
*index = value;
+ return Result::Ok;
}
-static void in_file_offset(Context* ctx, Offset* offset, const char* desc) {
+Result BinaryReader::ReadOffset(Offset* offset, const char* desc) {
uint32_t value;
- in_u32_leb128(ctx, &value, desc);
+ CHECK_RESULT(ReadU32Leb128(&value, desc));
*offset = value;
+ return Result::Ok;
}
static bool is_valid_external_kind(uint8_t kind) {
@@ -360,140 +439,139 @@ static bool is_inline_sig_type(Type type) {
return is_concrete_type(type) || type == Type::Void;
}
-static Index num_total_funcs(Context* ctx) {
- return ctx->num_func_imports + ctx->num_function_signatures;
+Index BinaryReader::NumTotalFuncs() {
+ return num_func_imports_ + num_function_signatures_;
}
-static Index num_total_tables(Context* ctx) {
- return ctx->num_table_imports + ctx->num_tables;
+Index BinaryReader::NumTotalTables() {
+ return num_table_imports_ + num_tables_;
}
-static Index num_total_memories(Context* ctx) {
- return ctx->num_memory_imports + ctx->num_memories;
+Index BinaryReader::NumTotalMemories() {
+ return num_memory_imports_ + num_memories_;
}
-static Index num_total_globals(Context* ctx) {
- return ctx->num_global_imports + ctx->num_globals;
+Index BinaryReader::NumTotalGlobals() {
+ return num_global_imports_ + num_globals_;
}
-static void read_init_expr(Context* ctx, Index index) {
- uint8_t opcode;
- in_u8(ctx, &opcode, "opcode");
+Result BinaryReader::ReadInitExpr(Index index) {
+ uint8_t opcode = 0;
+ CHECK_RESULT(ReadU8(&opcode, "opcode"));
switch (static_cast<Opcode>(opcode)) {
case Opcode::I32Const: {
uint32_t value = 0;
- in_i32_leb128(ctx, &value, "init_expr i32.const value");
+ CHECK_RESULT(ReadI32Leb128(&value, "init_expr i32.const value"));
CALLBACK(OnInitExprI32ConstExpr, index, value);
break;
}
case Opcode::I64Const: {
uint64_t value = 0;
- in_i64_leb128(ctx, &value, "init_expr i64.const value");
+ CHECK_RESULT(ReadI64Leb128(&value, "init_expr i64.const value"));
CALLBACK(OnInitExprI64ConstExpr, index, value);
break;
}
case Opcode::F32Const: {
uint32_t value_bits = 0;
- in_f32(ctx, &value_bits, "init_expr f32.const value");
+ CHECK_RESULT(ReadF32(&value_bits, "init_expr f32.const value"));
CALLBACK(OnInitExprF32ConstExpr, index, value_bits);
break;
}
case Opcode::F64Const: {
uint64_t value_bits = 0;
- in_f64(ctx, &value_bits, "init_expr f64.const value");
+ CHECK_RESULT(ReadF64(&value_bits, "init_expr f64.const value"));
CALLBACK(OnInitExprF64ConstExpr, index, value_bits);
break;
}
case Opcode::GetGlobal: {
Index global_index;
- in_index(ctx, &global_index, "init_expr get_global index");
+ CHECK_RESULT(ReadIndex(&global_index, "init_expr get_global index"));
CALLBACK(OnInitExprGetGlobalExpr, index, global_index);
break;
}
case Opcode::End:
- return;
+ return Result::Ok;
default:
- RAISE_ERROR("unexpected opcode in initializer expression: %d (0x%x)",
- opcode, opcode);
- break;
+ PrintError("unexpected opcode in initializer expression: %d (0x%x)",
+ opcode, opcode);
+ return Result::Error;
}
- in_u8(ctx, &opcode, "opcode");
- RAISE_ERROR_UNLESS(static_cast<Opcode>(opcode) == Opcode::End,
- "expected END opcode after initializer expression");
+ CHECK_RESULT(ReadU8(&opcode, "opcode"));
+ ERROR_UNLESS(static_cast<Opcode>(opcode) == Opcode::End,
+ "expected END opcode after initializer expression");
+ return Result::Ok;
}
-static void read_table(Context* ctx,
- Type* out_elem_type,
- Limits* out_elem_limits) {
- in_type(ctx, out_elem_type, "table elem type");
- RAISE_ERROR_UNLESS(*out_elem_type == Type::Anyfunc,
- "table elem type must by anyfunc");
+Result BinaryReader::ReadTable(Type* out_elem_type, Limits* out_elem_limits) {
+ CHECK_RESULT(ReadType(out_elem_type, "table elem type"));
+ ERROR_UNLESS(*out_elem_type == Type::Anyfunc,
+ "table elem type must by anyfunc");
uint32_t flags;
uint32_t initial;
uint32_t max = 0;
- in_u32_leb128(ctx, &flags, "table flags");
- in_u32_leb128(ctx, &initial, "table initial elem count");
+ CHECK_RESULT(ReadU32Leb128(&flags, "table flags"));
+ CHECK_RESULT(ReadU32Leb128(&initial, "table initial elem count"));
bool has_max = flags & WABT_BINARY_LIMITS_HAS_MAX_FLAG;
if (has_max) {
- in_u32_leb128(ctx, &max, "table max elem count");
- RAISE_ERROR_UNLESS(initial <= max,
- "table initial elem count must be <= max elem count");
+ CHECK_RESULT(ReadU32Leb128(&max, "table max elem count"));
+ ERROR_UNLESS(initial <= max,
+ "table initial elem count must be <= max elem count");
}
out_elem_limits->has_max = has_max;
out_elem_limits->initial = initial;
out_elem_limits->max = max;
+ return Result::Ok;
}
-static void read_memory(Context* ctx, Limits* out_page_limits) {
+Result BinaryReader::ReadMemory(Limits* out_page_limits) {
uint32_t flags;
uint32_t initial;
uint32_t max = 0;
- in_u32_leb128(ctx, &flags, "memory flags");
- in_u32_leb128(ctx, &initial, "memory initial page count");
+ CHECK_RESULT(ReadU32Leb128(&flags, "memory flags"));
+ CHECK_RESULT(ReadU32Leb128(&initial, "memory initial page count"));
bool has_max = flags & WABT_BINARY_LIMITS_HAS_MAX_FLAG;
- RAISE_ERROR_UNLESS(initial <= WABT_MAX_PAGES, "invalid memory initial size");
+ ERROR_UNLESS(initial <= WABT_MAX_PAGES, "invalid memory initial size");
if (has_max) {
- in_u32_leb128(ctx, &max, "memory max page count");
- RAISE_ERROR_UNLESS(max <= WABT_MAX_PAGES, "invalid memory max size");
- RAISE_ERROR_UNLESS(initial <= max,
- "memory initial size must be <= max size");
+ CHECK_RESULT(ReadU32Leb128(&max, "memory max page count"));
+ ERROR_UNLESS(max <= WABT_MAX_PAGES, "invalid memory max size");
+ ERROR_UNLESS(initial <= max, "memory initial size must be <= max size");
}
out_page_limits->has_max = has_max;
out_page_limits->initial = initial;
out_page_limits->max = max;
+ return Result::Ok;
}
-static void read_global_header(Context* ctx,
- Type* out_type,
- bool* out_mutable) {
- Type global_type;
- uint8_t mutable_;
- in_type(ctx, &global_type, "global type");
- RAISE_ERROR_UNLESS(is_concrete_type(global_type),
- "invalid global type: %#x", static_cast<int>(global_type));
+Result BinaryReader::ReadGlobalHeader(Type* out_type, bool* out_mutable) {
+ Type global_type = Type::Void;
+ uint8_t mutable_ = 0;
+ CHECK_RESULT(ReadType(&global_type, "global type"));
+ ERROR_UNLESS(is_concrete_type(global_type), "invalid global type: %#x",
+ static_cast<int>(global_type));
- in_u8(ctx, &mutable_, "global mutability");
- RAISE_ERROR_UNLESS(mutable_ <= 1, "global mutability must be 0 or 1");
+ CHECK_RESULT(ReadU8(&mutable_, "global mutability"));
+ ERROR_UNLESS(mutable_ <= 1, "global mutability must be 0 or 1");
*out_type = global_type;
*out_mutable = mutable_;
+ return Result::Ok;
}
-static void read_function_body(Context* ctx, Offset end_offset) {
+Result BinaryReader::ReadFunctionBody(Offset end_offset) {
bool seen_end_opcode = false;
- while (ctx->state.offset < end_offset) {
- uint8_t opcode_u8;
- in_u8(ctx, &opcode_u8, "opcode");
+ while (state_.offset < end_offset) {
+ uint8_t opcode_u8 = 0;
+ CHECK_RESULT(ReadU8(&opcode_u8, "opcode"));
Opcode opcode = static_cast<Opcode>(opcode_u8);
CALLBACK(OnOpcode, opcode);
switch (opcode) {
@@ -504,9 +582,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::Block: {
Type sig_type;
- in_type(ctx, &sig_type, "block signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
+ CHECK_RESULT(ReadType(&sig_type, "block signature type"));
+ ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
Index num_types = sig_type == Type::Void ? 0 : 1;
CALLBACK(OnBlockExpr, num_types, &sig_type);
CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
@@ -515,9 +593,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::Loop: {
Type sig_type;
- in_type(ctx, &sig_type, "loop signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
+ CHECK_RESULT(ReadType(&sig_type, "loop signature type"));
+ ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
Index num_types = sig_type == Type::Void ? 0 : 1;
CALLBACK(OnLoopExpr, num_types, &sig_type);
CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
@@ -526,9 +604,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::If: {
Type sig_type;
- in_type(ctx, &sig_type, "if signature type");
- RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
- "expected valid block signature type");
+ CHECK_RESULT(ReadType(&sig_type, "if signature type"));
+ ERROR_UNLESS(is_inline_sig_type(sig_type),
+ "expected valid block signature type");
Index num_types = sig_type == Type::Void ? 0 : 1;
CALLBACK(OnIfExpr, num_types, &sig_type);
CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
@@ -547,7 +625,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::Br: {
Index depth;
- in_index(ctx, &depth, "br depth");
+ CHECK_RESULT(ReadIndex(&depth, "br depth"));
CALLBACK(OnBrExpr, depth);
CALLBACK(OnOpcodeIndex, depth);
break;
@@ -555,7 +633,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::BrIf: {
Index depth;
- in_index(ctx, &depth, "br_if depth");
+ CHECK_RESULT(ReadIndex(&depth, "br_if depth"));
CALLBACK(OnBrIfExpr, depth);
CALLBACK(OnOpcodeIndex, depth);
break;
@@ -563,20 +641,20 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::BrTable: {
Index num_targets;
- in_index(ctx, &num_targets, "br_table target count");
- ctx->target_depths.resize(num_targets);
+ CHECK_RESULT(ReadIndex(&num_targets, "br_table target count"));
+ target_depths_.resize(num_targets);
for (Index i = 0; i < num_targets; ++i) {
Index target_depth;
- in_index(ctx, &target_depth, "br_table target depth");
- ctx->target_depths[i] = target_depth;
+ CHECK_RESULT(ReadIndex(&target_depth, "br_table target depth"));
+ target_depths_[i] = target_depth;
}
Index default_target_depth;
- in_index(ctx, &default_target_depth, "br_table default target depth");
+ CHECK_RESULT(
+ ReadIndex(&default_target_depth, "br_table default target depth"));
- Index* target_depths =
- num_targets ? ctx->target_depths.data() : nullptr;
+ Index* target_depths = num_targets ? target_depths_.data() : nullptr;
CALLBACK(OnBrTableExpr, num_targets, target_depths,
default_target_depth);
@@ -599,7 +677,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
break;
case Opcode::End:
- if (ctx->state.offset == end_offset) {
+ if (state_.offset == end_offset) {
seen_end_opcode = true;
CALLBACK0(OnEndFunc);
} else {
@@ -609,7 +687,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::I32Const: {
uint32_t value;
- in_i32_leb128(ctx, &value, "i32.const value");
+ CHECK_RESULT(ReadI32Leb128(&value, "i32.const value"));
CALLBACK(OnI32ConstExpr, value);
CALLBACK(OnOpcodeUint32, value);
break;
@@ -617,7 +695,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::I64Const: {
uint64_t value;
- in_i64_leb128(ctx, &value, "i64.const value");
+ CHECK_RESULT(ReadI64Leb128(&value, "i64.const value"));
CALLBACK(OnI64ConstExpr, value);
CALLBACK(OnOpcodeUint64, value);
break;
@@ -625,7 +703,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::F32Const: {
uint32_t value_bits = 0;
- in_f32(ctx, &value_bits, "f32.const value");
+ CHECK_RESULT(ReadF32(&value_bits, "f32.const value"));
CALLBACK(OnF32ConstExpr, value_bits);
CALLBACK(OnOpcodeF32, value_bits);
break;
@@ -633,7 +711,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::F64Const: {
uint64_t value_bits = 0;
- in_f64(ctx, &value_bits, "f64.const value");
+ CHECK_RESULT(ReadF64(&value_bits, "f64.const value"));
CALLBACK(OnF64ConstExpr, value_bits);
CALLBACK(OnOpcodeF64, value_bits);
break;
@@ -641,7 +719,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::GetGlobal: {
Index global_index;
- in_index(ctx, &global_index, "get_global global index");
+ CHECK_RESULT(ReadIndex(&global_index, "get_global global index"));
CALLBACK(OnGetGlobalExpr, global_index);
CALLBACK(OnOpcodeIndex, global_index);
break;
@@ -649,7 +727,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::GetLocal: {
Index local_index;
- in_index(ctx, &local_index, "get_local local index");
+ CHECK_RESULT(ReadIndex(&local_index, "get_local local index"));
CALLBACK(OnGetLocalExpr, local_index);
CALLBACK(OnOpcodeIndex, local_index);
break;
@@ -657,7 +735,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::SetGlobal: {
Index global_index;
- in_index(ctx, &global_index, "set_global global index");
+ CHECK_RESULT(ReadIndex(&global_index, "set_global global index"));
CALLBACK(OnSetGlobalExpr, global_index);
CALLBACK(OnOpcodeIndex, global_index);
break;
@@ -665,7 +743,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::SetLocal: {
Index local_index;
- in_index(ctx, &local_index, "set_local local index");
+ CHECK_RESULT(ReadIndex(&local_index, "set_local local index"));
CALLBACK(OnSetLocalExpr, local_index);
CALLBACK(OnOpcodeIndex, local_index);
break;
@@ -673,10 +751,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::Call: {
Index func_index;
- in_index(ctx, &func_index, "call function index");
- RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
- "invalid call function index: %" PRIindex,
- func_index);
+ CHECK_RESULT(ReadIndex(&func_index, "call function index"));
+ ERROR_UNLESS(func_index < NumTotalFuncs(),
+ "invalid call function index: %" PRIindex, func_index);
CALLBACK(OnCallExpr, func_index);
CALLBACK(OnOpcodeIndex, func_index);
break;
@@ -684,13 +761,12 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::CallIndirect: {
Index sig_index;
- in_index(ctx, &sig_index, "call_indirect signature index");
- RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
- "invalid call_indirect signature index");
+ CHECK_RESULT(ReadIndex(&sig_index, "call_indirect signature index"));
+ ERROR_UNLESS(sig_index < num_signatures_,
+ "invalid call_indirect signature index");
uint32_t reserved;
- in_u32_leb128(ctx, &reserved, "call_indirect reserved");
- RAISE_ERROR_UNLESS(reserved == 0,
- "call_indirect reserved value must be 0");
+ CHECK_RESULT(ReadU32Leb128(&reserved, "call_indirect reserved"));
+ ERROR_UNLESS(reserved == 0, "call_indirect reserved value must be 0");
CALLBACK(OnCallIndirectExpr, sig_index);
CALLBACK(OnOpcodeUint32Uint32, sig_index, reserved);
break;
@@ -698,7 +774,7 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::TeeLocal: {
Index local_index;
- in_index(ctx, &local_index, "tee_local local index");
+ CHECK_RESULT(ReadIndex(&local_index, "tee_local local index"));
CALLBACK(OnTeeLocalExpr, local_index);
CALLBACK(OnOpcodeIndex, local_index);
break;
@@ -719,9 +795,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::F32Load:
case Opcode::F64Load: {
uint32_t alignment_log2;
- in_u32_leb128(ctx, &alignment_log2, "load alignment");
+ CHECK_RESULT(ReadU32Leb128(&alignment_log2, "load alignment"));
Address offset;
- in_u32_leb128(ctx, &offset, "load offset");
+ CHECK_RESULT(ReadU32Leb128(&offset, "load offset"));
CALLBACK(OnLoadExpr, opcode, alignment_log2, offset);
CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
@@ -738,9 +814,9 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::F32Store:
case Opcode::F64Store: {
uint32_t alignment_log2;
- in_u32_leb128(ctx, &alignment_log2, "store alignment");
+ CHECK_RESULT(ReadU32Leb128(&alignment_log2, "store alignment"));
Address offset;
- in_u32_leb128(ctx, &offset, "store offset");
+ CHECK_RESULT(ReadU32Leb128(&offset, "store offset"));
CALLBACK(OnStoreExpr, opcode, alignment_log2, offset);
CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
@@ -749,9 +825,8 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::CurrentMemory: {
uint32_t reserved;
- in_u32_leb128(ctx, &reserved, "current_memory reserved");
- RAISE_ERROR_UNLESS(reserved == 0,
- "current_memory reserved value must be 0");
+ CHECK_RESULT(ReadU32Leb128(&reserved, "current_memory reserved"));
+ ERROR_UNLESS(reserved == 0, "current_memory reserved value must be 0");
CALLBACK0(OnCurrentMemoryExpr);
CALLBACK(OnOpcodeUint32, reserved);
break;
@@ -759,9 +834,8 @@ static void read_function_body(Context* ctx, Offset end_offset) {
case Opcode::GrowMemory: {
uint32_t reserved;
- in_u32_leb128(ctx, &reserved, "grow_memory reserved");
- RAISE_ERROR_UNLESS(reserved == 0,
- "grow_memory reserved value must be 0");
+ CHECK_RESULT(ReadU32Leb128(&reserved, "grow_memory reserved"));
+ ERROR_UNLESS(reserved == 0, "grow_memory reserved value must be 0");
CALLBACK0(OnGrowMemoryExpr);
CALLBACK(OnOpcodeUint32, reserved);
break;
@@ -907,122 +981,123 @@ static void read_function_body(Context* ctx, Offset end_offset) {
break;
default:
- RAISE_ERROR("unexpected opcode: %d (0x%x)", static_cast<int>(opcode),
- static_cast<unsigned>(opcode));
+ PrintError("unexpected opcode: %d (0x%x)", static_cast<int>(opcode),
+ static_cast<unsigned>(opcode));
+ return Result::Error;
}
}
- RAISE_ERROR_UNLESS(ctx->state.offset == end_offset,
- "function body longer than given size");
- RAISE_ERROR_UNLESS(seen_end_opcode, "function body must end with END opcode");
+ ERROR_UNLESS(state_.offset == end_offset,
+ "function body longer than given size");
+ ERROR_UNLESS(seen_end_opcode, "function body must end with END opcode");
+ return Result::Ok;
}
-static void read_names_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadNamesSection(Offset section_size) {
CALLBACK(BeginNamesSection, section_size);
Index i = 0;
- Offset previous_read_end = ctx->read_end;
+ Offset previous_read_end = read_end_;
uint32_t previous_subsection_type = 0;
- while (ctx->state.offset < ctx->read_end) {
+ while (state_.offset < read_end_) {
uint32_t name_type;
Offset subsection_size;
- in_u32_leb128(ctx, &name_type, "name type");
+ CHECK_RESULT(ReadU32Leb128(&name_type, "name type"));
if (i != 0) {
- if (name_type == previous_subsection_type)
- RAISE_ERROR("duplicate sub-section");
- if (name_type < previous_subsection_type)
- RAISE_ERROR("out-of-order sub-section");
+ ERROR_UNLESS(name_type != previous_subsection_type,
+ "duplicate sub-section");
+ ERROR_UNLESS(name_type >= previous_subsection_type,
+ "out-of-order sub-section");
}
previous_subsection_type = name_type;
- in_file_offset(ctx, &subsection_size, "subsection size");
- size_t subsection_end = ctx->state.offset + subsection_size;
- if (subsection_end > ctx->read_end)
- RAISE_ERROR("invalid sub-section size: extends past end");
- ctx->read_end = subsection_end;
+ CHECK_RESULT(ReadOffset(&subsection_size, "subsection size"));
+ size_t subsection_end = state_.offset + subsection_size;
+ ERROR_UNLESS(subsection_end <= read_end_,
+ "invalid sub-section size: extends past end");
+ read_end_ = subsection_end;
switch (static_cast<NameSectionSubsection>(name_type)) {
- case NameSectionSubsection::Function:
- CALLBACK(OnFunctionNameSubsection, i, name_type, subsection_size);
- if (subsection_size) {
- Index num_names;
- in_index(ctx, &num_names, "name count");
- CALLBACK(OnFunctionNamesCount, num_names);
- for (Index j = 0; j < num_names; ++j) {
- Index function_index;
- StringSlice function_name;
-
- in_index(ctx, &function_index, "function index");
- RAISE_ERROR_UNLESS(function_index < num_total_funcs(ctx),
- "invalid function index: %" PRIindex,
- function_index);
- in_str(ctx, &function_name, "function name");
- CALLBACK(OnFunctionName, function_index, function_name);
+ case NameSectionSubsection::Function:
+ CALLBACK(OnFunctionNameSubsection, i, name_type, subsection_size);
+ if (subsection_size) {
+ Index num_names;
+ CHECK_RESULT(ReadIndex(&num_names, "name count"));
+ CALLBACK(OnFunctionNamesCount, num_names);
+ for (Index j = 0; j < num_names; ++j) {
+ Index function_index;
+ StringSlice function_name;
+
+ CHECK_RESULT(ReadIndex(&function_index, "function index"));
+ ERROR_UNLESS(function_index < NumTotalFuncs(),
+ "invalid function index: %" PRIindex, function_index);
+ CHECK_RESULT(ReadStr(&function_name, "function name"));
+ CALLBACK(OnFunctionName, function_index, function_name);
+ }
}
- }
- break;
- case NameSectionSubsection::Local:
- CALLBACK(OnLocalNameSubsection, i, name_type, subsection_size);
- if (subsection_size) {
- Index num_funcs;
- in_index(ctx, &num_funcs, "function count");
- CALLBACK(OnLocalNameFunctionCount, num_funcs);
- for (Index j = 0; j < num_funcs; ++j) {
- Index function_index;
- in_index(ctx, &function_index, "function index");
- RAISE_ERROR_UNLESS(function_index < num_total_funcs(ctx),
- "invalid function index: %u", function_index);
- Index num_locals;
- in_index(ctx, &num_locals, "local count");
- CALLBACK(OnLocalNameLocalCount, function_index, num_locals);
- for (Index k = 0; k < num_locals; ++k) {
- Index local_index;
- StringSlice local_name;
-
- in_index(ctx, &local_index, "named index");
- in_str(ctx, &local_name, "name");
- CALLBACK(OnLocalName, function_index, local_index, local_name);
+ break;
+ case NameSectionSubsection::Local:
+ CALLBACK(OnLocalNameSubsection, i, name_type, subsection_size);
+ if (subsection_size) {
+ Index num_funcs;
+ CHECK_RESULT(ReadIndex(&num_funcs, "function count"));
+ CALLBACK(OnLocalNameFunctionCount, num_funcs);
+ for (Index j = 0; j < num_funcs; ++j) {
+ Index function_index;
+ CHECK_RESULT(ReadIndex(&function_index, "function index"));
+ ERROR_UNLESS(function_index < NumTotalFuncs(),
+ "invalid function index: %u", function_index);
+ Index num_locals;
+ CHECK_RESULT(ReadIndex(&num_locals, "local count"));
+ CALLBACK(OnLocalNameLocalCount, function_index, num_locals);
+ for (Index k = 0; k < num_locals; ++k) {
+ Index local_index;
+ StringSlice local_name;
+
+ CHECK_RESULT(ReadIndex(&local_index, "named index"));
+ CHECK_RESULT(ReadStr(&local_name, "name"));
+ CALLBACK(OnLocalName, function_index, local_index, local_name);
+ }
}
}
- }
- break;
- default:
- /* unknown subsection, skip it */
- ctx->state.offset = subsection_end;
- break;
+ break;
+ default:
+ /* unknown subsection, skip it */
+ state_.offset = subsection_end;
+ break;
}
++i;
- if (ctx->state.offset != subsection_end) {
- RAISE_ERROR("unfinished sub-section (expected end: 0x%" PRIzx ")",
- subsection_end);
- }
- ctx->read_end = previous_read_end;
+ ERROR_UNLESS(state_.offset == subsection_end,
+ "unfinished sub-section (expected end: 0x%" PRIzx ")",
+ subsection_end);
+ read_end_ = previous_read_end;
}
CALLBACK0(EndNamesSection);
+ return Result::Ok;
}
-static void read_reloc_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadRelocSection(Offset section_size) {
CALLBACK(BeginRelocSection, section_size);
uint32_t section;
- in_u32_leb128(ctx, &section, "section");
+ CHECK_RESULT(ReadU32Leb128(&section, "section"));
StringSlice section_name;
WABT_ZERO_MEMORY(section_name);
if (static_cast<BinarySection>(section) == BinarySection::Custom)
- in_str(ctx, &section_name, "section name");
+ CHECK_RESULT(ReadStr(&section_name, "section name"));
Index num_relocs;
- in_index(ctx, &num_relocs, "relocation count");
+ CHECK_RESULT(ReadIndex(&num_relocs, "relocation count"));
CALLBACK(OnRelocCount, num_relocs, static_cast<BinarySection>(section),
section_name);
for (Index i = 0; i < num_relocs; ++i) {
Offset offset;
Index index;
uint32_t reloc_type, addend = 0;
- in_u32_leb128(ctx, &reloc_type, "relocation type");
- in_file_offset(ctx, &offset, "offset");
- in_index(ctx, &index, "index");
+ CHECK_RESULT(ReadU32Leb128(&reloc_type, "relocation type"));
+ CHECK_RESULT(ReadOffset(&offset, "offset"));
+ CHECK_RESULT(ReadIndex(&index, "index"));
RelocType type = static_cast<RelocType>(reloc_type);
switch (type) {
case RelocType::GlobalAddressLEB:
case RelocType::GlobalAddressSLEB:
case RelocType::GlobalAddressI32:
- in_i32_leb128(ctx, &addend, "addend");
+ CHECK_RESULT(ReadI32Leb128(&addend, "addend"));
break;
default:
break;
@@ -1030,235 +1105,240 @@ static void read_reloc_section(Context* ctx, Offset section_size) {
CALLBACK(OnReloc, type, offset, index, addend);
}
CALLBACK0(EndRelocSection);
+ return Result::Ok;
}
-static void read_custom_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadCustomSection(Offset section_size) {
StringSlice section_name;
- in_str(ctx, &section_name, "section name");
+ CHECK_RESULT(ReadStr(&section_name, "section name"));
CALLBACK(BeginCustomSection, section_size, section_name);
- bool name_section_ok = ctx->last_known_section >= BinarySection::Import;
- if (ctx->options->read_debug_names && name_section_ok &&
+ bool name_section_ok = last_known_section_ >= BinarySection::Import;
+ if (options_->read_debug_names && name_section_ok &&
strncmp(section_name.start, WABT_BINARY_SECTION_NAME,
section_name.length) == 0) {
- read_names_section(ctx, section_size);
+ CHECK_RESULT(ReadNamesSection(section_size));
} else if (strncmp(section_name.start, WABT_BINARY_SECTION_RELOC,
strlen(WABT_BINARY_SECTION_RELOC)) == 0) {
- read_reloc_section(ctx, section_size);
+ CHECK_RESULT(ReadRelocSection(section_size));
} else {
/* This is an unknown custom section, skip it. */
- ctx->state.offset = ctx->read_end;
+ state_.offset = read_end_;
}
CALLBACK0(EndCustomSection);
+ return Result::Ok;
}
-static void read_type_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadTypeSection(Offset section_size) {
CALLBACK(BeginTypeSection, section_size);
- in_index(ctx, &ctx->num_signatures, "type count");
- CALLBACK(OnTypeCount, ctx->num_signatures);
+ CHECK_RESULT(ReadIndex(&num_signatures_, "type count"));
+ CALLBACK(OnTypeCount, num_signatures_);
- for (Index i = 0; i < ctx->num_signatures; ++i) {
+ for (Index i = 0; i < num_signatures_; ++i) {
Type form;
- in_type(ctx, &form, "type form");
- RAISE_ERROR_UNLESS(form == Type::Func, "unexpected type form: %d",
- static_cast<int>(form));
+ CHECK_RESULT(ReadType(&form, "type form"));
+ ERROR_UNLESS(form == Type::Func, "unexpected type form: %d",
+ static_cast<int>(form));
Index num_params;
- in_index(ctx, &num_params, "function param count");
+ CHECK_RESULT(ReadIndex(&num_params, "function param count"));
- ctx->param_types.resize(num_params);
+ param_types_.resize(num_params);
for (Index j = 0; j < num_params; ++j) {
Type param_type;
- in_type(ctx, &param_type, "function param type");
- RAISE_ERROR_UNLESS(is_concrete_type(param_type),
- "expected valid param type (got %d)",
- static_cast<int>(param_type));
- ctx->param_types[j] = param_type;
+ CHECK_RESULT(ReadType(&param_type, "function param type"));
+ ERROR_UNLESS(is_concrete_type(param_type),
+ "expected valid param type (got %d)",
+ static_cast<int>(param_type));
+ param_types_[j] = param_type;
}
Index num_results;
- in_index(ctx, &num_results, "function result count");
- RAISE_ERROR_UNLESS(num_results <= 1, "result count must be 0 or 1");
+ CHECK_RESULT(ReadIndex(&num_results, "function result count"));
+ ERROR_UNLESS(num_results <= 1, "result count must be 0 or 1");
Type result_type = Type::Void;
if (num_results) {
- in_type(ctx, &result_type, "function result type");
- RAISE_ERROR_UNLESS(is_concrete_type(result_type),
- "expected valid result type: %d",
- static_cast<int>(result_type));
+ CHECK_RESULT(ReadType(&result_type, "function result type"));
+ ERROR_UNLESS(is_concrete_type(result_type),
+ "expected valid result type: %d",
+ static_cast<int>(result_type));
}
- Type* param_types = num_params ? ctx->param_types.data() : nullptr;
+ Type* param_types = num_params ? param_types_.data() : nullptr;
CALLBACK(OnType, i, num_params, param_types, num_results, &result_type);
}
CALLBACK0(EndTypeSection);
+ return Result::Ok;
}
-static void read_import_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadImportSection(Offset section_size) {
CALLBACK(BeginImportSection, section_size);
- in_index(ctx, &ctx->num_imports, "import count");
- CALLBACK(OnImportCount, ctx->num_imports);
- for (Index i = 0; i < ctx->num_imports; ++i) {
+ CHECK_RESULT(ReadIndex(&num_imports_, "import count"));
+ CALLBACK(OnImportCount, num_imports_);
+ for (Index i = 0; i < num_imports_; ++i) {
StringSlice module_name;
- in_str(ctx, &module_name, "import module name");
+ CHECK_RESULT(ReadStr(&module_name, "import module name"));
StringSlice field_name;
- in_str(ctx, &field_name, "import field name");
+ CHECK_RESULT(ReadStr(&field_name, "import field name"));
uint32_t kind;
- in_u32_leb128(ctx, &kind, "import kind");
+ CHECK_RESULT(ReadU32Leb128(&kind, "import kind"));
switch (static_cast<ExternalKind>(kind)) {
case ExternalKind::Func: {
Index sig_index;
- in_index(ctx, &sig_index, "import signature index");
- RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
- "invalid import signature index");
+ CHECK_RESULT(ReadIndex(&sig_index, "import signature index"));
+ ERROR_UNLESS(sig_index < num_signatures_,
+ "invalid import signature index");
CALLBACK(OnImport, i, module_name, field_name);
- CALLBACK(OnImportFunc, i, module_name, field_name,
- ctx->num_func_imports, sig_index);
- ctx->num_func_imports++;
+ CALLBACK(OnImportFunc, i, module_name, field_name, num_func_imports_,
+ sig_index);
+ num_func_imports_++;
break;
}
case ExternalKind::Table: {
Type elem_type;
Limits elem_limits;
- read_table(ctx, &elem_type, &elem_limits);
+ CHECK_RESULT(ReadTable(&elem_type, &elem_limits));
CALLBACK(OnImport, i, module_name, field_name);
- CALLBACK(OnImportTable, i, module_name, field_name,
- ctx->num_table_imports, elem_type, &elem_limits);
- ctx->num_table_imports++;
+ CALLBACK(OnImportTable, i, module_name, field_name, num_table_imports_,
+ elem_type, &elem_limits);
+ num_table_imports_++;
break;
}
case ExternalKind::Memory: {
Limits page_limits;
- read_memory(ctx, &page_limits);
+ CHECK_RESULT(ReadMemory(&page_limits));
CALLBACK(OnImport, i, module_name, field_name);
CALLBACK(OnImportMemory, i, module_name, field_name,
- ctx->num_memory_imports, &page_limits);
- ctx->num_memory_imports++;
+ num_memory_imports_, &page_limits);
+ num_memory_imports_++;
break;
}
case ExternalKind::Global: {
Type type;
bool mutable_;
- read_global_header(ctx, &type, &mutable_);
+ CHECK_RESULT(ReadGlobalHeader(&type, &mutable_));
CALLBACK(OnImport, i, module_name, field_name);
CALLBACK(OnImportGlobal, i, module_name, field_name,
- ctx->num_global_imports, type, mutable_);
- ctx->num_global_imports++;
+ num_global_imports_, type, mutable_);
+ num_global_imports_++;
break;
}
default:
- RAISE_ERROR("invalid import kind: %d", kind);
+ PrintError("invalid import kind: %d", kind);
+ return Result::Error;
}
}
CALLBACK0(EndImportSection);
+ return Result::Ok;
}
-static void read_function_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadFunctionSection(Offset section_size) {
CALLBACK(BeginFunctionSection, section_size);
- in_index(ctx, &ctx->num_function_signatures, "function signature count");
- CALLBACK(OnFunctionCount, ctx->num_function_signatures);
- for (Index i = 0; i < ctx->num_function_signatures; ++i) {
- Index func_index = ctx->num_func_imports + i;
+ CHECK_RESULT(
+ ReadIndex(&num_function_signatures_, "function signature count"));
+ CALLBACK(OnFunctionCount, num_function_signatures_);
+ for (Index i = 0; i < num_function_signatures_; ++i) {
+ Index func_index = num_func_imports_ + i;
Index sig_index;
- in_index(ctx, &sig_index, "function signature index");
- RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
- "invalid function signature index: %" PRIindex,
- sig_index);
+ CHECK_RESULT(ReadIndex(&sig_index, "function signature index"));
+ ERROR_UNLESS(sig_index < num_signatures_,
+ "invalid function signature index: %" PRIindex, sig_index);
CALLBACK(OnFunction, func_index, sig_index);
}
CALLBACK0(EndFunctionSection);
+ return Result::Ok;
}
-static void read_table_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadTableSection(Offset section_size) {
CALLBACK(BeginTableSection, section_size);
- in_index(ctx, &ctx->num_tables, "table count");
- RAISE_ERROR_UNLESS(ctx->num_tables <= 1,
- "table count (%" PRIindex ") must be 0 or 1",
- ctx->num_tables);
- CALLBACK(OnTableCount, ctx->num_tables);
- for (Index i = 0; i < ctx->num_tables; ++i) {
- Index table_index = ctx->num_table_imports + i;
+ CHECK_RESULT(ReadIndex(&num_tables_, "table count"));
+ ERROR_UNLESS(num_tables_ <= 1, "table count (%" PRIindex ") must be 0 or 1",
+ num_tables_);
+ CALLBACK(OnTableCount, num_tables_);
+ for (Index i = 0; i < num_tables_; ++i) {
+ Index table_index = num_table_imports_ + i;
Type elem_type;
Limits elem_limits;
- read_table(ctx, &elem_type, &elem_limits);
+ CHECK_RESULT(ReadTable(&elem_type, &elem_limits));
CALLBACK(OnTable, table_index, elem_type, &elem_limits);
}
CALLBACK0(EndTableSection);
+ return Result::Ok;
}
-static void read_memory_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadMemorySection(Offset section_size) {
CALLBACK(BeginMemorySection, section_size);
- in_index(ctx, &ctx->num_memories, "memory count");
- RAISE_ERROR_UNLESS(ctx->num_memories <= 1, "memory count must be 0 or 1");
- CALLBACK(OnMemoryCount, ctx->num_memories);
- for (Index i = 0; i < ctx->num_memories; ++i) {
- Index memory_index = ctx->num_memory_imports + i;
+ CHECK_RESULT(ReadIndex(&num_memories_, "memory count"));
+ ERROR_UNLESS(num_memories_ <= 1, "memory count must be 0 or 1");
+ CALLBACK(OnMemoryCount, num_memories_);
+ for (Index i = 0; i < num_memories_; ++i) {
+ Index memory_index = num_memory_imports_ + i;
Limits page_limits;
- read_memory(ctx, &page_limits);
+ CHECK_RESULT(ReadMemory(&page_limits));
CALLBACK(OnMemory, memory_index, &page_limits);
}
CALLBACK0(EndMemorySection);
+ return Result::Ok;
}
-static void read_global_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadGlobalSection(Offset section_size) {
CALLBACK(BeginGlobalSection, section_size);
- in_index(ctx, &ctx->num_globals, "global count");
- CALLBACK(OnGlobalCount, ctx->num_globals);
- for (Index i = 0; i < ctx->num_globals; ++i) {
- Index global_index = ctx->num_global_imports + i;
+ CHECK_RESULT(ReadIndex(&num_globals_, "global count"));
+ CALLBACK(OnGlobalCount, num_globals_);
+ for (Index i = 0; i < num_globals_; ++i) {
+ Index global_index = num_global_imports_ + i;
Type global_type;
bool mutable_;
- read_global_header(ctx, &global_type, &mutable_);
+ CHECK_RESULT(ReadGlobalHeader(&global_type, &mutable_));
CALLBACK(BeginGlobal, global_index, global_type, mutable_);
CALLBACK(BeginGlobalInitExpr, global_index);
- read_init_expr(ctx, global_index);
+ CHECK_RESULT(ReadInitExpr(global_index));
CALLBACK(EndGlobalInitExpr, global_index);
CALLBACK(EndGlobal, global_index);
}
CALLBACK0(EndGlobalSection);
+ return Result::Ok;
}
-static void read_export_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadExportSection(Offset section_size) {
CALLBACK(BeginExportSection, section_size);
- in_index(ctx, &ctx->num_exports, "export count");
- CALLBACK(OnExportCount, ctx->num_exports);
- for (Index i = 0; i < ctx->num_exports; ++i) {
+ CHECK_RESULT(ReadIndex(&num_exports_, "export count"));
+ CALLBACK(OnExportCount, num_exports_);
+ for (Index i = 0; i < num_exports_; ++i) {
StringSlice name;
- in_str(ctx, &name, "export item name");
+ CHECK_RESULT(ReadStr(&name, "export item name"));
- uint8_t external_kind;
- in_u8(ctx, &external_kind, "export external kind");
- RAISE_ERROR_UNLESS(is_valid_external_kind(external_kind),
- "invalid export external kind: %d", external_kind);
+ uint8_t external_kind = 0;
+ CHECK_RESULT(ReadU8(&external_kind, "export external kind"));
+ ERROR_UNLESS(is_valid_external_kind(external_kind),
+ "invalid export external kind: %d", external_kind);
Index item_index;
- in_index(ctx, &item_index, "export item index");
+ CHECK_RESULT(ReadIndex(&item_index, "export item index"));
switch (static_cast<ExternalKind>(external_kind)) {
case ExternalKind::Func:
- RAISE_ERROR_UNLESS(item_index < num_total_funcs(ctx),
- "invalid export func index: %" PRIindex, item_index);
+ ERROR_UNLESS(item_index < NumTotalFuncs(),
+ "invalid export func index: %" PRIindex, item_index);
break;
case ExternalKind::Table:
- RAISE_ERROR_UNLESS(item_index < num_total_tables(ctx),
- "invalid export table index: %" PRIindex,
- item_index);
+ ERROR_UNLESS(item_index < NumTotalTables(),
+ "invalid export table index: %" PRIindex, item_index);
break;
case ExternalKind::Memory:
- RAISE_ERROR_UNLESS(item_index < num_total_memories(ctx),
- "invalid export memory index: %" PRIindex,
- item_index);
+ ERROR_UNLESS(item_index < NumTotalMemories(),
+ "invalid export memory index: %" PRIindex, item_index);
break;
case ExternalKind::Global:
- RAISE_ERROR_UNLESS(item_index < num_total_globals(ctx),
- "invalid export global index: %" PRIindex,
- item_index);
+ ERROR_UNLESS(item_index < NumTotalGlobals(),
+ "invalid export global index: %" PRIindex, item_index);
break;
}
@@ -1266,137 +1346,142 @@ static void read_export_section(Context* ctx, Offset section_size) {
name);
}
CALLBACK0(EndExportSection);
+ return Result::Ok;
}
-static void read_start_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadStartSection(Offset section_size) {
CALLBACK(BeginStartSection, section_size);
Index func_index;
- in_index(ctx, &func_index, "start function index");
- RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
- "invalid start function index: %" PRIindex, func_index);
+ CHECK_RESULT(ReadIndex(&func_index, "start function index"));
+ ERROR_UNLESS(func_index < NumTotalFuncs(),
+ "invalid start function index: %" PRIindex, func_index);
CALLBACK(OnStartFunction, func_index);
CALLBACK0(EndStartSection);
+ return Result::Ok;
}
-static void read_elem_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadElemSection(Offset section_size) {
CALLBACK(BeginElemSection, section_size);
Index num_elem_segments;
- in_index(ctx, &num_elem_segments, "elem segment count");
+ CHECK_RESULT(ReadIndex(&num_elem_segments, "elem segment count"));
CALLBACK(OnElemSegmentCount, num_elem_segments);
- RAISE_ERROR_UNLESS(num_elem_segments == 0 || num_total_tables(ctx) > 0,
- "elem section without table section");
+ ERROR_UNLESS(num_elem_segments == 0 || NumTotalTables() > 0,
+ "elem section without table section");
for (Index i = 0; i < num_elem_segments; ++i) {
Index table_index;
- in_index(ctx, &table_index, "elem segment table index");
+ CHECK_RESULT(ReadIndex(&table_index, "elem segment table index"));
CALLBACK(BeginElemSegment, i, table_index);
CALLBACK(BeginElemSegmentInitExpr, i);
- read_init_expr(ctx, i);
+ CHECK_RESULT(ReadInitExpr(i));
CALLBACK(EndElemSegmentInitExpr, i);
Index num_function_indexes;
- in_index(ctx, &num_function_indexes, "elem segment function index count");
+ CHECK_RESULT(
+ ReadIndex(&num_function_indexes, "elem segment function index count"));
CALLBACK(OnElemSegmentFunctionIndexCount, i, num_function_indexes);
for (Index j = 0; j < num_function_indexes; ++j) {
Index func_index;
- in_index(ctx, &func_index, "elem segment function index");
+ CHECK_RESULT(ReadIndex(&func_index, "elem segment function index"));
CALLBACK(OnElemSegmentFunctionIndex, i, func_index);
}
CALLBACK(EndElemSegment, i);
}
CALLBACK0(EndElemSection);
+ return Result::Ok;
}
-static void read_code_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadCodeSection(Offset section_size) {
CALLBACK(BeginCodeSection, section_size);
- in_index(ctx, &ctx->num_function_bodies, "function body count");
- RAISE_ERROR_UNLESS(ctx->num_function_signatures == ctx->num_function_bodies,
- "function signature count != function body count");
- CALLBACK(OnFunctionBodyCount, ctx->num_function_bodies);
- for (Index i = 0; i < ctx->num_function_bodies; ++i) {
- Index func_index = ctx->num_func_imports + i;
- Offset func_offset = ctx->state.offset;
- ctx->state.offset = func_offset;
+ CHECK_RESULT(ReadIndex(&num_function_bodies_, "function body count"));
+ ERROR_UNLESS(num_function_signatures_ == num_function_bodies_,
+ "function signature count != function body count");
+ CALLBACK(OnFunctionBodyCount, num_function_bodies_);
+ for (Index i = 0; i < num_function_bodies_; ++i) {
+ Index func_index = num_func_imports_ + i;
+ Offset func_offset = state_.offset;
+ state_.offset = func_offset;
CALLBACK(BeginFunctionBody, func_index);
uint32_t body_size;
- in_u32_leb128(ctx, &body_size, "function body size");
- Offset body_start_offset = ctx->state.offset;
+ CHECK_RESULT(ReadU32Leb128(&body_size, "function body size"));
+ Offset body_start_offset = state_.offset;
Offset end_offset = body_start_offset + body_size;
Index num_local_decls;
- in_index(ctx, &num_local_decls, "local declaration count");
+ CHECK_RESULT(ReadIndex(&num_local_decls, "local declaration count"));
CALLBACK(OnLocalDeclCount, num_local_decls);
for (Index k = 0; k < num_local_decls; ++k) {
Index num_local_types;
- in_index(ctx, &num_local_types, "local type count");
+ CHECK_RESULT(ReadIndex(&num_local_types, "local type count"));
Type local_type;
- in_type(ctx, &local_type, "local type");
- RAISE_ERROR_UNLESS(is_concrete_type(local_type),
- "expected valid local type");
+ CHECK_RESULT(ReadType(&local_type, "local type"));
+ ERROR_UNLESS(is_concrete_type(local_type), "expected valid local type");
CALLBACK(OnLocalDecl, k, num_local_types, local_type);
}
- read_function_body(ctx, end_offset);
+ CHECK_RESULT(ReadFunctionBody(end_offset));
CALLBACK(EndFunctionBody, func_index);
}
CALLBACK0(EndCodeSection);
+ return Result::Ok;
}
-static void read_data_section(Context* ctx, Offset section_size) {
+Result BinaryReader::ReadDataSection(Offset section_size) {
CALLBACK(BeginDataSection, section_size);
Index num_data_segments;
- in_index(ctx, &num_data_segments, "data segment count");
+ CHECK_RESULT(ReadIndex(&num_data_segments, "data segment count"));
CALLBACK(OnDataSegmentCount, num_data_segments);
- RAISE_ERROR_UNLESS(num_data_segments == 0 || num_total_memories(ctx) > 0,
- "data section without memory section");
+ ERROR_UNLESS(num_data_segments == 0 || NumTotalMemories() > 0,
+ "data section without memory section");
for (Index i = 0; i < num_data_segments; ++i) {
Index memory_index;
- in_index(ctx, &memory_index, "data segment memory index");
+ CHECK_RESULT(ReadIndex(&memory_index, "data segment memory index"));
CALLBACK(BeginDataSegment, i, memory_index);
CALLBACK(BeginDataSegmentInitExpr, i);
- read_init_expr(ctx, i);
+ CHECK_RESULT(ReadInitExpr(i));
CALLBACK(EndDataSegmentInitExpr, i);
Address data_size;
const void* data;
- in_bytes(ctx, &data, &data_size, "data segment data");
+ CHECK_RESULT(ReadBytes(&data, &data_size, "data segment data"));
CALLBACK(OnDataSegmentData, i, data, data_size);
CALLBACK(EndDataSegment, i);
}
CALLBACK0(EndDataSection);
+ return Result::Ok;
}
-static void read_sections(Context* ctx) {
- while (ctx->state.offset < ctx->state.size) {
+Result BinaryReader::ReadSections() {
+ while (state_.offset < state_.size) {
uint32_t section_code;
Offset section_size;
- /* Temporarily reset read_end to the full data size so the next section
+ /* Temporarily reset read_end_ to the full data size so the next section
* can be read. */
- ctx->read_end = ctx->state.size;
- in_u32_leb128(ctx, &section_code, "section code");
- in_file_offset(ctx, &section_size, "section size");
- ctx->read_end = ctx->state.offset + section_size;
+ read_end_ = state_.size;
+ CHECK_RESULT(ReadU32Leb128(&section_code, "section code"));
+ CHECK_RESULT(ReadOffset(&section_size, "section size"));
+ read_end_ = state_.offset + section_size;
if (section_code >= kBinarySectionCount) {
- RAISE_ERROR("invalid section code: %u; max is %u", section_code,
- kBinarySectionCount - 1);
+ PrintError("invalid section code: %u; max is %u", section_code,
+ kBinarySectionCount - 1);
+ return Result::Error;
}
BinarySection section = static_cast<BinarySection>(section_code);
- if (ctx->read_end > ctx->state.size)
- RAISE_ERROR("invalid section size: extends past end");
+ ERROR_UNLESS(read_end_ <= state_.size,
+ "invalid section size: extends past end");
- if (ctx->last_known_section != BinarySection::Invalid &&
- section != BinarySection::Custom &&
- section <= ctx->last_known_section) {
- RAISE_ERROR("section %s out of order", get_section_name(section));
- }
+ ERROR_UNLESS(last_known_section_ == BinarySection::Invalid ||
+ section == BinarySection::Custom ||
+ section > last_known_section_,
+ "section %s out of order", get_section_name(section));
CALLBACK(BeginSection, section, section_size);
-#define V(Name, name, code) \
- case BinarySection::Name: \
- read_##name##_section(ctx, section_size); \
+#define V(Name, name, code) \
+ case BinarySection::Name: \
+ CHECK_RESULT(Read##Name##Section(section_size)); \
break;
switch (section) {
@@ -1409,50 +1494,40 @@ static void read_sections(Context* ctx) {
#undef V
- if (ctx->state.offset != ctx->read_end) {
- RAISE_ERROR("unfinished section (expected end: 0x%" PRIzx ")",
- ctx->read_end);
- }
+ ERROR_UNLESS(state_.offset == read_end_,
+ "unfinished section (expected end: 0x%" PRIzx ")", read_end_);
if (section != BinarySection::Custom)
- ctx->last_known_section = section;
+ last_known_section_ = section;
}
+ return Result::Ok;
}
-Result read_binary(const void* data,
- size_t size,
- BinaryReader* reader,
- const ReadBinaryOptions* options) {
- BinaryReaderLogging logging_reader(options->log_stream, reader);
- Context context;
- /* all the macros assume a Context* named ctx */
- Context* ctx = &context;
- ctx->state.data = static_cast<const uint8_t*>(data);
- ctx->state.size = ctx->read_end = size;
- ctx->state.offset = 0;
- ctx->reader = options->log_stream ? &logging_reader : reader;
- ctx->options = options;
- ctx->last_known_section = BinarySection::Invalid;
-
- if (setjmp(ctx->error_jmp_buf) == 1) {
- return Result::Error;
- }
-
- ctx->reader->OnSetState(&ctx->state);
-
- uint32_t magic;
- in_u32(ctx, &magic, "magic");
- RAISE_ERROR_UNLESS(magic == WABT_BINARY_MAGIC, "bad magic value");
- uint32_t version;
- in_u32(ctx, &version, "version");
- RAISE_ERROR_UNLESS(version == WABT_BINARY_VERSION,
- "bad wasm file version: %#x (expected %#x)", version,
- WABT_BINARY_VERSION);
+Result BinaryReader::ReadModule() {
+ uint32_t magic = 0;
+ CHECK_RESULT(ReadU32(&magic, "magic"));
+ ERROR_UNLESS(magic == WABT_BINARY_MAGIC, "bad magic value");
+ uint32_t version = 0;
+ CHECK_RESULT(ReadU32(&version, "version"));
+ ERROR_UNLESS(version == WABT_BINARY_VERSION,
+ "bad wasm file version: %#x (expected %#x)", version,
+ WABT_BINARY_VERSION);
CALLBACK(BeginModule, version);
- read_sections(ctx);
+ CHECK_RESULT(ReadSections());
CALLBACK0(EndModule);
+
return Result::Ok;
}
+} // namespace
+
+Result read_binary(const void* data,
+ size_t size,
+ BinaryReaderDelegate* delegate,
+ const ReadBinaryOptions* options) {
+ BinaryReader reader(data, size, delegate, options);
+ return reader.ReadModule();
+}
+
} // namespace wabt