leb-helper.h 3.65 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_WASM_LEB_HELPER_H_
#define V8_WASM_LEB_HELPER_H_

8 9 10
#include <cstddef>
#include <cstdint>

11 12 13 14
namespace v8 {
namespace internal {
namespace wasm {

15 16 17
constexpr size_t kPaddedVarInt32Size = 5;
constexpr size_t kMaxVarInt32Size = 5;
constexpr size_t kMaxVarInt64Size = 10;
18

19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
class LEBHelper {
 public:
  // Write a 32-bit unsigned LEB to {dest}, updating {dest} to point after
  // the last uint8_t written. No safety checks.
  static void write_u32v(uint8_t** dest, uint32_t val) {
    while (val >= 0x80) {
      *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
      val >>= 7;
    }
    *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
  }

  // Write a 32-bit signed LEB to {dest}, updating {dest} to point after
  // the last uint8_t written. No safety checks.
  static void write_i32v(uint8_t** dest, int32_t val) {
    if (val >= 0) {
      while (val >= 0x40) {  // prevent sign extension.
        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
        val >>= 7;
      }
      *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
    } else {
      while ((val >> 6) != -1) {
        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
        val >>= 7;
      }
      *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
    }
  }

  // Write a 64-bit unsigned LEB to {dest}, updating {dest} to point after
  // the last uint8_t written. No safety checks.
  static void write_u64v(uint8_t** dest, uint64_t val) {
    while (val >= 0x80) {
      *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
      val >>= 7;
    }
    *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
  }

  // Write a 64-bit signed LEB to {dest}, updating {dest} to point after
  // the last uint8_t written. No safety checks.
  static void write_i64v(uint8_t** dest, int64_t val) {
    if (val >= 0) {
      while (val >= 0x40) {  // prevent sign extension.
        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
        val >>= 7;
      }
      *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
    } else {
      while ((val >> 6) != -1) {
        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
        val >>= 7;
      }
      *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
    }
  }

  // TODO(titzer): move core logic for decoding LEBs from decoder.h to here.

  // Compute the size of {val} if emitted as an LEB32.
  static inline size_t sizeof_u32v(size_t val) {
    size_t size = 0;
    do {
      size++;
      val = val >> 7;
    } while (val > 0);
    return size;
  }

  // Compute the size of {val} if emitted as an LEB32.
  static inline size_t sizeof_i32v(int32_t val) {
    size_t size = 1;
    if (val >= 0) {
      while (val >= 0x40) {  // prevent sign extension.
        size++;
        val >>= 7;
      }
    } else {
      while ((val >> 6) != -1) {
        size++;
        val >>= 7;
      }
    }
    return size;
  }

  // Compute the size of {val} if emitted as an unsigned LEB64.
  static inline size_t sizeof_u64v(uint64_t val) {
    size_t size = 0;
    do {
      size++;
      val = val >> 7;
    } while (val > 0);
    return size;
  }

  // Compute the size of {val} if emitted as a signed LEB64.
  static inline size_t sizeof_i64v(int64_t val) {
    size_t size = 1;
    if (val >= 0) {
      while (val >= 0x40) {  // prevent sign extension.
        size++;
        val >>= 7;
      }
    } else {
      while ((val >> 6) != -1) {
        size++;
        val >>= 7;
      }
    }
    return size;
  }
};

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_LEB_HELPER_H_