diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/wasm2c/include/wabt/common.h | |
parent | Initial commit. (diff) | |
download | firefox-esr-upstream.tar.xz firefox-esr-upstream.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | third_party/wasm2c/include/wabt/common.h | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/third_party/wasm2c/include/wabt/common.h b/third_party/wasm2c/include/wabt/common.h new file mode 100644 index 0000000000..2ae1fa1fe9 --- /dev/null +++ b/third_party/wasm2c/include/wabt/common.h @@ -0,0 +1,456 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WABT_COMMON_H_ +#define WABT_COMMON_H_ + +#include <algorithm> +#include <cassert> +#include <cstdarg> +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <memory> +#include <string> +#include <string_view> +#include <type_traits> +#include <vector> + +#include "wabt/config.h" + +#include "wabt/base-types.h" +#include "wabt/result.h" +#include "wabt/string-format.h" +#include "wabt/type.h" + +#define WABT_FATAL(...) fprintf(stderr, __VA_ARGS__), exit(1) +#define WABT_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define WABT_USE(x) static_cast<void>(x) + +// 64k +#define WABT_PAGE_SIZE 0x10000 +// # of pages that fit in 32-bit address space +#define WABT_MAX_PAGES32 0x10000 +// # of pages that fit in 64-bit address space +#define WABT_MAX_PAGES64 0x1000000000000 +#define WABT_BYTES_TO_PAGES(x) ((x) >> 16) +#define WABT_ALIGN_UP_TO_PAGE(x) \ + (((x) + WABT_PAGE_SIZE - 1) & ~(WABT_PAGE_SIZE - 1)) + +#define WABT_ENUM_COUNT(name) \ + (static_cast<int>(name::Last) - static_cast<int>(name::First) + 1) + +#define WABT_DISALLOW_COPY_AND_ASSIGN(type) \ + type(const type&) = delete; \ + type& operator=(const type&) = delete; + +#if WITH_EXCEPTIONS +#define WABT_TRY try { +#define WABT_CATCH_BAD_ALLOC \ + } \ + catch (std::bad_alloc&) { \ + } +#define WABT_CATCH_BAD_ALLOC_AND_EXIT \ + } \ + catch (std::bad_alloc&) { \ + WABT_FATAL("Memory allocation failure.\n"); \ + } +#else +#define WABT_TRY +#define WABT_CATCH_BAD_ALLOC +#define WABT_CATCH_BAD_ALLOC_AND_EXIT +#endif + +#define PRIindex "u" +#define PRIaddress PRIu64 +#define PRIoffset PRIzx + +namespace wabt { +inline void MemcpyEndianAware(void* dst, + const void* src, + size_t dsize, + size_t ssize, + size_t doff, + size_t soff, + size_t len) { +#if WABT_BIG_ENDIAN + memcpy(static_cast<char*>(dst) + (dsize) - (len) - (doff), + static_cast<const char*>(src) + (ssize) - (len) - (soff), (len)); +#else + memcpy(static_cast<char*>(dst) + (doff), + static_cast<const char*>(src) + (soff), (len)); +#endif +} +} + +struct v128 { + v128() = default; + v128(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) { + set_u32(0, x0); + set_u32(1, x1); + set_u32(2, x2); + set_u32(3, x3); + } + + bool operator==(const v128& other) const { + return std::equal(std::begin(v), std::end(v), std::begin(other.v)); + } + bool operator!=(const v128& other) const { return !(*this == other); } + + uint8_t u8(int lane) const { return To<uint8_t>(lane); } + uint16_t u16(int lane) const { return To<uint16_t>(lane); } + uint32_t u32(int lane) const { return To<uint32_t>(lane); } + uint64_t u64(int lane) const { return To<uint64_t>(lane); } + uint32_t f32_bits(int lane) const { return To<uint32_t>(lane); } + uint64_t f64_bits(int lane) const { return To<uint64_t>(lane); } + + void set_u8(int lane, uint8_t x) { return From<uint8_t>(lane, x); } + void set_u16(int lane, uint16_t x) { return From<uint16_t>(lane, x); } + void set_u32(int lane, uint32_t x) { return From<uint32_t>(lane, x); } + void set_u64(int lane, uint64_t x) { return From<uint64_t>(lane, x); } + void set_f32_bits(int lane, uint32_t x) { return From<uint32_t>(lane, x); } + void set_f64_bits(int lane, uint64_t x) { return From<uint64_t>(lane, x); } + + bool is_zero() const { + return std::all_of(std::begin(v), std::end(v), + [](uint8_t x) { return x == 0; }); + } + void set_zero() { std::fill(std::begin(v), std::end(v), 0); } + + template <typename T> + T To(int lane) const { + static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); + assert((lane + 1) * sizeof(T) <= sizeof(v)); + T result; + wabt::MemcpyEndianAware(&result, v, sizeof(result), sizeof(v), 0, + lane * sizeof(T), sizeof(result)); + return result; + } + + template <typename T> + void From(int lane, T data) { + static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); + assert((lane + 1) * sizeof(T) <= sizeof(v)); + wabt::MemcpyEndianAware(v, &data, sizeof(v), sizeof(data), lane * sizeof(T), + 0, sizeof(data)); + } + + uint8_t v[16]; +}; + +namespace wabt { + +template <typename Dst, typename Src> +Dst WABT_VECTORCALL Bitcast(Src&& value) { + static_assert(sizeof(Src) == sizeof(Dst), "Bitcast sizes must match."); + Dst result; + memcpy(&result, &value, sizeof(result)); + return result; +} + +template <typename T> +void ZeroMemory(T& v) { + WABT_STATIC_ASSERT(std::is_pod<T>::value); + memset(&v, 0, sizeof(v)); +} + +// Placement construct +template <typename T, typename... Args> +void Construct(T& placement, Args&&... args) { + new (&placement) T(std::forward<Args>(args)...); +} + +// Placement destruct +template <typename T> +void Destruct(T& placement) { + placement.~T(); +} + +enum class LabelType { + Func, + InitExpr, + Block, + Loop, + If, + Else, + Try, + Catch, + + First = Func, + Last = Catch, +}; +constexpr int kLabelTypeCount = WABT_ENUM_COUNT(LabelType); + +struct Location { + enum class Type { + Text, + Binary, + }; + + Location() : line(0), first_column(0), last_column(0) {} + Location(std::string_view filename, + int line, + int first_column, + int last_column) + : filename(filename), + line(line), + first_column(first_column), + last_column(last_column) {} + explicit Location(size_t offset) : offset(offset) {} + + std::string_view filename; + union { + // For text files. + struct { + int line; + int first_column; + int last_column; + }; + // For binary files. + struct { + size_t offset; + }; + }; +}; + +enum class SegmentKind { + Active, + Passive, + Declared, +}; + +// Used in test asserts for special expected values "nan:canonical" and +// "nan:arithmetic" +enum class ExpectedNan { + None, + Canonical, + Arithmetic, +}; + +// Matches binary format, do not change. +enum SegmentFlags : uint8_t { + SegFlagsNone = 0, + SegPassive = 1, // bit 0: Is passive + SegExplicitIndex = 2, // bit 1: Has explict index (Implies table 0 if absent) + SegDeclared = 3, // Only used for declared segments + SegUseElemExprs = 4, // bit 2: Is elemexpr (Or else index sequence) + + SegFlagMax = (SegUseElemExprs << 1) - 1, // All bits set. +}; + +enum class RelocType { + FuncIndexLEB = 0, // e.g. Immediate of call instruction + TableIndexSLEB = 1, // e.g. Loading address of function + TableIndexI32 = 2, // e.g. Function address in DATA + MemoryAddressLEB = 3, // e.g. Memory address in load/store offset immediate + MemoryAddressSLEB = 4, // e.g. Memory address in i32.const + MemoryAddressI32 = 5, // e.g. Memory address in DATA + TypeIndexLEB = 6, // e.g. Immediate type in call_indirect + GlobalIndexLEB = 7, // e.g. Immediate of global.get inst + FunctionOffsetI32 = 8, // e.g. Code offset in DWARF metadata + SectionOffsetI32 = 9, // e.g. Section offset in DWARF metadata + TagIndexLEB = 10, // Used in throw instructions + MemoryAddressRelSLEB = 11, // In PIC code, addr relative to __memory_base + TableIndexRelSLEB = 12, // In PIC code, table index relative to __table_base + GlobalIndexI32 = 13, // e.g. Global index in data (e.g. DWARF) + MemoryAddressLEB64 = 14, // Memory64: Like MemoryAddressLEB + MemoryAddressSLEB64 = 15, // Memory64: Like MemoryAddressSLEB + MemoryAddressI64 = 16, // Memory64: Like MemoryAddressI32 + MemoryAddressRelSLEB64 = 17, // Memory64: Like MemoryAddressRelSLEB + TableIndexSLEB64 = 18, // Memory64: Like TableIndexSLEB + TableIndexI64 = 19, // Memory64: Like TableIndexI32 + TableNumberLEB = 20, // e.g. Immediate of table.get + MemoryAddressTLSSLEB = 21, // Address relative to __tls_base + MemoryAddressTLSI32 = 22, // Address relative to __tls_base + + First = FuncIndexLEB, + Last = MemoryAddressTLSI32, +}; +constexpr int kRelocTypeCount = WABT_ENUM_COUNT(RelocType); + +struct Reloc { + Reloc(RelocType, size_t offset, Index index, int32_t addend = 0); + + RelocType type; + size_t offset; + Index index; + int32_t addend; +}; + +enum class LinkingEntryType { + SegmentInfo = 5, + InitFunctions = 6, + ComdatInfo = 7, + SymbolTable = 8, +}; + +enum class DylinkEntryType { + MemInfo = 1, + Needed = 2, + ExportInfo = 3, + ImportInfo = 4, +}; + +enum class SymbolType { + Function = 0, + Data = 1, + Global = 2, + Section = 3, + Tag = 4, + Table = 5, +}; + +enum class ComdatType { + Data = 0x0, + Function = 0x1, +}; + +#define WABT_SYMBOL_MASK_VISIBILITY 0x4 +#define WABT_SYMBOL_MASK_BINDING 0x3 +#define WABT_SYMBOL_FLAG_UNDEFINED 0x10 +#define WABT_SYMBOL_FLAG_EXPORTED 0x20 +#define WABT_SYMBOL_FLAG_EXPLICIT_NAME 0x40 +#define WABT_SYMBOL_FLAG_NO_STRIP 0x80 +#define WABT_SYMBOL_FLAG_TLS 0x100 +#define WABT_SYMBOL_FLAG_MAX 0x1ff + +#define WABT_SEGMENT_FLAG_STRINGS 0x1 +#define WABT_SEGMENT_FLAG_TLS 0x2 +#define WABT_SEGMENT_FLAG_MAX 0xff + +enum class SymbolVisibility { + Default = 0, + Hidden = 4, +}; + +enum class SymbolBinding { + Global = 0, + Weak = 1, + Local = 2, +}; + +/* matches binary format, do not change */ +enum class ExternalKind { + Func = 0, + Table = 1, + Memory = 2, + Global = 3, + Tag = 4, + + First = Func, + Last = Tag, +}; +constexpr int kExternalKindCount = WABT_ENUM_COUNT(ExternalKind); + +struct Limits { + Limits() = default; + explicit Limits(uint64_t initial) : initial(initial) {} + Limits(uint64_t initial, uint64_t max) + : initial(initial), max(max), has_max(true) {} + Limits(uint64_t initial, uint64_t max, bool is_shared) + : initial(initial), max(max), has_max(true), is_shared(is_shared) {} + Limits(uint64_t initial, uint64_t max, bool is_shared, bool is_64) + : initial(initial), + max(max), + has_max(true), + is_shared(is_shared), + is_64(is_64) {} + Type IndexType() const { return is_64 ? Type::I64 : Type::I32; } + + uint64_t initial = 0; + uint64_t max = 0; + bool has_max = false; + bool is_shared = false; + bool is_64 = false; +}; + +enum { WABT_USE_NATURAL_ALIGNMENT = 0xFFFFFFFFFFFFFFFF }; + +Result ReadFile(std::string_view filename, std::vector<uint8_t>* out_data); + +void InitStdio(); + +/* external kind */ + +extern const char* g_kind_name[]; + +static inline const char* GetKindName(ExternalKind kind) { + return static_cast<size_t>(kind) < kExternalKindCount + ? g_kind_name[static_cast<size_t>(kind)] + : "<error_kind>"; +} + +/* reloc */ + +extern const char* g_reloc_type_name[]; + +static inline const char* GetRelocTypeName(RelocType reloc) { + return static_cast<size_t>(reloc) < kRelocTypeCount + ? g_reloc_type_name[static_cast<size_t>(reloc)] + : "<error_reloc_type>"; +} + +/* symbol */ + +static inline const char* GetSymbolTypeName(SymbolType type) { + switch (type) { + case SymbolType::Function: + return "func"; + case SymbolType::Global: + return "global"; + case SymbolType::Data: + return "data"; + case SymbolType::Section: + return "section"; + case SymbolType::Tag: + return "tag"; + case SymbolType::Table: + return "table"; + default: + return "<error_symbol_type>"; + } +} + +template <typename T> +void ConvertBackslashToSlash(T begin, T end) { + std::replace(begin, end, '\\', '/'); +} + +inline void ConvertBackslashToSlash(char* s, size_t length) { + ConvertBackslashToSlash(s, s + length); +} + +inline void ConvertBackslashToSlash(char* s) { + ConvertBackslashToSlash(s, strlen(s)); +} + +inline void ConvertBackslashToSlash(std::string* s) { + ConvertBackslashToSlash(s->begin(), s->end()); +} + +inline void SwapBytesSized(void* addr, size_t size) { + auto bytes = static_cast<uint8_t*>(addr); + for (size_t i = 0; i < size / 2; i++) { + std::swap(bytes[i], bytes[size - 1 - i]); + } +} + +} // namespace wabt + +#endif // WABT_COMMON_H_ |