11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#if !V8_ENABLE_WEBASSEMBLY
61cb0ef41Sopenharmony_ci#error This header should only be included if WebAssembly is enabled.
71cb0ef41Sopenharmony_ci#endif  // !V8_ENABLE_WEBASSEMBLY
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#ifndef V8_WASM_WASM_INIT_EXPR_H_
101cb0ef41Sopenharmony_ci#define V8_WASM_WASM_INIT_EXPR_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <memory>
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci#include "src/wasm/value-type.h"
151cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace v8 {
181cb0ef41Sopenharmony_cinamespace internal {
191cb0ef41Sopenharmony_cinamespace wasm {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cistruct WasmModule;
221cb0ef41Sopenharmony_ciclass WasmFeatures;
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// Representation of an initializer expression. Unlike {ConstantExpression} in
251cb0ef41Sopenharmony_ci// wasm-module.h, this does not use {WireBytesRef}, i.e., it does not depend on
261cb0ef41Sopenharmony_ci// a wasm module's bytecode representation.
271cb0ef41Sopenharmony_ciclass WasmInitExpr : public ZoneObject {
281cb0ef41Sopenharmony_ci public:
291cb0ef41Sopenharmony_ci  enum Operator {
301cb0ef41Sopenharmony_ci    kNone,
311cb0ef41Sopenharmony_ci    kGlobalGet,
321cb0ef41Sopenharmony_ci    kI32Const,
331cb0ef41Sopenharmony_ci    kI64Const,
341cb0ef41Sopenharmony_ci    kF32Const,
351cb0ef41Sopenharmony_ci    kF64Const,
361cb0ef41Sopenharmony_ci    kS128Const,
371cb0ef41Sopenharmony_ci    kRefNullConst,
381cb0ef41Sopenharmony_ci    kRefFuncConst,
391cb0ef41Sopenharmony_ci    kStructNewWithRtt,
401cb0ef41Sopenharmony_ci    kStructNew,
411cb0ef41Sopenharmony_ci    kStructNewDefaultWithRtt,
421cb0ef41Sopenharmony_ci    kStructNewDefault,
431cb0ef41Sopenharmony_ci    kArrayInit,
441cb0ef41Sopenharmony_ci    kArrayInitStatic,
451cb0ef41Sopenharmony_ci    kRttCanon,
461cb0ef41Sopenharmony_ci  };
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  union Immediate {
491cb0ef41Sopenharmony_ci    int32_t i32_const;
501cb0ef41Sopenharmony_ci    int64_t i64_const;
511cb0ef41Sopenharmony_ci    float f32_const;
521cb0ef41Sopenharmony_ci    double f64_const;
531cb0ef41Sopenharmony_ci    std::array<uint8_t, kSimd128Size> s128_const;
541cb0ef41Sopenharmony_ci    uint32_t index;
551cb0ef41Sopenharmony_ci    HeapType::Representation heap_type;
561cb0ef41Sopenharmony_ci  };
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  WasmInitExpr() : kind_(kNone), operands_(nullptr) {
591cb0ef41Sopenharmony_ci    immediate_.i32_const = 0;
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci  explicit WasmInitExpr(int32_t v) : kind_(kI32Const), operands_(nullptr) {
621cb0ef41Sopenharmony_ci    immediate_.i32_const = v;
631cb0ef41Sopenharmony_ci  }
641cb0ef41Sopenharmony_ci  explicit WasmInitExpr(int64_t v) : kind_(kI64Const), operands_(nullptr) {
651cb0ef41Sopenharmony_ci    immediate_.i64_const = v;
661cb0ef41Sopenharmony_ci  }
671cb0ef41Sopenharmony_ci  explicit WasmInitExpr(float v) : kind_(kF32Const), operands_(nullptr) {
681cb0ef41Sopenharmony_ci    immediate_.f32_const = v;
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci  explicit WasmInitExpr(double v) : kind_(kF64Const), operands_(nullptr) {
711cb0ef41Sopenharmony_ci    immediate_.f64_const = v;
721cb0ef41Sopenharmony_ci  }
731cb0ef41Sopenharmony_ci  explicit WasmInitExpr(uint8_t v[kSimd128Size])
741cb0ef41Sopenharmony_ci      : kind_(kS128Const), operands_(nullptr) {
751cb0ef41Sopenharmony_ci    memcpy(immediate_.s128_const.data(), v, kSimd128Size);
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci
781cb0ef41Sopenharmony_ci  static WasmInitExpr GlobalGet(uint32_t index) {
791cb0ef41Sopenharmony_ci    WasmInitExpr expr;
801cb0ef41Sopenharmony_ci    expr.kind_ = kGlobalGet;
811cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
821cb0ef41Sopenharmony_ci    return expr;
831cb0ef41Sopenharmony_ci  }
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  static WasmInitExpr RefFuncConst(uint32_t index) {
861cb0ef41Sopenharmony_ci    WasmInitExpr expr;
871cb0ef41Sopenharmony_ci    expr.kind_ = kRefFuncConst;
881cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
891cb0ef41Sopenharmony_ci    return expr;
901cb0ef41Sopenharmony_ci  }
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci  static WasmInitExpr RefNullConst(HeapType::Representation heap_type) {
931cb0ef41Sopenharmony_ci    WasmInitExpr expr;
941cb0ef41Sopenharmony_ci    expr.kind_ = kRefNullConst;
951cb0ef41Sopenharmony_ci    expr.immediate_.heap_type = heap_type;
961cb0ef41Sopenharmony_ci    return expr;
971cb0ef41Sopenharmony_ci  }
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci  static WasmInitExpr StructNewWithRtt(uint32_t index,
1001cb0ef41Sopenharmony_ci                                       ZoneVector<WasmInitExpr>* elements) {
1011cb0ef41Sopenharmony_ci    WasmInitExpr expr(kStructNewWithRtt, elements);
1021cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1031cb0ef41Sopenharmony_ci    return expr;
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci  static WasmInitExpr StructNew(uint32_t index,
1071cb0ef41Sopenharmony_ci                                ZoneVector<WasmInitExpr>* elements) {
1081cb0ef41Sopenharmony_ci    WasmInitExpr expr(kStructNew, elements);
1091cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1101cb0ef41Sopenharmony_ci    return expr;
1111cb0ef41Sopenharmony_ci  }
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  static WasmInitExpr StructNewDefaultWithRtt(Zone* zone, uint32_t index,
1141cb0ef41Sopenharmony_ci                                              WasmInitExpr rtt) {
1151cb0ef41Sopenharmony_ci    WasmInitExpr expr(kStructNewDefaultWithRtt,
1161cb0ef41Sopenharmony_ci                      zone->New<ZoneVector<WasmInitExpr>>(
1171cb0ef41Sopenharmony_ci                          std::initializer_list<WasmInitExpr>{rtt}, zone));
1181cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1191cb0ef41Sopenharmony_ci    return expr;
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  static WasmInitExpr StructNewDefault(uint32_t index) {
1231cb0ef41Sopenharmony_ci    WasmInitExpr expr;
1241cb0ef41Sopenharmony_ci    expr.kind_ = kStructNewDefault;
1251cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1261cb0ef41Sopenharmony_ci    return expr;
1271cb0ef41Sopenharmony_ci  }
1281cb0ef41Sopenharmony_ci
1291cb0ef41Sopenharmony_ci  static WasmInitExpr ArrayInit(uint32_t index,
1301cb0ef41Sopenharmony_ci                                ZoneVector<WasmInitExpr>* elements) {
1311cb0ef41Sopenharmony_ci    WasmInitExpr expr(kArrayInit, elements);
1321cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1331cb0ef41Sopenharmony_ci    return expr;
1341cb0ef41Sopenharmony_ci  }
1351cb0ef41Sopenharmony_ci
1361cb0ef41Sopenharmony_ci  static WasmInitExpr ArrayInitStatic(uint32_t index,
1371cb0ef41Sopenharmony_ci                                      ZoneVector<WasmInitExpr>* elements) {
1381cb0ef41Sopenharmony_ci    WasmInitExpr expr(kArrayInitStatic, elements);
1391cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1401cb0ef41Sopenharmony_ci    return expr;
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci  static WasmInitExpr RttCanon(uint32_t index) {
1441cb0ef41Sopenharmony_ci    WasmInitExpr expr;
1451cb0ef41Sopenharmony_ci    expr.kind_ = kRttCanon;
1461cb0ef41Sopenharmony_ci    expr.immediate_.index = index;
1471cb0ef41Sopenharmony_ci    return expr;
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci
1501cb0ef41Sopenharmony_ci  Immediate immediate() const { return immediate_; }
1511cb0ef41Sopenharmony_ci  Operator kind() const { return kind_; }
1521cb0ef41Sopenharmony_ci  const ZoneVector<WasmInitExpr>* operands() const { return operands_; }
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  bool operator==(const WasmInitExpr& other) const {
1551cb0ef41Sopenharmony_ci    if (kind() != other.kind()) return false;
1561cb0ef41Sopenharmony_ci    switch (kind()) {
1571cb0ef41Sopenharmony_ci      case kNone:
1581cb0ef41Sopenharmony_ci        return true;
1591cb0ef41Sopenharmony_ci      case kGlobalGet:
1601cb0ef41Sopenharmony_ci      case kRefFuncConst:
1611cb0ef41Sopenharmony_ci      case kRttCanon:
1621cb0ef41Sopenharmony_ci        return immediate().index == other.immediate().index;
1631cb0ef41Sopenharmony_ci      case kI32Const:
1641cb0ef41Sopenharmony_ci        return immediate().i32_const == other.immediate().i32_const;
1651cb0ef41Sopenharmony_ci      case kI64Const:
1661cb0ef41Sopenharmony_ci        return immediate().i64_const == other.immediate().i64_const;
1671cb0ef41Sopenharmony_ci      case kF32Const:
1681cb0ef41Sopenharmony_ci        return immediate().f32_const == other.immediate().f32_const;
1691cb0ef41Sopenharmony_ci      case kF64Const:
1701cb0ef41Sopenharmony_ci        return immediate().f64_const == other.immediate().f64_const;
1711cb0ef41Sopenharmony_ci      case kS128Const:
1721cb0ef41Sopenharmony_ci        return immediate().s128_const == other.immediate().s128_const;
1731cb0ef41Sopenharmony_ci      case kRefNullConst:
1741cb0ef41Sopenharmony_ci        return immediate().heap_type == other.immediate().heap_type;
1751cb0ef41Sopenharmony_ci      case kStructNewWithRtt:
1761cb0ef41Sopenharmony_ci      case kStructNew:
1771cb0ef41Sopenharmony_ci      case kStructNewDefaultWithRtt:
1781cb0ef41Sopenharmony_ci      case kStructNewDefault:
1791cb0ef41Sopenharmony_ci        if (immediate().index != other.immediate().index) return false;
1801cb0ef41Sopenharmony_ci        DCHECK_EQ(operands()->size(), other.operands()->size());
1811cb0ef41Sopenharmony_ci        for (uint32_t i = 0; i < operands()->size(); i++) {
1821cb0ef41Sopenharmony_ci          if (operands()[i] != other.operands()[i]) return false;
1831cb0ef41Sopenharmony_ci        }
1841cb0ef41Sopenharmony_ci        return true;
1851cb0ef41Sopenharmony_ci      case kArrayInit:
1861cb0ef41Sopenharmony_ci      case kArrayInitStatic:
1871cb0ef41Sopenharmony_ci        if (immediate().index != other.immediate().index) return false;
1881cb0ef41Sopenharmony_ci        if (operands()->size() != other.operands()->size()) return false;
1891cb0ef41Sopenharmony_ci        for (uint32_t i = 0; i < operands()->size(); i++) {
1901cb0ef41Sopenharmony_ci          if (operands()[i] != other.operands()[i]) return false;
1911cb0ef41Sopenharmony_ci        }
1921cb0ef41Sopenharmony_ci        return true;
1931cb0ef41Sopenharmony_ci    }
1941cb0ef41Sopenharmony_ci  }
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  V8_INLINE bool operator!=(const WasmInitExpr& other) const {
1971cb0ef41Sopenharmony_ci    return !(*this == other);
1981cb0ef41Sopenharmony_ci  }
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_ci  ValueType type(const WasmModule* module,
2011cb0ef41Sopenharmony_ci                 const WasmFeatures& enabled_features) const;
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci private:
2041cb0ef41Sopenharmony_ci  WasmInitExpr(Operator kind, const ZoneVector<WasmInitExpr>* operands)
2051cb0ef41Sopenharmony_ci      : kind_(kind), operands_(operands) {}
2061cb0ef41Sopenharmony_ci  Immediate immediate_;
2071cb0ef41Sopenharmony_ci  Operator kind_;
2081cb0ef41Sopenharmony_ci  const ZoneVector<WasmInitExpr>* operands_;
2091cb0ef41Sopenharmony_ci};
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ciASSERT_TRIVIALLY_COPYABLE(WasmInitExpr);
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci}  // namespace wasm
2141cb0ef41Sopenharmony_ci}  // namespace internal
2151cb0ef41Sopenharmony_ci}  // namespace v8
2161cb0ef41Sopenharmony_ci
2171cb0ef41Sopenharmony_ci#endif  // V8_WASM_WASM_INIT_EXPR_H_
218