Home | History | Annotate | Download | only in wasm
      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.
     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.
     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.
     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.
     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.
     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.
     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.
    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.
    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