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