diff options
author | Ben Smith <binjimin@gmail.com> | 2017-09-22 00:55:44 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-22 00:55:44 -0700 |
commit | 6b59c48cfcd28062836d7ace77c3d9cc0b3e18a9 (patch) | |
tree | b19188b67b80e1a321563f2df8bb7e8d4c7ca03b /src/binary-reader.cc | |
parent | cc79eb62915517ef899c8f2e32619cb0ae1ecde9 (diff) | |
download | wabt-6b59c48cfcd28062836d7ace77c3d9cc0b3e18a9.tar.gz wabt-6b59c48cfcd28062836d7ace77c3d9cc0b3e18a9.tar.bz2 wabt-6b59c48cfcd28062836d7ace77c3d9cc0b3e18a9.zip |
Move Leb128 reading functions to leb128.cc (#635)
Diffstat (limited to 'src/binary-reader.cc')
-rw-r--r-- | src/binary-reader.cc | 177 |
1 files changed, 15 insertions, 162 deletions
diff --git a/src/binary-reader.cc b/src/binary-reader.cc index f9eaeacd..895518a4 100644 --- a/src/binary-reader.cc +++ b/src/binary-reader.cc @@ -28,6 +28,7 @@ #include "src/binary.h" #include "src/binary-reader-logging.h" +#include "src/leb128.h" #include "src/stream.h" #include "src/utf8.h" @@ -59,89 +60,6 @@ namespace wabt { -#define BYTE_AT(type, i, shift) ((static_cast<type>(p[i]) & 0x7f) << (shift)) - -#define LEB128_1(type) (BYTE_AT(type, 0, 0)) -#define LEB128_2(type) (BYTE_AT(type, 1, 7) | LEB128_1(type)) -#define LEB128_3(type) (BYTE_AT(type, 2, 14) | LEB128_2(type)) -#define LEB128_4(type) (BYTE_AT(type, 3, 21) | LEB128_3(type)) -#define LEB128_5(type) (BYTE_AT(type, 4, 28) | LEB128_4(type)) -#define LEB128_6(type) (BYTE_AT(type, 5, 35) | LEB128_5(type)) -#define LEB128_7(type) (BYTE_AT(type, 6, 42) | LEB128_6(type)) -#define LEB128_8(type) (BYTE_AT(type, 7, 49) | LEB128_7(type)) -#define LEB128_9(type) (BYTE_AT(type, 8, 56) | LEB128_8(type)) -#define LEB128_10(type) (BYTE_AT(type, 9, 63) | LEB128_9(type)) - -#define SHIFT_AMOUNT(type, sign_bit) (sizeof(type) * 8 - 1 - (sign_bit)) -#define SIGN_EXTEND(type, value, sign_bit) \ - (static_cast<type>((value) << SHIFT_AMOUNT(type, sign_bit)) >> \ - SHIFT_AMOUNT(type, sign_bit)) - -// TODO(binji): move LEB functions elsewhere -size_t ReadU32Leb128(const uint8_t* p, - const uint8_t* end, - uint32_t* out_value) { - if (p < end && (p[0] & 0x80) == 0) { - *out_value = LEB128_1(uint32_t); - return 1; - } else if (p + 1 < end && (p[1] & 0x80) == 0) { - *out_value = LEB128_2(uint32_t); - return 2; - } else if (p + 2 < end && (p[2] & 0x80) == 0) { - *out_value = LEB128_3(uint32_t); - return 3; - } else if (p + 3 < end && (p[3] & 0x80) == 0) { - *out_value = LEB128_4(uint32_t); - return 4; - } else if (p + 4 < end && (p[4] & 0x80) == 0) { - /* the top bits set represent values > 32 bits */ - if (p[4] & 0xf0) - return 0; - *out_value = LEB128_5(uint32_t); - return 5; - } else { - /* past the end */ - *out_value = 0; - return 0; - } -} - -size_t ReadI32Leb128(const uint8_t* p, - const uint8_t* end, - uint32_t* out_value) { - if (p < end && (p[0] & 0x80) == 0) { - uint32_t result = LEB128_1(uint32_t); - *out_value = SIGN_EXTEND(int32_t, result, 6); - return 1; - } else if (p + 1 < end && (p[1] & 0x80) == 0) { - uint32_t result = LEB128_2(uint32_t); - *out_value = SIGN_EXTEND(int32_t, result, 13); - return 2; - } else if (p + 2 < end && (p[2] & 0x80) == 0) { - uint32_t result = LEB128_3(uint32_t); - *out_value = SIGN_EXTEND(int32_t, result, 20); - return 3; - } else if (p + 3 < end && (p[3] & 0x80) == 0) { - uint32_t result = LEB128_4(uint32_t); - *out_value = SIGN_EXTEND(int32_t, result, 27); - return 4; - } else if (p + 4 < end && (p[4] & 0x80) == 0) { - /* the top bits should be a sign-extension of the sign bit */ - bool sign_bit_set = (p[4] & 0x8); - int top_bits = p[4] & 0xf0; - if ((sign_bit_set && top_bits != 0x70) || - (!sign_bit_set && top_bits != 0)) { - return 0; - } - uint32_t result = LEB128_5(uint32_t); - *out_value = result; - return 5; - } else { - /* past the end */ - return 0; - } -} - namespace { class BinaryReader { @@ -161,8 +79,8 @@ class BinaryReader { 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 ReadS32Leb128(uint32_t* out_value, const char* desc) WABT_WARN_UNUSED; + Result ReadS64Leb128(uint64_t* out_value, const char* desc) WABT_WARN_UNUSED; Result ReadType(Type* out_value, const char* desc) WABT_WARN_UNUSED; Result ReadStr(string_view* out_str, const char* desc) WABT_WARN_UNUSED; Result ReadBytes(const void** out_data, @@ -317,92 +235,27 @@ Result BinaryReader::ReadU32Leb128(uint32_t* out_value, const char* desc) { return Result::Ok; } -Result BinaryReader::ReadI32Leb128(uint32_t* out_value, const char* desc) { +Result BinaryReader::ReadS32Leb128(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 = wabt::ReadI32Leb128(p, end, out_value); + size_t bytes_read = wabt::ReadS32Leb128(p, end, out_value); ERROR_UNLESS(bytes_read > 0, "unable to read i32 leb128: %s", desc); state_.offset += bytes_read; return Result::Ok; } -Result BinaryReader::ReadI64Leb128(uint64_t* out_value, const char* desc) { +Result BinaryReader::ReadS64Leb128(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); - 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); - 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); - 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); - 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); - 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); - 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); - 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); - 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); - 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)) { - PrintError("invalid i64 leb128: %s", desc); - return Result::Error; - } - uint64_t result = LEB128_10(uint64_t); - *out_value = result; - state_.offset += 10; - } else { - /* past the end */ - PrintError("unable to read i64 leb128: %s", desc); - return Result::Error; - } + size_t bytes_read = wabt::ReadS64Leb128(p, end, out_value); + ERROR_UNLESS(bytes_read > 0, "unable to read i64 leb128: %s", desc); + state_.offset += bytes_read; return Result::Ok; } -#undef BYTE_AT -#undef LEB128_1 -#undef LEB128_2 -#undef LEB128_3 -#undef LEB128_4 -#undef LEB128_5 -#undef LEB128_6 -#undef LEB128_7 -#undef LEB128_8 -#undef LEB128_9 -#undef LEB128_10 -#undef SHIFT_AMOUNT -#undef SIGN_EXTEND - Result BinaryReader::ReadType(Type* out_value, const char* desc) { uint32_t type = 0; - CHECK_RESULT(ReadI32Leb128(&type, desc)); + CHECK_RESULT(ReadS32Leb128(&type, desc)); /* Must be in the vs7 range: [-128, 127). */ ERROR_UNLESS( static_cast<int32_t>(type) >= -128 && static_cast<int32_t>(type) <= 127, @@ -504,14 +357,14 @@ Result BinaryReader::ReadInitExpr(Index index, bool require_i32) { switch (opcode) { case Opcode::I32Const: { uint32_t value = 0; - CHECK_RESULT(ReadI32Leb128(&value, "init_expr i32.const value")); + CHECK_RESULT(ReadS32Leb128(&value, "init_expr i32.const value")); CALLBACK(OnInitExprI32ConstExpr, index, value); break; } case Opcode::I64Const: { uint64_t value = 0; - CHECK_RESULT(ReadI64Leb128(&value, "init_expr i64.const value")); + CHECK_RESULT(ReadS64Leb128(&value, "init_expr i64.const value")); CALLBACK(OnInitExprI64ConstExpr, index, value); break; } @@ -738,7 +591,7 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { case Opcode::I32Const: { uint32_t value; - CHECK_RESULT(ReadI32Leb128(&value, "i32.const value")); + CHECK_RESULT(ReadS32Leb128(&value, "i32.const value")); CALLBACK(OnI32ConstExpr, value); CALLBACK(OnOpcodeUint32, value); break; @@ -746,7 +599,7 @@ Result BinaryReader::ReadFunctionBody(Offset end_offset) { case Opcode::I64Const: { uint64_t value; - CHECK_RESULT(ReadI64Leb128(&value, "i64.const value")); + CHECK_RESULT(ReadS64Leb128(&value, "i64.const value")); CALLBACK(OnI64ConstExpr, value); CALLBACK(OnOpcodeUint64, value); break; @@ -1338,7 +1191,7 @@ Result BinaryReader::ReadRelocSection(Offset section_size) { case RelocType::MemoryAddressLEB: case RelocType::MemoryAddressSLEB: case RelocType::MemoryAddressI32: - CHECK_RESULT(ReadI32Leb128(&addend, "addend")); + CHECK_RESULT(ReadS32Leb128(&addend, "addend")); break; default: break; |