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