• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef V8_WASM_LEB_HELPER_H_
6 #define V8_WASM_LEB_HELPER_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 
11 namespace v8 {
12 namespace internal {
13 namespace wasm {
14 
15 constexpr size_t kPaddedVarInt32Size = 5;
16 constexpr size_t kMaxVarInt32Size = 5;
17 constexpr size_t kMaxVarInt64Size = 10;
18 
19 class LEBHelper {
20  public:
21   // Write a 32-bit unsigned LEB to {dest}, updating {dest} to point after
22   // the last uint8_t written. No safety checks.
write_u32v(uint8_t ** dest,uint32_t val)23   static void write_u32v(uint8_t** dest, uint32_t val) {
24     while (val >= 0x80) {
25       *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
26       val >>= 7;
27     }
28     *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
29   }
30 
31   // Write a 32-bit signed LEB to {dest}, updating {dest} to point after
32   // the last uint8_t written. No safety checks.
write_i32v(uint8_t ** dest,int32_t val)33   static void write_i32v(uint8_t** dest, int32_t val) {
34     if (val >= 0) {
35       while (val >= 0x40) {  // prevent sign extension.
36         *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
37         val >>= 7;
38       }
39       *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
40     } else {
41       while ((val >> 6) != -1) {
42         *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
43         val >>= 7;
44       }
45       *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
46     }
47   }
48 
49   // Write a 64-bit unsigned LEB to {dest}, updating {dest} to point after
50   // the last uint8_t written. No safety checks.
write_u64v(uint8_t ** dest,uint64_t val)51   static void write_u64v(uint8_t** dest, uint64_t val) {
52     while (val >= 0x80) {
53       *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
54       val >>= 7;
55     }
56     *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
57   }
58 
59   // Write a 64-bit signed LEB to {dest}, updating {dest} to point after
60   // the last uint8_t written. No safety checks.
write_i64v(uint8_t ** dest,int64_t val)61   static void write_i64v(uint8_t** dest, int64_t val) {
62     if (val >= 0) {
63       while (val >= 0x40) {  // prevent sign extension.
64         *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
65         val >>= 7;
66       }
67       *((*dest)++) = static_cast<uint8_t>(val & 0xFF);
68     } else {
69       while ((val >> 6) != -1) {
70         *((*dest)++) = static_cast<uint8_t>(0x80 | (val & 0x7F));
71         val >>= 7;
72       }
73       *((*dest)++) = static_cast<uint8_t>(val & 0x7F);
74     }
75   }
76 
77   // TODO(titzer): move core logic for decoding LEBs from decoder.h to here.
78 
79   // Compute the size of {val} if emitted as an LEB32.
sizeof_u32v(size_t val)80   static inline size_t sizeof_u32v(size_t val) {
81     size_t size = 0;
82     do {
83       size++;
84       val = val >> 7;
85     } while (val > 0);
86     return size;
87   }
88 
89   // Compute the size of {val} if emitted as an LEB32.
sizeof_i32v(int32_t val)90   static inline size_t sizeof_i32v(int32_t val) {
91     size_t size = 1;
92     if (val >= 0) {
93       while (val >= 0x40) {  // prevent sign extension.
94         size++;
95         val >>= 7;
96       }
97     } else {
98       while ((val >> 6) != -1) {
99         size++;
100         val >>= 7;
101       }
102     }
103     return size;
104   }
105 
106   // Compute the size of {val} if emitted as an unsigned LEB64.
sizeof_u64v(uint64_t val)107   static inline size_t sizeof_u64v(uint64_t val) {
108     size_t size = 0;
109     do {
110       size++;
111       val = val >> 7;
112     } while (val > 0);
113     return size;
114   }
115 
116   // Compute the size of {val} if emitted as a signed LEB64.
sizeof_i64v(int64_t val)117   static inline size_t sizeof_i64v(int64_t val) {
118     size_t size = 1;
119     if (val >= 0) {
120       while (val >= 0x40) {  // prevent sign extension.
121         size++;
122         val >>= 7;
123       }
124     } else {
125       while ((val >> 6) != -1) {
126         size++;
127         val >>= 7;
128       }
129     }
130     return size;
131   }
132 };
133 
134 }  // namespace wasm
135 }  // namespace internal
136 }  // namespace v8
137 
138 #endif  // V8_WASM_LEB_HELPER_H_
139