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