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