summaryrefslogtreecommitdiff
path: root/src/binary-reader.cc
diff options
context:
space:
mode:
authorBen Smith <binjimin@gmail.com>2017-09-22 00:55:44 -0700
committerGitHub <noreply@github.com>2017-09-22 00:55:44 -0700
commit6b59c48cfcd28062836d7ace77c3d9cc0b3e18a9 (patch)
treeb19188b67b80e1a321563f2df8bb7e8d4c7ca03b /src/binary-reader.cc
parentcc79eb62915517ef899c8f2e32619cb0ae1ecde9 (diff)
downloadwabt-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.cc177
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;