wasm-value.h 4.08 KB
Newer Older
1 2 3 4
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#ifndef V8_WASM_WASM_VALUE_H_
#define V8_WASM_WASM_VALUE_H_
7

8
#include "src/boxed-float.h"
9
#include "src/v8memory.h"
10 11 12 13 14 15 16
#include "src/wasm/wasm-opcodes.h"
#include "src/zone/zone-containers.h"

namespace v8 {
namespace internal {
namespace wasm {

17 18 19 20 21
#define FOREACH_SIMD_TYPE(V) \
  V(float, float4, f32x4, 4) \
  V(int32_t, int4, i32x4, 4) \
  V(int16_t, int8, i16x8, 8) \
  V(int8_t, int16, i8x16, 16)
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

#define DEFINE_SIMD_TYPE(cType, sType, name, kSize) \
  struct sType {                                    \
    cType val[kSize];                               \
  };
FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE)
#undef DEFINE_SIMD_TYPE

class Simd128 {
 public:
  Simd128() : val_() {
    for (size_t i = 0; i < 16; i++) {
      val_[i] = 0;
    }
  }
#define DEFINE_SIMD_TYPE_SPECIFIC_METHODS(cType, sType, name, size)    \
  explicit Simd128(sType val) {                                        \
    WriteUnalignedValue<sType>(reinterpret_cast<Address>(val_), val);  \
  }                                                                    \
  sType to_##name() {                                                  \
    return ReadUnalignedValue<sType>(reinterpret_cast<Address>(val_)); \
  }
  FOREACH_SIMD_TYPE(DEFINE_SIMD_TYPE_SPECIFIC_METHODS)
#undef DEFINE_SIMD_TYPE_SPECIFIC_METHODS

 private:
  uint8_t val_[16];
};

51 52 53 54 55
// Macro for defining WasmValue methods for different types.
// Elements:
// - name (for to_<name>() method)
// - wasm type
// - c type
56 57 58 59 60 61 62 63 64 65
#define FOREACH_WASMVAL_TYPE(V)   \
  V(i32, kWasmI32, int32_t)       \
  V(u32, kWasmI32, uint32_t)      \
  V(i64, kWasmI64, int64_t)       \
  V(u64, kWasmI64, uint64_t)      \
  V(f32, kWasmF32, float)         \
  V(f32_boxed, kWasmF32, Float32) \
  V(f64, kWasmF64, double)        \
  V(f64_boxed, kWasmF64, Float64) \
  V(s128, kWasmS128, Simd128)
66 67 68 69

// A wasm value with type information.
class WasmValue {
 public:
70 71 72 73 74 75 76 77 78 79 80 81 82 83
  WasmValue() : type_(kWasmStmt), bit_pattern_{} {}

#define DEFINE_TYPE_SPECIFIC_METHODS(name, localtype, ctype)                   \
  explicit WasmValue(ctype v) : type_(localtype), bit_pattern_{} {             \
    static_assert(sizeof(ctype) <= sizeof(bit_pattern_),                       \
                  "size too big for WasmValue");                               \
    WriteUnalignedValue<ctype>(reinterpret_cast<Address>(bit_pattern_), v);    \
  }                                                                            \
  ctype to_##name() const {                                                    \
    DCHECK_EQ(localtype, type_);                                               \
    return to_##name##_unchecked();                                            \
  }                                                                            \
  ctype to_##name##_unchecked() const {                                        \
    return ReadUnalignedValue<ctype>(reinterpret_cast<Address>(bit_pattern_)); \
84
  }
85
  FOREACH_WASMVAL_TYPE(DEFINE_TYPE_SPECIFIC_METHODS)
86 87 88 89
#undef DEFINE_TYPE_SPECIFIC_METHODS

  ValueType type() const { return type_; }

90
  // Checks equality of type and bit pattern (also for float and double values).
91
  bool operator==(const WasmValue& other) const {
92 93
    return type_ == other.type_ &&
           !memcmp(bit_pattern_, other.bit_pattern_, 16);
94 95 96
  }

  template <typename T>
97
  inline T to() const;
98 99

  template <typename T>
100
  inline T to_unchecked() const;
101 102 103

 private:
  ValueType type_;
104
  uint8_t bit_pattern_[16];
105 106
};

107 108 109
#define DECLARE_CAST(name, localtype, ctype, ...) \
  template <>                                     \
  inline ctype WasmValue::to_unchecked() const {  \
110
    return to_##name##_unchecked();               \
111 112 113
  }                                               \
  template <>                                     \
  inline ctype WasmValue::to() const {            \
114
    return to_##name();                           \
115
  }
116
FOREACH_WASMVAL_TYPE(DECLARE_CAST)
117 118 119 120 121 122
#undef DECLARE_CAST

}  // namespace wasm
}  // namespace internal
}  // namespace v8

123
#endif  // V8_WASM_WASM_VALUE_H_