xref: /third_party/node/deps/v8/src/wasm/leb-helper.h (revision 1cb0ef41)
1// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if !V8_ENABLE_WEBASSEMBLY
6#error This header should only be included if WebAssembly is enabled.
7#endif  // !V8_ENABLE_WEBASSEMBLY
8
9#ifndef V8_WASM_LEB_HELPER_H_
10#define V8_WASM_LEB_HELPER_H_
11
12#include <cstddef>
13#include <cstdint>
14
15namespace v8 {
16namespace internal {
17namespace wasm {
18
19constexpr size_t kPaddedVarInt32Size = 5;
20constexpr size_t kMaxVarInt32Size = 5;
21constexpr size_t kMaxVarInt64Size = 10;
22
23class LEBHelper {
24 public:
25  // Write a 32-bit unsigned LEB to {dest}, updating {dest} to point after
26  // the last uint8_t written. No safety checks.
27  static void write_u32v(uint8_t** dest, uint32_t val) {
28    while (val >= 0x80) {
29      *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
30      val >>= 7;
31    }
32    *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
33  }
34
35  // Write a 32-bit signed LEB to {dest}, updating {dest} to point after
36  // the last uint8_t written. No safety checks.
37  static void write_i32v(uint8_t** dest, int32_t val) {
38    if (val >= 0) {
39      while (val >= 0x40) {  // prevent sign extension.
40        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
41        val >>= 7;
42      }
43      *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
44    } else {
45      while ((val >> 6) != -1) {
46        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
47        val >>= 7;
48      }
49      *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
50    }
51  }
52
53  // Write a 64-bit unsigned LEB to {dest}, updating {dest} to point after
54  // the last uint8_t written. No safety checks.
55  static void write_u64v(uint8_t** dest, uint64_t val) {
56    while (val >= 0x80) {
57      *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
58      val >>= 7;
59    }
60    *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
61  }
62
63  // Write a 64-bit signed LEB to {dest}, updating {dest} to point after
64  // the last uint8_t written. No safety checks.
65  static void write_i64v(uint8_t** dest, int64_t val) {
66    if (val >= 0) {
67      while (val >= 0x40) {  // prevent sign extension.
68        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
69        val >>= 7;
70      }
71      *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
72    } else {
73      while ((val >> 6) != -1) {
74        *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
75        val >>= 7;
76      }
77      *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
78    }
79  }
80
81  // TODO(titzer): move core logic for decoding LEBs from decoder.h to here.
82
83  // Compute the size of {val} if emitted as an LEB32.
84  static size_t sizeof_u32v(size_t val) {
85    size_t size = 0;
86    do {
87      size++;
88      val = val >> 7;
89    } while (val > 0);
90    return size;
91  }
92
93  // Compute the size of {val} if emitted as an LEB32.
94  static size_t sizeof_i32v(int32_t val) {
95    size_t size = 1;
96    if (val >= 0) {
97      while (val >= 0x40) {  // prevent sign extension.
98        size++;
99        val >>= 7;
100      }
101    } else {
102      while ((val >> 6) != -1) {
103        size++;
104        val >>= 7;
105      }
106    }
107    return size;
108  }
109
110  // Compute the size of {val} if emitted as an unsigned LEB64.
111  static size_t sizeof_u64v(uint64_t val) {
112    size_t size = 0;
113    do {
114      size++;
115      val = val >> 7;
116    } while (val > 0);
117    return size;
118  }
119
120  // Compute the size of {val} if emitted as a signed LEB64.
121  static size_t sizeof_i64v(int64_t val) {
122    size_t size = 1;
123    if (val >= 0) {
124      while (val >= 0x40) {  // prevent sign extension.
125        size++;
126        val >>= 7;
127      }
128    } else {
129      while ((val >> 6) != -1) {
130        size++;
131        val >>= 7;
132      }
133    }
134    return size;
135  }
136};
137
138}  // namespace wasm
139}  // namespace internal
140}  // namespace v8
141
142#endif  // V8_WASM_LEB_HELPER_H_
143