11cb0ef41Sopenharmony_ci// Copyright 2015 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_MODULE_H_
101cb0ef41Sopenharmony_ci#define V8_WASM_WASM_MODULE_H_
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <map>
131cb0ef41Sopenharmony_ci#include <memory>
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci#include "src/base/optional.h"
161cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h"
171cb0ef41Sopenharmony_ci#include "src/base/vector.h"
181cb0ef41Sopenharmony_ci#include "src/common/globals.h"
191cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
201cb0ef41Sopenharmony_ci#include "src/wasm/branch-hint-map.h"
211cb0ef41Sopenharmony_ci#include "src/wasm/signature-map.h"
221cb0ef41Sopenharmony_ci#include "src/wasm/struct-types.h"
231cb0ef41Sopenharmony_ci#include "src/wasm/wasm-constants.h"
241cb0ef41Sopenharmony_ci#include "src/wasm/wasm-init-expr.h"
251cb0ef41Sopenharmony_ci#include "src/wasm/wasm-limits.h"
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_cinamespace v8 {
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_cinamespace internal {
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciclass WasmModuleObject;
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_cinamespace wasm {
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ciusing WasmName = base::Vector<const char>;
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cistruct AsmJsOffsets;
381cb0ef41Sopenharmony_ciclass ErrorThrower;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci// Reference to a string in the wire bytes.
411cb0ef41Sopenharmony_ciclass WireBytesRef {
421cb0ef41Sopenharmony_ci public:
431cb0ef41Sopenharmony_ci  WireBytesRef() : WireBytesRef(0, 0) {}
441cb0ef41Sopenharmony_ci  WireBytesRef(uint32_t offset, uint32_t length)
451cb0ef41Sopenharmony_ci      : offset_(offset), length_(length) {
461cb0ef41Sopenharmony_ci    DCHECK_IMPLIES(offset_ == 0, length_ == 0);
471cb0ef41Sopenharmony_ci    DCHECK_LE(offset_, offset_ + length_);  // no uint32_t overflow.
481cb0ef41Sopenharmony_ci  }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  uint32_t offset() const { return offset_; }
511cb0ef41Sopenharmony_ci  uint32_t length() const { return length_; }
521cb0ef41Sopenharmony_ci  uint32_t end_offset() const { return offset_ + length_; }
531cb0ef41Sopenharmony_ci  bool is_empty() const { return length_ == 0; }
541cb0ef41Sopenharmony_ci  bool is_set() const { return offset_ != 0; }
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci private:
571cb0ef41Sopenharmony_ci  uint32_t offset_;
581cb0ef41Sopenharmony_ci  uint32_t length_;
591cb0ef41Sopenharmony_ci};
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci// Static representation of a wasm function.
621cb0ef41Sopenharmony_cistruct WasmFunction {
631cb0ef41Sopenharmony_ci  const FunctionSig* sig;  // signature of the function.
641cb0ef41Sopenharmony_ci  uint32_t func_index;     // index into the function table.
651cb0ef41Sopenharmony_ci  uint32_t sig_index;      // index into the signature table.
661cb0ef41Sopenharmony_ci  WireBytesRef code;       // code of this function.
671cb0ef41Sopenharmony_ci  // Required number of slots in a feedback vector. Marked {mutable} because
681cb0ef41Sopenharmony_ci  // this is computed late (by Liftoff compilation), when the rest of the
691cb0ef41Sopenharmony_ci  // {WasmFunction} is typically considered {const}.
701cb0ef41Sopenharmony_ci  mutable int feedback_slots;
711cb0ef41Sopenharmony_ci  bool imported;
721cb0ef41Sopenharmony_ci  bool exported;
731cb0ef41Sopenharmony_ci  bool declared;
741cb0ef41Sopenharmony_ci};
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci// A representation of a constant expression. The most common expression types
771cb0ef41Sopenharmony_ci// are hard-coded, while the rest are represented as a {WireBytesRef}.
781cb0ef41Sopenharmony_ciclass ConstantExpression {
791cb0ef41Sopenharmony_ci public:
801cb0ef41Sopenharmony_ci  enum Kind {
811cb0ef41Sopenharmony_ci    kEmpty,
821cb0ef41Sopenharmony_ci    kI32Const,
831cb0ef41Sopenharmony_ci    kRefNull,
841cb0ef41Sopenharmony_ci    kRefFunc,
851cb0ef41Sopenharmony_ci    kWireBytesRef,
861cb0ef41Sopenharmony_ci    kLastKind = kWireBytesRef
871cb0ef41Sopenharmony_ci  };
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci  union Value {
901cb0ef41Sopenharmony_ci    int32_t i32_value;
911cb0ef41Sopenharmony_ci    uint32_t index_or_offset;
921cb0ef41Sopenharmony_ci    HeapType::Representation repr;
931cb0ef41Sopenharmony_ci  };
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  ConstantExpression() : bit_field_(KindField::encode(kEmpty)) {}
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  static ConstantExpression I32Const(int32_t value) {
981cb0ef41Sopenharmony_ci    return ConstantExpression(ValueField::encode(value) |
991cb0ef41Sopenharmony_ci                              KindField::encode(kI32Const));
1001cb0ef41Sopenharmony_ci  }
1011cb0ef41Sopenharmony_ci  static ConstantExpression RefFunc(uint32_t index) {
1021cb0ef41Sopenharmony_ci    return ConstantExpression(ValueField::encode(index) |
1031cb0ef41Sopenharmony_ci                              KindField::encode(kRefFunc));
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci  static ConstantExpression RefNull(HeapType::Representation repr) {
1061cb0ef41Sopenharmony_ci    return ConstantExpression(ValueField::encode(repr) |
1071cb0ef41Sopenharmony_ci                              KindField::encode(kRefNull));
1081cb0ef41Sopenharmony_ci  }
1091cb0ef41Sopenharmony_ci  static ConstantExpression WireBytes(uint32_t offset, uint32_t length) {
1101cb0ef41Sopenharmony_ci    return ConstantExpression(OffsetField::encode(offset) |
1111cb0ef41Sopenharmony_ci                              LengthField::encode(length) |
1121cb0ef41Sopenharmony_ci                              KindField::encode(kWireBytesRef));
1131cb0ef41Sopenharmony_ci  }
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci  Kind kind() const { return KindField::decode(bit_field_); }
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  bool is_set() const { return kind() != kEmpty; }
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ci  uint32_t index() const {
1201cb0ef41Sopenharmony_ci    DCHECK_EQ(kind(), kRefFunc);
1211cb0ef41Sopenharmony_ci    return ValueField::decode(bit_field_);
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  HeapType::Representation repr() const {
1251cb0ef41Sopenharmony_ci    DCHECK_EQ(kind(), kRefNull);
1261cb0ef41Sopenharmony_ci    return static_cast<HeapType::Representation>(
1271cb0ef41Sopenharmony_ci        ValueField::decode(bit_field_));
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci  int32_t i32_value() const {
1311cb0ef41Sopenharmony_ci    DCHECK_EQ(kind(), kI32Const);
1321cb0ef41Sopenharmony_ci    return ValueField::decode(bit_field_);
1331cb0ef41Sopenharmony_ci  }
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  WireBytesRef wire_bytes_ref() const {
1361cb0ef41Sopenharmony_ci    DCHECK_EQ(kind(), kWireBytesRef);
1371cb0ef41Sopenharmony_ci    return WireBytesRef(OffsetField::decode(bit_field_),
1381cb0ef41Sopenharmony_ci                        LengthField::decode(bit_field_));
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci private:
1421cb0ef41Sopenharmony_ci  static constexpr int kValueBits = 32;
1431cb0ef41Sopenharmony_ci  static constexpr int kLengthBits = 30;
1441cb0ef41Sopenharmony_ci  static constexpr int kOffsetBits = 30;
1451cb0ef41Sopenharmony_ci  static constexpr int kKindBits = 3;
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_ci  // There are two possible combinations of fields: offset + length + kind if
1481cb0ef41Sopenharmony_ci  // kind = kWireBytesRef, or value + kind for anything else.
1491cb0ef41Sopenharmony_ci  using ValueField = base::BitField<uint32_t, 0, kValueBits, uint64_t>;
1501cb0ef41Sopenharmony_ci  using OffsetField = base::BitField<uint32_t, 0, kOffsetBits, uint64_t>;
1511cb0ef41Sopenharmony_ci  using LengthField = OffsetField::Next<uint32_t, kLengthBits>;
1521cb0ef41Sopenharmony_ci  using KindField = LengthField::Next<Kind, kKindBits>;
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  // Make sure we reserve enough bits for a {WireBytesRef}'s length and offset.
1551cb0ef41Sopenharmony_ci  STATIC_ASSERT(kV8MaxWasmModuleSize <= LengthField::kMax + 1);
1561cb0ef41Sopenharmony_ci  STATIC_ASSERT(kV8MaxWasmModuleSize <= OffsetField::kMax + 1);
1571cb0ef41Sopenharmony_ci  // Make sure kind fits in kKindBits.
1581cb0ef41Sopenharmony_ci  STATIC_ASSERT(kLastKind <= KindField::kMax + 1);
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci  explicit ConstantExpression(uint64_t bit_field) : bit_field_(bit_field) {}
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  uint64_t bit_field_;
1631cb0ef41Sopenharmony_ci};
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci// We want to keep {ConstantExpression} small to reduce memory usage during
1661cb0ef41Sopenharmony_ci// compilation/instantiation.
1671cb0ef41Sopenharmony_ciSTATIC_ASSERT(sizeof(ConstantExpression) <= 8);
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci// Static representation of a wasm global variable.
1701cb0ef41Sopenharmony_cistruct WasmGlobal {
1711cb0ef41Sopenharmony_ci  ValueType type;           // type of the global.
1721cb0ef41Sopenharmony_ci  bool mutability;          // {true} if mutable.
1731cb0ef41Sopenharmony_ci  ConstantExpression init;  // the initialization expression of the global.
1741cb0ef41Sopenharmony_ci  union {
1751cb0ef41Sopenharmony_ci    // Index of imported mutable global.
1761cb0ef41Sopenharmony_ci    uint32_t index;
1771cb0ef41Sopenharmony_ci    // Offset into global memory (if not imported & mutable). Expressed in bytes
1781cb0ef41Sopenharmony_ci    // for value-typed globals, and in tagged words for reference-typed globals.
1791cb0ef41Sopenharmony_ci    uint32_t offset;
1801cb0ef41Sopenharmony_ci  };
1811cb0ef41Sopenharmony_ci  bool imported;  // true if imported.
1821cb0ef41Sopenharmony_ci  bool exported;  // true if exported.
1831cb0ef41Sopenharmony_ci};
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci// Note: An exception tag signature only uses the params portion of a function
1861cb0ef41Sopenharmony_ci// signature.
1871cb0ef41Sopenharmony_ciusing WasmTagSig = FunctionSig;
1881cb0ef41Sopenharmony_ci
1891cb0ef41Sopenharmony_ci// Static representation of a wasm tag type.
1901cb0ef41Sopenharmony_cistruct WasmTag {
1911cb0ef41Sopenharmony_ci  explicit WasmTag(const WasmTagSig* sig) : sig(sig) {}
1921cb0ef41Sopenharmony_ci  const FunctionSig* ToFunctionSig() const { return sig; }
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ci  const WasmTagSig* sig;  // type signature of the tag.
1951cb0ef41Sopenharmony_ci};
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci// Static representation of a wasm data segment.
1981cb0ef41Sopenharmony_cistruct WasmDataSegment {
1991cb0ef41Sopenharmony_ci  // Construct an active segment.
2001cb0ef41Sopenharmony_ci  explicit WasmDataSegment(ConstantExpression dest_addr)
2011cb0ef41Sopenharmony_ci      : dest_addr(dest_addr), active(true) {}
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  // Construct a passive segment, which has no dest_addr.
2041cb0ef41Sopenharmony_ci  WasmDataSegment() : active(false) {}
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  ConstantExpression dest_addr;  // destination memory address of the data.
2071cb0ef41Sopenharmony_ci  WireBytesRef source;           // start offset in the module bytes.
2081cb0ef41Sopenharmony_ci  bool active = true;  // true if copied automatically during instantiation.
2091cb0ef41Sopenharmony_ci};
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci// Static representation of wasm element segment (table initializer).
2121cb0ef41Sopenharmony_cistruct WasmElemSegment {
2131cb0ef41Sopenharmony_ci  enum Status {
2141cb0ef41Sopenharmony_ci    kStatusActive,      // copied automatically during instantiation.
2151cb0ef41Sopenharmony_ci    kStatusPassive,     // copied explicitly after instantiation.
2161cb0ef41Sopenharmony_ci    kStatusDeclarative  // purely declarative and never copied.
2171cb0ef41Sopenharmony_ci  };
2181cb0ef41Sopenharmony_ci  enum ElementType { kFunctionIndexElements, kExpressionElements };
2191cb0ef41Sopenharmony_ci
2201cb0ef41Sopenharmony_ci  // Construct an active segment.
2211cb0ef41Sopenharmony_ci  WasmElemSegment(ValueType type, uint32_t table_index,
2221cb0ef41Sopenharmony_ci                  ConstantExpression offset, ElementType element_type)
2231cb0ef41Sopenharmony_ci      : status(kStatusActive),
2241cb0ef41Sopenharmony_ci        type(type),
2251cb0ef41Sopenharmony_ci        table_index(table_index),
2261cb0ef41Sopenharmony_ci        offset(std::move(offset)),
2271cb0ef41Sopenharmony_ci        element_type(element_type) {}
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  // Construct a passive or declarative segment, which has no table index or
2301cb0ef41Sopenharmony_ci  // offset.
2311cb0ef41Sopenharmony_ci  WasmElemSegment(ValueType type, Status status, ElementType element_type)
2321cb0ef41Sopenharmony_ci      : status(status), type(type), table_index(0), element_type(element_type) {
2331cb0ef41Sopenharmony_ci    DCHECK_NE(status, kStatusActive);
2341cb0ef41Sopenharmony_ci  }
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci  // Default constructor. Constucts an invalid segment.
2371cb0ef41Sopenharmony_ci  WasmElemSegment()
2381cb0ef41Sopenharmony_ci      : status(kStatusActive),
2391cb0ef41Sopenharmony_ci        type(kWasmBottom),
2401cb0ef41Sopenharmony_ci        table_index(0),
2411cb0ef41Sopenharmony_ci        element_type(kFunctionIndexElements) {}
2421cb0ef41Sopenharmony_ci
2431cb0ef41Sopenharmony_ci  WasmElemSegment(const WasmElemSegment&) = delete;
2441cb0ef41Sopenharmony_ci  WasmElemSegment(WasmElemSegment&&) V8_NOEXCEPT = default;
2451cb0ef41Sopenharmony_ci  WasmElemSegment& operator=(const WasmElemSegment&) = delete;
2461cb0ef41Sopenharmony_ci  WasmElemSegment& operator=(WasmElemSegment&&) V8_NOEXCEPT = default;
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci  Status status;
2491cb0ef41Sopenharmony_ci  ValueType type;
2501cb0ef41Sopenharmony_ci  uint32_t table_index;
2511cb0ef41Sopenharmony_ci  ConstantExpression offset;
2521cb0ef41Sopenharmony_ci  ElementType element_type;
2531cb0ef41Sopenharmony_ci  std::vector<ConstantExpression> entries;
2541cb0ef41Sopenharmony_ci};
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci// Static representation of a wasm import.
2571cb0ef41Sopenharmony_cistruct WasmImport {
2581cb0ef41Sopenharmony_ci  WireBytesRef module_name;   // module name.
2591cb0ef41Sopenharmony_ci  WireBytesRef field_name;    // import name.
2601cb0ef41Sopenharmony_ci  ImportExportKindCode kind;  // kind of the import.
2611cb0ef41Sopenharmony_ci  uint32_t index;             // index into the respective space.
2621cb0ef41Sopenharmony_ci};
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ci// Static representation of a wasm export.
2651cb0ef41Sopenharmony_cistruct WasmExport {
2661cb0ef41Sopenharmony_ci  WireBytesRef name;          // exported name.
2671cb0ef41Sopenharmony_ci  ImportExportKindCode kind;  // kind of the export.
2681cb0ef41Sopenharmony_ci  uint32_t index;             // index into the respective space.
2691cb0ef41Sopenharmony_ci};
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_cienum class WasmCompilationHintStrategy : uint8_t {
2721cb0ef41Sopenharmony_ci  kDefault = 0,
2731cb0ef41Sopenharmony_ci  kLazy = 1,
2741cb0ef41Sopenharmony_ci  kEager = 2,
2751cb0ef41Sopenharmony_ci  kLazyBaselineEagerTopTier = 3,
2761cb0ef41Sopenharmony_ci};
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_cienum class WasmCompilationHintTier : uint8_t {
2791cb0ef41Sopenharmony_ci  kDefault = 0,
2801cb0ef41Sopenharmony_ci  kBaseline = 1,
2811cb0ef41Sopenharmony_ci  kOptimized = 2,
2821cb0ef41Sopenharmony_ci};
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci// Static representation of a wasm compilation hint
2851cb0ef41Sopenharmony_cistruct WasmCompilationHint {
2861cb0ef41Sopenharmony_ci  WasmCompilationHintStrategy strategy;
2871cb0ef41Sopenharmony_ci  WasmCompilationHintTier baseline_tier;
2881cb0ef41Sopenharmony_ci  WasmCompilationHintTier top_tier;
2891cb0ef41Sopenharmony_ci};
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_cienum ModuleOrigin : uint8_t {
2921cb0ef41Sopenharmony_ci  kWasmOrigin,
2931cb0ef41Sopenharmony_ci  kAsmJsSloppyOrigin,
2941cb0ef41Sopenharmony_ci  kAsmJsStrictOrigin
2951cb0ef41Sopenharmony_ci};
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci#define SELECT_WASM_COUNTER(counters, origin, prefix, suffix)     \
2981cb0ef41Sopenharmony_ci  ((origin) == kWasmOrigin ? (counters)->prefix##_wasm_##suffix() \
2991cb0ef41Sopenharmony_ci                           : (counters)->prefix##_asm_##suffix())
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_cistruct ModuleWireBytes;
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE LazilyGeneratedNames {
3041cb0ef41Sopenharmony_ci public:
3051cb0ef41Sopenharmony_ci  WireBytesRef LookupFunctionName(const ModuleWireBytes& wire_bytes,
3061cb0ef41Sopenharmony_ci                                  uint32_t function_index) const;
3071cb0ef41Sopenharmony_ci
3081cb0ef41Sopenharmony_ci  void AddForTesting(int function_index, WireBytesRef name);
3091cb0ef41Sopenharmony_ci
3101cb0ef41Sopenharmony_ci private:
3111cb0ef41Sopenharmony_ci  // {function_names_} are populated lazily after decoding, and
3121cb0ef41Sopenharmony_ci  // therefore need a mutex to protect concurrent modifications
3131cb0ef41Sopenharmony_ci  // from multiple {WasmModuleObject}.
3141cb0ef41Sopenharmony_ci  mutable base::Mutex mutex_;
3151cb0ef41Sopenharmony_ci  mutable std::unique_ptr<std::unordered_map<uint32_t, WireBytesRef>>
3161cb0ef41Sopenharmony_ci      function_names_;
3171cb0ef41Sopenharmony_ci};
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE AsmJsOffsetInformation {
3201cb0ef41Sopenharmony_ci public:
3211cb0ef41Sopenharmony_ci  explicit AsmJsOffsetInformation(base::Vector<const byte> encoded_offsets);
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  // Destructor defined in wasm-module.cc, where the definition of
3241cb0ef41Sopenharmony_ci  // {AsmJsOffsets} is available.
3251cb0ef41Sopenharmony_ci  ~AsmJsOffsetInformation();
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ci  int GetSourcePosition(int func_index, int byte_offset,
3281cb0ef41Sopenharmony_ci                        bool is_at_number_conversion);
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci  std::pair<int, int> GetFunctionOffsets(int func_index);
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci private:
3331cb0ef41Sopenharmony_ci  void EnsureDecodedOffsets();
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  // The offset information table is decoded lazily, hence needs to be
3361cb0ef41Sopenharmony_ci  // protected against concurrent accesses.
3371cb0ef41Sopenharmony_ci  // Exactly one of the two fields below will be set at a time.
3381cb0ef41Sopenharmony_ci  mutable base::Mutex mutex_;
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci  // Holds the encoded offset table bytes.
3411cb0ef41Sopenharmony_ci  base::OwnedVector<const uint8_t> encoded_offsets_;
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  // Holds the decoded offset table.
3441cb0ef41Sopenharmony_ci  std::unique_ptr<AsmJsOffsets> decoded_offsets_;
3451cb0ef41Sopenharmony_ci};
3461cb0ef41Sopenharmony_ci
3471cb0ef41Sopenharmony_ci// Used as the supertype for a type at the top of the type hierarchy.
3481cb0ef41Sopenharmony_ciconstexpr uint32_t kNoSuperType = std::numeric_limits<uint32_t>::max();
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_cistruct TypeDefinition {
3511cb0ef41Sopenharmony_ci  enum Kind { kFunction, kStruct, kArray };
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ci  TypeDefinition(const FunctionSig* sig, uint32_t supertype)
3541cb0ef41Sopenharmony_ci      : function_sig(sig), supertype(supertype), kind(kFunction) {}
3551cb0ef41Sopenharmony_ci  TypeDefinition(const StructType* type, uint32_t supertype)
3561cb0ef41Sopenharmony_ci      : struct_type(type), supertype(supertype), kind(kStruct) {}
3571cb0ef41Sopenharmony_ci  TypeDefinition(const ArrayType* type, uint32_t supertype)
3581cb0ef41Sopenharmony_ci      : array_type(type), supertype(supertype), kind(kArray) {}
3591cb0ef41Sopenharmony_ci  TypeDefinition()
3601cb0ef41Sopenharmony_ci      : function_sig(nullptr), supertype(kNoSuperType), kind(kFunction) {}
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci  union {
3631cb0ef41Sopenharmony_ci    const FunctionSig* function_sig;
3641cb0ef41Sopenharmony_ci    const StructType* struct_type;
3651cb0ef41Sopenharmony_ci    const ArrayType* array_type;
3661cb0ef41Sopenharmony_ci  };
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci  bool operator==(const TypeDefinition& other) const {
3691cb0ef41Sopenharmony_ci    if (supertype != other.supertype || kind != other.kind) {
3701cb0ef41Sopenharmony_ci      return false;
3711cb0ef41Sopenharmony_ci    }
3721cb0ef41Sopenharmony_ci    switch (kind) {
3731cb0ef41Sopenharmony_ci      case kFunction:
3741cb0ef41Sopenharmony_ci        return *function_sig == *other.function_sig;
3751cb0ef41Sopenharmony_ci      case kStruct:
3761cb0ef41Sopenharmony_ci        return *struct_type == *other.struct_type;
3771cb0ef41Sopenharmony_ci      case kArray:
3781cb0ef41Sopenharmony_ci        return *array_type == *other.array_type;
3791cb0ef41Sopenharmony_ci    }
3801cb0ef41Sopenharmony_ci  }
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  bool operator!=(const TypeDefinition& other) const {
3831cb0ef41Sopenharmony_ci    return !(*this == other);
3841cb0ef41Sopenharmony_ci  }
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci  uint32_t supertype;
3871cb0ef41Sopenharmony_ci  Kind kind;
3881cb0ef41Sopenharmony_ci};
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_cistruct V8_EXPORT_PRIVATE WasmDebugSymbols {
3911cb0ef41Sopenharmony_ci  enum class Type { None, SourceMap, EmbeddedDWARF, ExternalDWARF };
3921cb0ef41Sopenharmony_ci  Type type = Type::None;
3931cb0ef41Sopenharmony_ci  WireBytesRef external_url;
3941cb0ef41Sopenharmony_ci};
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_cistruct CallSiteFeedback {
3971cb0ef41Sopenharmony_ci  int function_index;
3981cb0ef41Sopenharmony_ci  int absolute_call_frequency;
3991cb0ef41Sopenharmony_ci};
4001cb0ef41Sopenharmony_cistruct FunctionTypeFeedback {
4011cb0ef41Sopenharmony_ci  std::vector<CallSiteFeedback> feedback_vector;
4021cb0ef41Sopenharmony_ci  std::map<WasmCodePosition, int> positions;
4031cb0ef41Sopenharmony_ci  int tierup_priority = 0;
4041cb0ef41Sopenharmony_ci};
4051cb0ef41Sopenharmony_cistruct TypeFeedbackStorage {
4061cb0ef41Sopenharmony_ci  std::map<uint32_t, FunctionTypeFeedback> feedback_for_function;
4071cb0ef41Sopenharmony_ci  // Accesses to {feedback_for_function} are guarded by this mutex.
4081cb0ef41Sopenharmony_ci  base::Mutex mutex;
4091cb0ef41Sopenharmony_ci};
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_cistruct WasmTable;
4121cb0ef41Sopenharmony_ci
4131cb0ef41Sopenharmony_ci// Static representation of a module.
4141cb0ef41Sopenharmony_cistruct V8_EXPORT_PRIVATE WasmModule {
4151cb0ef41Sopenharmony_ci  std::unique_ptr<Zone> signature_zone;
4161cb0ef41Sopenharmony_ci  uint32_t initial_pages = 0;      // initial size of the memory in 64k pages
4171cb0ef41Sopenharmony_ci  uint32_t maximum_pages = 0;      // maximum size of the memory in 64k pages
4181cb0ef41Sopenharmony_ci  bool has_shared_memory = false;  // true if memory is a SharedArrayBuffer
4191cb0ef41Sopenharmony_ci  bool has_maximum_pages = false;  // true if there is a maximum memory size
4201cb0ef41Sopenharmony_ci  bool is_memory64 = false;        // true if the memory is 64 bit
4211cb0ef41Sopenharmony_ci  bool has_memory = false;         // true if the memory was defined or imported
4221cb0ef41Sopenharmony_ci  bool mem_export = false;         // true if the memory is exported
4231cb0ef41Sopenharmony_ci  int start_function_index = -1;   // start function, >= 0 if any
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ci  // Size of the buffer required for all globals that are not imported and
4261cb0ef41Sopenharmony_ci  // mutable.
4271cb0ef41Sopenharmony_ci  uint32_t untagged_globals_buffer_size = 0;
4281cb0ef41Sopenharmony_ci  uint32_t tagged_globals_buffer_size = 0;
4291cb0ef41Sopenharmony_ci  uint32_t num_imported_mutable_globals = 0;
4301cb0ef41Sopenharmony_ci  uint32_t num_imported_functions = 0;
4311cb0ef41Sopenharmony_ci  uint32_t num_imported_tables = 0;
4321cb0ef41Sopenharmony_ci  uint32_t num_declared_functions = 0;  // excluding imported
4331cb0ef41Sopenharmony_ci  uint32_t num_exported_functions = 0;
4341cb0ef41Sopenharmony_ci  uint32_t num_declared_data_segments = 0;  // From the DataCount section.
4351cb0ef41Sopenharmony_ci  // Position and size of the code section (payload only, i.e. without section
4361cb0ef41Sopenharmony_ci  // ID and length).
4371cb0ef41Sopenharmony_ci  WireBytesRef code = {0, 0};
4381cb0ef41Sopenharmony_ci  WireBytesRef name = {0, 0};
4391cb0ef41Sopenharmony_ci
4401cb0ef41Sopenharmony_ci  void add_type(TypeDefinition type) {
4411cb0ef41Sopenharmony_ci    types.push_back(type);
4421cb0ef41Sopenharmony_ci    uint32_t canonical_id = type.kind == TypeDefinition::kFunction
4431cb0ef41Sopenharmony_ci                                ? signature_map.FindOrInsert(*type.function_sig)
4441cb0ef41Sopenharmony_ci                                : 0;
4451cb0ef41Sopenharmony_ci    canonicalized_type_ids.push_back(canonical_id);
4461cb0ef41Sopenharmony_ci    // Canonical type will be computed later.
4471cb0ef41Sopenharmony_ci    isorecursive_canonical_type_ids.push_back(kNoSuperType);
4481cb0ef41Sopenharmony_ci  }
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci  bool has_type(uint32_t index) const { return index < types.size(); }
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  void add_signature(const FunctionSig* sig, uint32_t supertype) {
4531cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(sig);
4541cb0ef41Sopenharmony_ci    add_type(TypeDefinition(sig, supertype));
4551cb0ef41Sopenharmony_ci  }
4561cb0ef41Sopenharmony_ci  bool has_signature(uint32_t index) const {
4571cb0ef41Sopenharmony_ci    return index < types.size() &&
4581cb0ef41Sopenharmony_ci           types[index].kind == TypeDefinition::kFunction;
4591cb0ef41Sopenharmony_ci  }
4601cb0ef41Sopenharmony_ci  const FunctionSig* signature(uint32_t index) const {
4611cb0ef41Sopenharmony_ci    DCHECK(has_signature(index));
4621cb0ef41Sopenharmony_ci    return types[index].function_sig;
4631cb0ef41Sopenharmony_ci  }
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci  void add_struct_type(const StructType* type, uint32_t supertype) {
4661cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(type);
4671cb0ef41Sopenharmony_ci    add_type(TypeDefinition(type, supertype));
4681cb0ef41Sopenharmony_ci  }
4691cb0ef41Sopenharmony_ci  bool has_struct(uint32_t index) const {
4701cb0ef41Sopenharmony_ci    return index < types.size() && types[index].kind == TypeDefinition::kStruct;
4711cb0ef41Sopenharmony_ci  }
4721cb0ef41Sopenharmony_ci  const StructType* struct_type(uint32_t index) const {
4731cb0ef41Sopenharmony_ci    DCHECK(has_struct(index));
4741cb0ef41Sopenharmony_ci    return types[index].struct_type;
4751cb0ef41Sopenharmony_ci  }
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci  void add_array_type(const ArrayType* type, uint32_t supertype) {
4781cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(type);
4791cb0ef41Sopenharmony_ci    add_type(TypeDefinition(type, supertype));
4801cb0ef41Sopenharmony_ci  }
4811cb0ef41Sopenharmony_ci  bool has_array(uint32_t index) const {
4821cb0ef41Sopenharmony_ci    return index < types.size() && types[index].kind == TypeDefinition::kArray;
4831cb0ef41Sopenharmony_ci  }
4841cb0ef41Sopenharmony_ci  const ArrayType* array_type(uint32_t index) const {
4851cb0ef41Sopenharmony_ci    DCHECK(has_array(index));
4861cb0ef41Sopenharmony_ci    return types[index].array_type;
4871cb0ef41Sopenharmony_ci  }
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci  uint32_t supertype(uint32_t index) const {
4901cb0ef41Sopenharmony_ci    DCHECK(index < types.size());
4911cb0ef41Sopenharmony_ci    return types[index].supertype;
4921cb0ef41Sopenharmony_ci  }
4931cb0ef41Sopenharmony_ci  bool has_supertype(uint32_t index) const {
4941cb0ef41Sopenharmony_ci    return supertype(index) != kNoSuperType;
4951cb0ef41Sopenharmony_ci  }
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ci  std::vector<TypeDefinition> types;  // by type index
4981cb0ef41Sopenharmony_ci  // TODO(7748): Unify the following two arrays.
4991cb0ef41Sopenharmony_ci  // Maps each type index to a canonical index for purposes of call_indirect.
5001cb0ef41Sopenharmony_ci  std::vector<uint32_t> canonicalized_type_ids;
5011cb0ef41Sopenharmony_ci  // Maps each type index to its global (cross-module) canonical index as per
5021cb0ef41Sopenharmony_ci  // isorecursive type canonicalization.
5031cb0ef41Sopenharmony_ci  std::vector<uint32_t> isorecursive_canonical_type_ids;
5041cb0ef41Sopenharmony_ci  // Canonicalizing map for signature indexes.
5051cb0ef41Sopenharmony_ci  SignatureMap signature_map;
5061cb0ef41Sopenharmony_ci  std::vector<WasmFunction> functions;
5071cb0ef41Sopenharmony_ci  std::vector<WasmGlobal> globals;
5081cb0ef41Sopenharmony_ci  std::vector<WasmDataSegment> data_segments;
5091cb0ef41Sopenharmony_ci  std::vector<WasmTable> tables;
5101cb0ef41Sopenharmony_ci  std::vector<WasmImport> import_table;
5111cb0ef41Sopenharmony_ci  std::vector<WasmExport> export_table;
5121cb0ef41Sopenharmony_ci  std::vector<WasmTag> tags;
5131cb0ef41Sopenharmony_ci  std::vector<WasmElemSegment> elem_segments;
5141cb0ef41Sopenharmony_ci  std::vector<WasmCompilationHint> compilation_hints;
5151cb0ef41Sopenharmony_ci  BranchHintInfo branch_hints;
5161cb0ef41Sopenharmony_ci  mutable TypeFeedbackStorage type_feedback;
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  ModuleOrigin origin = kWasmOrigin;  // origin of the module
5191cb0ef41Sopenharmony_ci  LazilyGeneratedNames lazily_generated_names;
5201cb0ef41Sopenharmony_ci  WasmDebugSymbols debug_symbols;
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  // Asm.js source position information. Only available for modules compiled
5231cb0ef41Sopenharmony_ci  // from asm.js.
5241cb0ef41Sopenharmony_ci  std::unique_ptr<AsmJsOffsetInformation> asm_js_offset_information;
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci  explicit WasmModule(std::unique_ptr<Zone> signature_zone = nullptr);
5271cb0ef41Sopenharmony_ci  WasmModule(const WasmModule&) = delete;
5281cb0ef41Sopenharmony_ci  WasmModule& operator=(const WasmModule&) = delete;
5291cb0ef41Sopenharmony_ci};
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci// Static representation of a wasm indirect call table.
5321cb0ef41Sopenharmony_cistruct WasmTable {
5331cb0ef41Sopenharmony_ci  MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS(WasmTable);
5341cb0ef41Sopenharmony_ci
5351cb0ef41Sopenharmony_ci  // 'module' can be nullptr
5361cb0ef41Sopenharmony_ci  // TODO(9495): Update this function as more table types are supported, or
5371cb0ef41Sopenharmony_ci  // remove it completely when all reference types are allowed.
5381cb0ef41Sopenharmony_ci  static bool IsValidTableType(ValueType type, const WasmModule* module) {
5391cb0ef41Sopenharmony_ci    if (!type.is_object_reference()) return false;
5401cb0ef41Sopenharmony_ci    HeapType heap_type = type.heap_type();
5411cb0ef41Sopenharmony_ci    return heap_type == HeapType::kFunc || heap_type == HeapType::kAny ||
5421cb0ef41Sopenharmony_ci           (module != nullptr && heap_type.is_index() &&
5431cb0ef41Sopenharmony_ci            module->has_signature(heap_type.ref_index()));
5441cb0ef41Sopenharmony_ci  }
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ci  ValueType type = kWasmVoid;     // table type.
5471cb0ef41Sopenharmony_ci  uint32_t initial_size = 0;      // initial table size.
5481cb0ef41Sopenharmony_ci  uint32_t maximum_size = 0;      // maximum table size.
5491cb0ef41Sopenharmony_ci  bool has_maximum_size = false;  // true if there is a maximum size.
5501cb0ef41Sopenharmony_ci  bool imported = false;          // true if imported.
5511cb0ef41Sopenharmony_ci  bool exported = false;          // true if exported.
5521cb0ef41Sopenharmony_ci  ConstantExpression initial_value;
5531cb0ef41Sopenharmony_ci};
5541cb0ef41Sopenharmony_ci
5551cb0ef41Sopenharmony_ciinline bool is_asmjs_module(const WasmModule* module) {
5561cb0ef41Sopenharmony_ci  return module->origin != kWasmOrigin;
5571cb0ef41Sopenharmony_ci}
5581cb0ef41Sopenharmony_ci
5591cb0ef41Sopenharmony_cisize_t EstimateStoredSize(const WasmModule* module);
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci// Returns the number of possible export wrappers for a given module.
5621cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE int MaxNumExportWrappers(const WasmModule* module);
5631cb0ef41Sopenharmony_ci
5641cb0ef41Sopenharmony_ci// Returns the wrapper index for a function in {module} with signature {sig}
5651cb0ef41Sopenharmony_ci// or {sig_index} and origin defined by {is_import}.
5661cb0ef41Sopenharmony_ci// Prefer to use the {sig_index} consuming version, as it is much faster.
5671cb0ef41Sopenharmony_ciint GetExportWrapperIndex(const WasmModule* module, const FunctionSig* sig,
5681cb0ef41Sopenharmony_ci                          bool is_import);
5691cb0ef41Sopenharmony_ciint GetExportWrapperIndex(const WasmModule* module, uint32_t sig_index,
5701cb0ef41Sopenharmony_ci                          bool is_import);
5711cb0ef41Sopenharmony_ci
5721cb0ef41Sopenharmony_ci// Return the byte offset of the function identified by the given index.
5731cb0ef41Sopenharmony_ci// The offset will be relative to the start of the module bytes.
5741cb0ef41Sopenharmony_ci// Returns -1 if the function index is invalid.
5751cb0ef41Sopenharmony_ciint GetWasmFunctionOffset(const WasmModule* module, uint32_t func_index);
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci// Returns the function containing the given byte offset.
5781cb0ef41Sopenharmony_ci// Returns -1 if the byte offset is not contained in any
5791cb0ef41Sopenharmony_ci// function of this module.
5801cb0ef41Sopenharmony_ciint GetContainingWasmFunction(const WasmModule* module, uint32_t byte_offset);
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci// Returns the function containing the given byte offset.
5831cb0ef41Sopenharmony_ci// Will return preceding function if the byte offset is not
5841cb0ef41Sopenharmony_ci// contained within a function.
5851cb0ef41Sopenharmony_ciint GetNearestWasmFunction(const WasmModule* module, uint32_t byte_offset);
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci// Gets the explicitly defined subtyping depth for the given type.
5881cb0ef41Sopenharmony_ci// Returns 0 if the type has no explicit supertype.
5891cb0ef41Sopenharmony_ci// The result is capped to {kV8MaxRttSubtypingDepth + 1}.
5901cb0ef41Sopenharmony_ci// Invalid cyclic hierarchies will return -1.
5911cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE int GetSubtypingDepth(const WasmModule* module,
5921cb0ef41Sopenharmony_ci                                        uint32_t type_index);
5931cb0ef41Sopenharmony_ci
5941cb0ef41Sopenharmony_ci// Interface to the storage (wire bytes) of a wasm module.
5951cb0ef41Sopenharmony_ci// It is illegal for anyone receiving a ModuleWireBytes to store pointers based
5961cb0ef41Sopenharmony_ci// on module_bytes, as this storage is only guaranteed to be alive as long as
5971cb0ef41Sopenharmony_ci// this struct is alive.
5981cb0ef41Sopenharmony_cistruct V8_EXPORT_PRIVATE ModuleWireBytes {
5991cb0ef41Sopenharmony_ci  explicit ModuleWireBytes(base::Vector<const byte> module_bytes)
6001cb0ef41Sopenharmony_ci      : module_bytes_(module_bytes) {}
6011cb0ef41Sopenharmony_ci  ModuleWireBytes(const byte* start, const byte* end)
6021cb0ef41Sopenharmony_ci      : module_bytes_(start, static_cast<int>(end - start)) {
6031cb0ef41Sopenharmony_ci    DCHECK_GE(kMaxInt, end - start);
6041cb0ef41Sopenharmony_ci  }
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci  // Get a string stored in the module bytes representing a name.
6071cb0ef41Sopenharmony_ci  WasmName GetNameOrNull(WireBytesRef ref) const;
6081cb0ef41Sopenharmony_ci
6091cb0ef41Sopenharmony_ci  // Get a string stored in the module bytes representing a function name.
6101cb0ef41Sopenharmony_ci  WasmName GetNameOrNull(const WasmFunction* function,
6111cb0ef41Sopenharmony_ci                         const WasmModule* module) const;
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ci  // Checks the given reference is contained within the module bytes.
6141cb0ef41Sopenharmony_ci  bool BoundsCheck(WireBytesRef ref) const {
6151cb0ef41Sopenharmony_ci    uint32_t size = static_cast<uint32_t>(module_bytes_.length());
6161cb0ef41Sopenharmony_ci    return ref.offset() <= size && ref.length() <= size - ref.offset();
6171cb0ef41Sopenharmony_ci  }
6181cb0ef41Sopenharmony_ci
6191cb0ef41Sopenharmony_ci  base::Vector<const byte> GetFunctionBytes(
6201cb0ef41Sopenharmony_ci      const WasmFunction* function) const {
6211cb0ef41Sopenharmony_ci    return module_bytes_.SubVector(function->code.offset(),
6221cb0ef41Sopenharmony_ci                                   function->code.end_offset());
6231cb0ef41Sopenharmony_ci  }
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci  base::Vector<const byte> module_bytes() const { return module_bytes_; }
6261cb0ef41Sopenharmony_ci  const byte* start() const { return module_bytes_.begin(); }
6271cb0ef41Sopenharmony_ci  const byte* end() const { return module_bytes_.end(); }
6281cb0ef41Sopenharmony_ci  size_t length() const { return module_bytes_.length(); }
6291cb0ef41Sopenharmony_ci
6301cb0ef41Sopenharmony_ci private:
6311cb0ef41Sopenharmony_ci  base::Vector<const byte> module_bytes_;
6321cb0ef41Sopenharmony_ci};
6331cb0ef41Sopenharmony_ci
6341cb0ef41Sopenharmony_ci// A helper for printing out the names of functions.
6351cb0ef41Sopenharmony_cistruct WasmFunctionName {
6361cb0ef41Sopenharmony_ci  WasmFunctionName(const WasmFunction* function, WasmName name)
6371cb0ef41Sopenharmony_ci      : function_(function), name_(name) {}
6381cb0ef41Sopenharmony_ci
6391cb0ef41Sopenharmony_ci  const WasmFunction* function_;
6401cb0ef41Sopenharmony_ci  const WasmName name_;
6411cb0ef41Sopenharmony_ci};
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const WasmFunctionName& name);
6441cb0ef41Sopenharmony_ci
6451cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE bool IsWasmCodegenAllowed(Isolate* isolate,
6461cb0ef41Sopenharmony_ci                                            Handle<Context> context);
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ciHandle<JSObject> GetTypeForFunction(Isolate* isolate, const FunctionSig* sig,
6491cb0ef41Sopenharmony_ci                                    bool for_exception = false);
6501cb0ef41Sopenharmony_ciHandle<JSObject> GetTypeForGlobal(Isolate* isolate, bool is_mutable,
6511cb0ef41Sopenharmony_ci                                  ValueType type);
6521cb0ef41Sopenharmony_ciHandle<JSObject> GetTypeForMemory(Isolate* isolate, uint32_t min_size,
6531cb0ef41Sopenharmony_ci                                  base::Optional<uint32_t> max_size,
6541cb0ef41Sopenharmony_ci                                  bool shared);
6551cb0ef41Sopenharmony_ciHandle<JSObject> GetTypeForTable(Isolate* isolate, ValueType type,
6561cb0ef41Sopenharmony_ci                                 uint32_t min_size,
6571cb0ef41Sopenharmony_ci                                 base::Optional<uint32_t> max_size);
6581cb0ef41Sopenharmony_ciHandle<JSArray> GetImports(Isolate* isolate, Handle<WasmModuleObject> module);
6591cb0ef41Sopenharmony_ciHandle<JSArray> GetExports(Isolate* isolate, Handle<WasmModuleObject> module);
6601cb0ef41Sopenharmony_ciHandle<JSArray> GetCustomSections(Isolate* isolate,
6611cb0ef41Sopenharmony_ci                                  Handle<WasmModuleObject> module,
6621cb0ef41Sopenharmony_ci                                  Handle<String> name, ErrorThrower* thrower);
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci// Get the source position from a given function index and byte offset,
6651cb0ef41Sopenharmony_ci// for either asm.js or pure Wasm modules.
6661cb0ef41Sopenharmony_ciint GetSourcePosition(const WasmModule*, uint32_t func_index,
6671cb0ef41Sopenharmony_ci                      uint32_t byte_offset, bool is_at_number_conversion);
6681cb0ef41Sopenharmony_ci
6691cb0ef41Sopenharmony_ci// Translate function index to the index relative to the first declared (i.e.
6701cb0ef41Sopenharmony_ci// non-imported) function.
6711cb0ef41Sopenharmony_ciinline int declared_function_index(const WasmModule* module, int func_index) {
6721cb0ef41Sopenharmony_ci  DCHECK_LE(module->num_imported_functions, func_index);
6731cb0ef41Sopenharmony_ci  int declared_idx = func_index - module->num_imported_functions;
6741cb0ef41Sopenharmony_ci  DCHECK_GT(module->num_declared_functions, declared_idx);
6751cb0ef41Sopenharmony_ci  return declared_idx;
6761cb0ef41Sopenharmony_ci}
6771cb0ef41Sopenharmony_ci
6781cb0ef41Sopenharmony_ci// TruncatedUserString makes it easy to output names up to a certain length, and
6791cb0ef41Sopenharmony_ci// output a truncation followed by '...' if they exceed a limit.
6801cb0ef41Sopenharmony_ci// Use like this:
6811cb0ef41Sopenharmony_ci//   TruncatedUserString<> name (pc, len);
6821cb0ef41Sopenharmony_ci//   printf("... %.*s ...", name.length(), name.start())
6831cb0ef41Sopenharmony_citemplate <int kMaxLen = 50>
6841cb0ef41Sopenharmony_ciclass TruncatedUserString {
6851cb0ef41Sopenharmony_ci  static_assert(kMaxLen >= 4, "minimum length is 4 (length of '...' plus one)");
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci public:
6881cb0ef41Sopenharmony_ci  template <typename T>
6891cb0ef41Sopenharmony_ci  explicit TruncatedUserString(base::Vector<T> name)
6901cb0ef41Sopenharmony_ci      : TruncatedUserString(name.begin(), name.length()) {}
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci  TruncatedUserString(const byte* start, size_t len)
6931cb0ef41Sopenharmony_ci      : TruncatedUserString(reinterpret_cast<const char*>(start), len) {}
6941cb0ef41Sopenharmony_ci
6951cb0ef41Sopenharmony_ci  TruncatedUserString(const char* start, size_t len)
6961cb0ef41Sopenharmony_ci      : start_(start), length_(std::min(kMaxLen, static_cast<int>(len))) {
6971cb0ef41Sopenharmony_ci    if (len > static_cast<size_t>(kMaxLen)) {
6981cb0ef41Sopenharmony_ci      memcpy(buffer_, start, kMaxLen - 3);
6991cb0ef41Sopenharmony_ci      memset(buffer_ + kMaxLen - 3, '.', 3);
7001cb0ef41Sopenharmony_ci      start_ = buffer_;
7011cb0ef41Sopenharmony_ci    }
7021cb0ef41Sopenharmony_ci  }
7031cb0ef41Sopenharmony_ci
7041cb0ef41Sopenharmony_ci  const char* start() const { return start_; }
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ci  int length() const { return length_; }
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci private:
7091cb0ef41Sopenharmony_ci  const char* start_;
7101cb0ef41Sopenharmony_ci  const int length_;
7111cb0ef41Sopenharmony_ci  char buffer_[kMaxLen];
7121cb0ef41Sopenharmony_ci};
7131cb0ef41Sopenharmony_ci
7141cb0ef41Sopenharmony_ci// Print the signature into the given {buffer}, using {delimiter} as separator
7151cb0ef41Sopenharmony_ci// between parameter types and return types. If {buffer} is non-empty, it will
7161cb0ef41Sopenharmony_ci// be null-terminated, even if the signature is cut off. Returns the number of
7171cb0ef41Sopenharmony_ci// characters written, excluding the terminating null-byte.
7181cb0ef41Sopenharmony_cisize_t PrintSignature(base::Vector<char> buffer, const wasm::FunctionSig*,
7191cb0ef41Sopenharmony_ci                      char delimiter = ':');
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ci}  // namespace wasm
7221cb0ef41Sopenharmony_ci}  // namespace internal
7231cb0ef41Sopenharmony_ci}  // namespace v8
7241cb0ef41Sopenharmony_ci
7251cb0ef41Sopenharmony_ci#endif  // V8_WASM_WASM_MODULE_H_
726