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_BUILDER_H_ 101cb0ef41Sopenharmony_ci#define V8_WASM_WASM_MODULE_BUILDER_H_ 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci#include "src/base/memory.h" 131cb0ef41Sopenharmony_ci#include "src/base/platform/wrappers.h" 141cb0ef41Sopenharmony_ci#include "src/base/vector.h" 151cb0ef41Sopenharmony_ci#include "src/codegen/signature.h" 161cb0ef41Sopenharmony_ci#include "src/wasm/leb-helper.h" 171cb0ef41Sopenharmony_ci#include "src/wasm/local-decl-encoder.h" 181cb0ef41Sopenharmony_ci#include "src/wasm/value-type.h" 191cb0ef41Sopenharmony_ci#include "src/wasm/wasm-module.h" 201cb0ef41Sopenharmony_ci#include "src/wasm/wasm-opcodes.h" 211cb0ef41Sopenharmony_ci#include "src/wasm/wasm-result.h" 221cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h" 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_cinamespace v8 { 251cb0ef41Sopenharmony_cinamespace internal { 261cb0ef41Sopenharmony_cinamespace wasm { 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciclass ZoneBuffer : public ZoneObject { 291cb0ef41Sopenharmony_ci public: 301cb0ef41Sopenharmony_ci // This struct is just a type tag for Zone::NewArray<T>(size_t) call. 311cb0ef41Sopenharmony_ci struct Buffer {}; 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci static constexpr size_t kInitialSize = 1024; 341cb0ef41Sopenharmony_ci explicit ZoneBuffer(Zone* zone, size_t initial = kInitialSize) 351cb0ef41Sopenharmony_ci : zone_(zone), buffer_(zone->NewArray<byte, Buffer>(initial)) { 361cb0ef41Sopenharmony_ci pos_ = buffer_; 371cb0ef41Sopenharmony_ci end_ = buffer_ + initial; 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci 401cb0ef41Sopenharmony_ci void write_u8(uint8_t x) { 411cb0ef41Sopenharmony_ci EnsureSpace(1); 421cb0ef41Sopenharmony_ci *(pos_++) = x; 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci void write_u16(uint16_t x) { 461cb0ef41Sopenharmony_ci EnsureSpace(2); 471cb0ef41Sopenharmony_ci base::WriteLittleEndianValue<uint16_t>(reinterpret_cast<Address>(pos_), x); 481cb0ef41Sopenharmony_ci pos_ += 2; 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci void write_u32(uint32_t x) { 521cb0ef41Sopenharmony_ci EnsureSpace(4); 531cb0ef41Sopenharmony_ci base::WriteLittleEndianValue<uint32_t>(reinterpret_cast<Address>(pos_), x); 541cb0ef41Sopenharmony_ci pos_ += 4; 551cb0ef41Sopenharmony_ci } 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci void write_u64(uint64_t x) { 581cb0ef41Sopenharmony_ci EnsureSpace(8); 591cb0ef41Sopenharmony_ci base::WriteLittleEndianValue<uint64_t>(reinterpret_cast<Address>(pos_), x); 601cb0ef41Sopenharmony_ci pos_ += 8; 611cb0ef41Sopenharmony_ci } 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci void write_u32v(uint32_t val) { 641cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt32Size); 651cb0ef41Sopenharmony_ci LEBHelper::write_u32v(&pos_, val); 661cb0ef41Sopenharmony_ci } 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci void write_i32v(int32_t val) { 691cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt32Size); 701cb0ef41Sopenharmony_ci LEBHelper::write_i32v(&pos_, val); 711cb0ef41Sopenharmony_ci } 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_ci void write_u64v(uint64_t val) { 741cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt64Size); 751cb0ef41Sopenharmony_ci LEBHelper::write_u64v(&pos_, val); 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci void write_i64v(int64_t val) { 791cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt64Size); 801cb0ef41Sopenharmony_ci LEBHelper::write_i64v(&pos_, val); 811cb0ef41Sopenharmony_ci } 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci void write_size(size_t val) { 841cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt32Size); 851cb0ef41Sopenharmony_ci DCHECK_EQ(val, static_cast<uint32_t>(val)); 861cb0ef41Sopenharmony_ci LEBHelper::write_u32v(&pos_, static_cast<uint32_t>(val)); 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci void write_f32(float val) { write_u32(bit_cast<uint32_t>(val)); } 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci void write_f64(double val) { write_u64(bit_cast<uint64_t>(val)); } 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci void write(const byte* data, size_t size) { 941cb0ef41Sopenharmony_ci if (size == 0) return; 951cb0ef41Sopenharmony_ci EnsureSpace(size); 961cb0ef41Sopenharmony_ci memcpy(pos_, data, size); 971cb0ef41Sopenharmony_ci pos_ += size; 981cb0ef41Sopenharmony_ci } 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ci void write_string(base::Vector<const char> name) { 1011cb0ef41Sopenharmony_ci write_size(name.length()); 1021cb0ef41Sopenharmony_ci write(reinterpret_cast<const byte*>(name.begin()), name.length()); 1031cb0ef41Sopenharmony_ci } 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci size_t reserve_u32v() { 1061cb0ef41Sopenharmony_ci size_t off = offset(); 1071cb0ef41Sopenharmony_ci EnsureSpace(kMaxVarInt32Size); 1081cb0ef41Sopenharmony_ci pos_ += kMaxVarInt32Size; 1091cb0ef41Sopenharmony_ci return off; 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // Patch a (padded) u32v at the given offset to be the given value. 1131cb0ef41Sopenharmony_ci void patch_u32v(size_t offset, uint32_t val) { 1141cb0ef41Sopenharmony_ci byte* ptr = buffer_ + offset; 1151cb0ef41Sopenharmony_ci for (size_t pos = 0; pos != kPaddedVarInt32Size; ++pos) { 1161cb0ef41Sopenharmony_ci uint32_t next = val >> 7; 1171cb0ef41Sopenharmony_ci byte out = static_cast<byte>(val & 0x7f); 1181cb0ef41Sopenharmony_ci if (pos != kPaddedVarInt32Size - 1) { 1191cb0ef41Sopenharmony_ci *(ptr++) = 0x80 | out; 1201cb0ef41Sopenharmony_ci val = next; 1211cb0ef41Sopenharmony_ci } else { 1221cb0ef41Sopenharmony_ci *(ptr++) = out; 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci } 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci void patch_u8(size_t offset, byte val) { 1281cb0ef41Sopenharmony_ci DCHECK_GE(size(), offset); 1291cb0ef41Sopenharmony_ci buffer_[offset] = val; 1301cb0ef41Sopenharmony_ci } 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci size_t offset() const { return static_cast<size_t>(pos_ - buffer_); } 1331cb0ef41Sopenharmony_ci size_t size() const { return static_cast<size_t>(pos_ - buffer_); } 1341cb0ef41Sopenharmony_ci const byte* data() const { return buffer_; } 1351cb0ef41Sopenharmony_ci const byte* begin() const { return buffer_; } 1361cb0ef41Sopenharmony_ci const byte* end() const { return pos_; } 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci void EnsureSpace(size_t size) { 1391cb0ef41Sopenharmony_ci if ((pos_ + size) > end_) { 1401cb0ef41Sopenharmony_ci size_t new_size = size + (end_ - buffer_) * 2; 1411cb0ef41Sopenharmony_ci byte* new_buffer = zone_->NewArray<byte, Buffer>(new_size); 1421cb0ef41Sopenharmony_ci memcpy(new_buffer, buffer_, (pos_ - buffer_)); 1431cb0ef41Sopenharmony_ci pos_ = new_buffer + (pos_ - buffer_); 1441cb0ef41Sopenharmony_ci buffer_ = new_buffer; 1451cb0ef41Sopenharmony_ci end_ = new_buffer + new_size; 1461cb0ef41Sopenharmony_ci } 1471cb0ef41Sopenharmony_ci DCHECK(pos_ + size <= end_); 1481cb0ef41Sopenharmony_ci } 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci void Truncate(size_t size) { 1511cb0ef41Sopenharmony_ci DCHECK_GE(offset(), size); 1521cb0ef41Sopenharmony_ci pos_ = buffer_ + size; 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci byte** pos_ptr() { return &pos_; } 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci private: 1581cb0ef41Sopenharmony_ci Zone* zone_; 1591cb0ef41Sopenharmony_ci byte* buffer_; 1601cb0ef41Sopenharmony_ci byte* pos_; 1611cb0ef41Sopenharmony_ci byte* end_; 1621cb0ef41Sopenharmony_ci}; 1631cb0ef41Sopenharmony_ci 1641cb0ef41Sopenharmony_ciclass WasmModuleBuilder; 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject { 1671cb0ef41Sopenharmony_ci public: 1681cb0ef41Sopenharmony_ci // Building methods. 1691cb0ef41Sopenharmony_ci void SetSignature(const FunctionSig* sig); 1701cb0ef41Sopenharmony_ci void SetSignature(uint32_t sig_index); 1711cb0ef41Sopenharmony_ci uint32_t AddLocal(ValueType type); 1721cb0ef41Sopenharmony_ci void EmitByte(byte b); 1731cb0ef41Sopenharmony_ci void EmitI32V(int32_t val); 1741cb0ef41Sopenharmony_ci void EmitU32V(uint32_t val); 1751cb0ef41Sopenharmony_ci void EmitCode(const byte* code, uint32_t code_size); 1761cb0ef41Sopenharmony_ci void Emit(WasmOpcode opcode); 1771cb0ef41Sopenharmony_ci void EmitWithPrefix(WasmOpcode opcode); 1781cb0ef41Sopenharmony_ci void EmitGetLocal(uint32_t index); 1791cb0ef41Sopenharmony_ci void EmitSetLocal(uint32_t index); 1801cb0ef41Sopenharmony_ci void EmitTeeLocal(uint32_t index); 1811cb0ef41Sopenharmony_ci void EmitI32Const(int32_t val); 1821cb0ef41Sopenharmony_ci void EmitI64Const(int64_t val); 1831cb0ef41Sopenharmony_ci void EmitF32Const(float val); 1841cb0ef41Sopenharmony_ci void EmitF64Const(double val); 1851cb0ef41Sopenharmony_ci void EmitS128Const(Simd128 val); 1861cb0ef41Sopenharmony_ci void EmitWithU8(WasmOpcode opcode, const byte immediate); 1871cb0ef41Sopenharmony_ci void EmitWithU8U8(WasmOpcode opcode, const byte imm1, const byte imm2); 1881cb0ef41Sopenharmony_ci void EmitWithI32V(WasmOpcode opcode, int32_t immediate); 1891cb0ef41Sopenharmony_ci void EmitWithU32V(WasmOpcode opcode, uint32_t immediate); 1901cb0ef41Sopenharmony_ci void EmitValueType(ValueType type); 1911cb0ef41Sopenharmony_ci void EmitDirectCallIndex(uint32_t index); 1921cb0ef41Sopenharmony_ci void SetName(base::Vector<const char> name); 1931cb0ef41Sopenharmony_ci void AddAsmWasmOffset(size_t call_position, size_t to_number_position); 1941cb0ef41Sopenharmony_ci void SetAsmFunctionStartPosition(size_t function_position); 1951cb0ef41Sopenharmony_ci void SetCompilationHint(WasmCompilationHintStrategy strategy, 1961cb0ef41Sopenharmony_ci WasmCompilationHintTier baseline, 1971cb0ef41Sopenharmony_ci WasmCompilationHintTier top_tier); 1981cb0ef41Sopenharmony_ci 1991cb0ef41Sopenharmony_ci size_t GetPosition() const { return body_.size(); } 2001cb0ef41Sopenharmony_ci void FixupByte(size_t position, byte value) { 2011cb0ef41Sopenharmony_ci body_.patch_u8(position, value); 2021cb0ef41Sopenharmony_ci } 2031cb0ef41Sopenharmony_ci void DeleteCodeAfter(size_t position); 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci void WriteSignature(ZoneBuffer* buffer) const; 2061cb0ef41Sopenharmony_ci void WriteBody(ZoneBuffer* buffer) const; 2071cb0ef41Sopenharmony_ci void WriteAsmWasmOffsetTable(ZoneBuffer* buffer) const; 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci WasmModuleBuilder* builder() const { return builder_; } 2101cb0ef41Sopenharmony_ci uint32_t func_index() { return func_index_; } 2111cb0ef41Sopenharmony_ci uint32_t sig_index() { return signature_index_; } 2121cb0ef41Sopenharmony_ci inline const FunctionSig* signature(); 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci private: 2151cb0ef41Sopenharmony_ci explicit WasmFunctionBuilder(WasmModuleBuilder* builder); 2161cb0ef41Sopenharmony_ci friend class WasmModuleBuilder; 2171cb0ef41Sopenharmony_ci friend Zone; 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci struct DirectCallIndex { 2201cb0ef41Sopenharmony_ci size_t offset; 2211cb0ef41Sopenharmony_ci uint32_t direct_index; 2221cb0ef41Sopenharmony_ci }; 2231cb0ef41Sopenharmony_ci 2241cb0ef41Sopenharmony_ci WasmModuleBuilder* builder_; 2251cb0ef41Sopenharmony_ci LocalDeclEncoder locals_; 2261cb0ef41Sopenharmony_ci uint32_t signature_index_; 2271cb0ef41Sopenharmony_ci uint32_t func_index_; 2281cb0ef41Sopenharmony_ci ZoneBuffer body_; 2291cb0ef41Sopenharmony_ci base::Vector<const char> name_; 2301cb0ef41Sopenharmony_ci ZoneVector<uint32_t> i32_temps_; 2311cb0ef41Sopenharmony_ci ZoneVector<uint32_t> i64_temps_; 2321cb0ef41Sopenharmony_ci ZoneVector<uint32_t> f32_temps_; 2331cb0ef41Sopenharmony_ci ZoneVector<uint32_t> f64_temps_; 2341cb0ef41Sopenharmony_ci ZoneVector<DirectCallIndex> direct_calls_; 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci // Delta-encoded mapping from wasm bytes to asm.js source positions. 2371cb0ef41Sopenharmony_ci ZoneBuffer asm_offsets_; 2381cb0ef41Sopenharmony_ci uint32_t last_asm_byte_offset_ = 0; 2391cb0ef41Sopenharmony_ci uint32_t last_asm_source_position_ = 0; 2401cb0ef41Sopenharmony_ci uint32_t asm_func_start_source_position_ = 0; 2411cb0ef41Sopenharmony_ci uint8_t hint_ = kNoCompilationHint; 2421cb0ef41Sopenharmony_ci}; 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE WasmModuleBuilder : public ZoneObject { 2451cb0ef41Sopenharmony_ci public: 2461cb0ef41Sopenharmony_ci explicit WasmModuleBuilder(Zone* zone); 2471cb0ef41Sopenharmony_ci WasmModuleBuilder(const WasmModuleBuilder&) = delete; 2481cb0ef41Sopenharmony_ci WasmModuleBuilder& operator=(const WasmModuleBuilder&) = delete; 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci // Static representation of wasm element segment (table initializer). This is 2511cb0ef41Sopenharmony_ci // different than the version in wasm-module.h. 2521cb0ef41Sopenharmony_ci class WasmElemSegment { 2531cb0ef41Sopenharmony_ci public: 2541cb0ef41Sopenharmony_ci // asm.js gives function indices starting with the first non-imported 2551cb0ef41Sopenharmony_ci // function. 2561cb0ef41Sopenharmony_ci enum FunctionIndexingMode { 2571cb0ef41Sopenharmony_ci kRelativeToImports, 2581cb0ef41Sopenharmony_ci kRelativeToDeclaredFunctions 2591cb0ef41Sopenharmony_ci }; 2601cb0ef41Sopenharmony_ci enum Status { 2611cb0ef41Sopenharmony_ci kStatusActive, // copied automatically during instantiation. 2621cb0ef41Sopenharmony_ci kStatusPassive, // copied explicitly after instantiation. 2631cb0ef41Sopenharmony_ci kStatusDeclarative // purely declarative and never copied. 2641cb0ef41Sopenharmony_ci }; 2651cb0ef41Sopenharmony_ci struct Entry { 2661cb0ef41Sopenharmony_ci enum Kind { kGlobalGetEntry, kRefFuncEntry, kRefNullEntry } kind; 2671cb0ef41Sopenharmony_ci uint32_t index; 2681cb0ef41Sopenharmony_ci Entry(Kind kind, uint32_t index) : kind(kind), index(index) {} 2691cb0ef41Sopenharmony_ci Entry() : kind(kRefNullEntry), index(0) {} 2701cb0ef41Sopenharmony_ci }; 2711cb0ef41Sopenharmony_ci 2721cb0ef41Sopenharmony_ci // Construct an active segment. 2731cb0ef41Sopenharmony_ci WasmElemSegment(Zone* zone, ValueType type, uint32_t table_index, 2741cb0ef41Sopenharmony_ci WasmInitExpr offset) 2751cb0ef41Sopenharmony_ci : type(type), 2761cb0ef41Sopenharmony_ci table_index(table_index), 2771cb0ef41Sopenharmony_ci offset(offset), 2781cb0ef41Sopenharmony_ci entries(zone), 2791cb0ef41Sopenharmony_ci status(kStatusActive) { 2801cb0ef41Sopenharmony_ci DCHECK(IsValidOffsetKind(offset.kind())); 2811cb0ef41Sopenharmony_ci } 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci // Construct a passive or declarative segment, which has no table 2841cb0ef41Sopenharmony_ci // index or offset. 2851cb0ef41Sopenharmony_ci WasmElemSegment(Zone* zone, ValueType type, bool declarative) 2861cb0ef41Sopenharmony_ci : type(type), 2871cb0ef41Sopenharmony_ci table_index(0), 2881cb0ef41Sopenharmony_ci entries(zone), 2891cb0ef41Sopenharmony_ci status(declarative ? kStatusDeclarative : kStatusPassive) { 2901cb0ef41Sopenharmony_ci DCHECK(IsValidOffsetKind(offset.kind())); 2911cb0ef41Sopenharmony_ci } 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(WasmElemSegment); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci ValueType type; 2961cb0ef41Sopenharmony_ci uint32_t table_index; 2971cb0ef41Sopenharmony_ci WasmInitExpr offset; 2981cb0ef41Sopenharmony_ci FunctionIndexingMode indexing_mode = kRelativeToImports; 2991cb0ef41Sopenharmony_ci ZoneVector<Entry> entries; 3001cb0ef41Sopenharmony_ci Status status; 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_ci private: 3031cb0ef41Sopenharmony_ci // This ensures no {WasmInitExpr} with subexpressions is used, which would 3041cb0ef41Sopenharmony_ci // cause a memory leak because those are stored in an std::vector. Such 3051cb0ef41Sopenharmony_ci // offset would also be mistyped. 3061cb0ef41Sopenharmony_ci bool IsValidOffsetKind(WasmInitExpr::Operator kind) { 3071cb0ef41Sopenharmony_ci return kind == WasmInitExpr::kI32Const || 3081cb0ef41Sopenharmony_ci kind == WasmInitExpr::kGlobalGet; 3091cb0ef41Sopenharmony_ci } 3101cb0ef41Sopenharmony_ci }; 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci // Building methods. 3131cb0ef41Sopenharmony_ci uint32_t AddImport(base::Vector<const char> name, FunctionSig* sig, 3141cb0ef41Sopenharmony_ci base::Vector<const char> module = {}); 3151cb0ef41Sopenharmony_ci WasmFunctionBuilder* AddFunction(const FunctionSig* sig = nullptr); 3161cb0ef41Sopenharmony_ci WasmFunctionBuilder* AddFunction(uint32_t sig_index); 3171cb0ef41Sopenharmony_ci uint32_t AddGlobal(ValueType type, bool mutability = true, 3181cb0ef41Sopenharmony_ci WasmInitExpr init = WasmInitExpr()); 3191cb0ef41Sopenharmony_ci uint32_t AddGlobalImport(base::Vector<const char> name, ValueType type, 3201cb0ef41Sopenharmony_ci bool mutability, 3211cb0ef41Sopenharmony_ci base::Vector<const char> module = {}); 3221cb0ef41Sopenharmony_ci void AddDataSegment(const byte* data, uint32_t size, uint32_t dest); 3231cb0ef41Sopenharmony_ci // Add an element segment to this {WasmModuleBuilder}. {segment}'s enties 3241cb0ef41Sopenharmony_ci // have to be initialized. 3251cb0ef41Sopenharmony_ci void AddElementSegment(WasmElemSegment segment); 3261cb0ef41Sopenharmony_ci // Helper method to create an active segment with one function. Assumes that 3271cb0ef41Sopenharmony_ci // table segment at {table_index} is typed as funcref. 3281cb0ef41Sopenharmony_ci void SetIndirectFunction(uint32_t table_index, uint32_t index_in_table, 3291cb0ef41Sopenharmony_ci uint32_t direct_function_index, 3301cb0ef41Sopenharmony_ci WasmElemSegment::FunctionIndexingMode indexing_mode); 3311cb0ef41Sopenharmony_ci // Increase the starting size of the table at {table_index} by {count}. Also 3321cb0ef41Sopenharmony_ci // increases the maximum table size if needed. Returns the former starting 3331cb0ef41Sopenharmony_ci // size, or the maximum uint32_t value if the maximum table size has been 3341cb0ef41Sopenharmony_ci // exceeded. 3351cb0ef41Sopenharmony_ci uint32_t IncreaseTableMinSize(uint32_t table_index, uint32_t count); 3361cb0ef41Sopenharmony_ci // Adds the signature to the module if it does not already exist. 3371cb0ef41Sopenharmony_ci uint32_t AddSignature(const FunctionSig* sig, 3381cb0ef41Sopenharmony_ci uint32_t supertype = kNoSuperType); 3391cb0ef41Sopenharmony_ci // Does not deduplicate function signatures. 3401cb0ef41Sopenharmony_ci uint32_t ForceAddSignature(const FunctionSig* sig, 3411cb0ef41Sopenharmony_ci uint32_t supertype = kNoSuperType); 3421cb0ef41Sopenharmony_ci uint32_t AddException(const FunctionSig* type); 3431cb0ef41Sopenharmony_ci uint32_t AddStructType(StructType* type, uint32_t supertype = kNoSuperType); 3441cb0ef41Sopenharmony_ci uint32_t AddArrayType(ArrayType* type, uint32_t supertype = kNoSuperType); 3451cb0ef41Sopenharmony_ci uint32_t AddTable(ValueType type, uint32_t min_size); 3461cb0ef41Sopenharmony_ci uint32_t AddTable(ValueType type, uint32_t min_size, uint32_t max_size); 3471cb0ef41Sopenharmony_ci uint32_t AddTable(ValueType type, uint32_t min_size, uint32_t max_size, 3481cb0ef41Sopenharmony_ci WasmInitExpr init); 3491cb0ef41Sopenharmony_ci void MarkStartFunction(WasmFunctionBuilder* builder); 3501cb0ef41Sopenharmony_ci void AddExport(base::Vector<const char> name, ImportExportKindCode kind, 3511cb0ef41Sopenharmony_ci uint32_t index); 3521cb0ef41Sopenharmony_ci void AddExport(base::Vector<const char> name, WasmFunctionBuilder* builder) { 3531cb0ef41Sopenharmony_ci AddExport(name, kExternalFunction, builder->func_index()); 3541cb0ef41Sopenharmony_ci } 3551cb0ef41Sopenharmony_ci uint32_t AddExportedGlobal(ValueType type, bool mutability, WasmInitExpr init, 3561cb0ef41Sopenharmony_ci base::Vector<const char> name); 3571cb0ef41Sopenharmony_ci void ExportImportedFunction(base::Vector<const char> name, int import_index); 3581cb0ef41Sopenharmony_ci void SetMinMemorySize(uint32_t value); 3591cb0ef41Sopenharmony_ci void SetMaxMemorySize(uint32_t value); 3601cb0ef41Sopenharmony_ci void SetHasSharedMemory(); 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci void StartRecursiveTypeGroup() { 3631cb0ef41Sopenharmony_ci DCHECK_EQ(current_recursive_group_start_, -1); 3641cb0ef41Sopenharmony_ci current_recursive_group_start_ = static_cast<int>(types_.size()); 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci void EndRecursiveTypeGroup() { 3681cb0ef41Sopenharmony_ci // Make sure we are in a recursive group. 3691cb0ef41Sopenharmony_ci DCHECK_NE(current_recursive_group_start_, -1); 3701cb0ef41Sopenharmony_ci // Make sure the current recursive group has at least one element. 3711cb0ef41Sopenharmony_ci DCHECK_GT(static_cast<int>(types_.size()), current_recursive_group_start_); 3721cb0ef41Sopenharmony_ci recursive_groups_.emplace( 3731cb0ef41Sopenharmony_ci current_recursive_group_start_, 3741cb0ef41Sopenharmony_ci static_cast<uint32_t>(types_.size()) - current_recursive_group_start_); 3751cb0ef41Sopenharmony_ci current_recursive_group_start_ = -1; 3761cb0ef41Sopenharmony_ci } 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci // Writing methods. 3791cb0ef41Sopenharmony_ci void WriteTo(ZoneBuffer* buffer) const; 3801cb0ef41Sopenharmony_ci void WriteAsmJsOffsetTable(ZoneBuffer* buffer) const; 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci Zone* zone() { return zone_; } 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci ValueType GetTableType(uint32_t index) { return tables_[index].type; } 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_ci bool IsSignature(uint32_t index) { 3871cb0ef41Sopenharmony_ci return types_[index].kind == TypeDefinition::kFunction; 3881cb0ef41Sopenharmony_ci } 3891cb0ef41Sopenharmony_ci 3901cb0ef41Sopenharmony_ci const FunctionSig* GetSignature(uint32_t index) { 3911cb0ef41Sopenharmony_ci DCHECK(types_[index].kind == TypeDefinition::kFunction); 3921cb0ef41Sopenharmony_ci return types_[index].function_sig; 3931cb0ef41Sopenharmony_ci } 3941cb0ef41Sopenharmony_ci 3951cb0ef41Sopenharmony_ci bool IsStructType(uint32_t index) { 3961cb0ef41Sopenharmony_ci return types_[index].kind == TypeDefinition::kStruct; 3971cb0ef41Sopenharmony_ci } 3981cb0ef41Sopenharmony_ci const StructType* GetStructType(uint32_t index) { 3991cb0ef41Sopenharmony_ci return types_[index].struct_type; 4001cb0ef41Sopenharmony_ci } 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci bool IsArrayType(uint32_t index) { 4031cb0ef41Sopenharmony_ci return types_[index].kind == TypeDefinition::kArray; 4041cb0ef41Sopenharmony_ci } 4051cb0ef41Sopenharmony_ci const ArrayType* GetArrayType(uint32_t index) { 4061cb0ef41Sopenharmony_ci return types_[index].array_type; 4071cb0ef41Sopenharmony_ci } 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci WasmFunctionBuilder* GetFunction(uint32_t index) { return functions_[index]; } 4101cb0ef41Sopenharmony_ci int NumExceptions() { return static_cast<int>(exceptions_.size()); } 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci int NumTypes() { return static_cast<int>(types_.size()); } 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ci int NumTables() { return static_cast<int>(tables_.size()); } 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci int NumFunctions() { return static_cast<int>(functions_.size()); } 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci const FunctionSig* GetExceptionType(int index) { 4191cb0ef41Sopenharmony_ci return types_[exceptions_[index]].function_sig; 4201cb0ef41Sopenharmony_ci } 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ci private: 4231cb0ef41Sopenharmony_ci struct WasmFunctionImport { 4241cb0ef41Sopenharmony_ci base::Vector<const char> module; 4251cb0ef41Sopenharmony_ci base::Vector<const char> name; 4261cb0ef41Sopenharmony_ci uint32_t sig_index; 4271cb0ef41Sopenharmony_ci }; 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci struct WasmGlobalImport { 4301cb0ef41Sopenharmony_ci base::Vector<const char> module; 4311cb0ef41Sopenharmony_ci base::Vector<const char> name; 4321cb0ef41Sopenharmony_ci ValueTypeCode type_code; 4331cb0ef41Sopenharmony_ci bool mutability; 4341cb0ef41Sopenharmony_ci }; 4351cb0ef41Sopenharmony_ci 4361cb0ef41Sopenharmony_ci struct WasmExport { 4371cb0ef41Sopenharmony_ci base::Vector<const char> name; 4381cb0ef41Sopenharmony_ci ImportExportKindCode kind; 4391cb0ef41Sopenharmony_ci int index; // Can be negative for re-exported imports. 4401cb0ef41Sopenharmony_ci }; 4411cb0ef41Sopenharmony_ci 4421cb0ef41Sopenharmony_ci struct WasmGlobal { 4431cb0ef41Sopenharmony_ci ValueType type; 4441cb0ef41Sopenharmony_ci bool mutability; 4451cb0ef41Sopenharmony_ci WasmInitExpr init; 4461cb0ef41Sopenharmony_ci }; 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ci struct WasmTable { 4491cb0ef41Sopenharmony_ci ValueType type; 4501cb0ef41Sopenharmony_ci uint32_t min_size; 4511cb0ef41Sopenharmony_ci uint32_t max_size; 4521cb0ef41Sopenharmony_ci bool has_maximum; 4531cb0ef41Sopenharmony_ci WasmInitExpr init; 4541cb0ef41Sopenharmony_ci }; 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci struct WasmDataSegment { 4571cb0ef41Sopenharmony_ci ZoneVector<byte> data; 4581cb0ef41Sopenharmony_ci uint32_t dest; 4591cb0ef41Sopenharmony_ci }; 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci friend class WasmFunctionBuilder; 4621cb0ef41Sopenharmony_ci Zone* zone_; 4631cb0ef41Sopenharmony_ci ZoneVector<TypeDefinition> types_; 4641cb0ef41Sopenharmony_ci ZoneVector<WasmFunctionImport> function_imports_; 4651cb0ef41Sopenharmony_ci ZoneVector<WasmGlobalImport> global_imports_; 4661cb0ef41Sopenharmony_ci ZoneVector<WasmExport> exports_; 4671cb0ef41Sopenharmony_ci ZoneVector<WasmFunctionBuilder*> functions_; 4681cb0ef41Sopenharmony_ci ZoneVector<WasmTable> tables_; 4691cb0ef41Sopenharmony_ci ZoneVector<WasmDataSegment> data_segments_; 4701cb0ef41Sopenharmony_ci ZoneVector<WasmElemSegment> element_segments_; 4711cb0ef41Sopenharmony_ci ZoneVector<WasmGlobal> globals_; 4721cb0ef41Sopenharmony_ci ZoneVector<int> exceptions_; 4731cb0ef41Sopenharmony_ci ZoneUnorderedMap<FunctionSig, uint32_t> signature_map_; 4741cb0ef41Sopenharmony_ci int current_recursive_group_start_; 4751cb0ef41Sopenharmony_ci // first index -> size 4761cb0ef41Sopenharmony_ci ZoneUnorderedMap<uint32_t, uint32_t> recursive_groups_; 4771cb0ef41Sopenharmony_ci int start_function_index_; 4781cb0ef41Sopenharmony_ci uint32_t min_memory_size_; 4791cb0ef41Sopenharmony_ci uint32_t max_memory_size_; 4801cb0ef41Sopenharmony_ci bool has_max_memory_size_; 4811cb0ef41Sopenharmony_ci bool has_shared_memory_; 4821cb0ef41Sopenharmony_ci#if DEBUG 4831cb0ef41Sopenharmony_ci // Once AddExportedImport is called, no more imports can be added. 4841cb0ef41Sopenharmony_ci bool adding_imports_allowed_ = true; 4851cb0ef41Sopenharmony_ci#endif 4861cb0ef41Sopenharmony_ci}; 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ciconst FunctionSig* WasmFunctionBuilder::signature() { 4891cb0ef41Sopenharmony_ci return builder_->types_[signature_index_].function_sig; 4901cb0ef41Sopenharmony_ci} 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci} // namespace wasm 4931cb0ef41Sopenharmony_ci} // namespace internal 4941cb0ef41Sopenharmony_ci} // namespace v8 4951cb0ef41Sopenharmony_ci 4961cb0ef41Sopenharmony_ci#endif // V8_WASM_WASM_MODULE_BUILDER_H_ 497