Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/wabt/common.h
1 /* 2 * Copyright 2016 WebAssembly Community Group participants 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef WABT_COMMON_H_ 18 #define WABT_COMMON_H_ 19 20 #include <algorithm> 21 #include <cassert> 22 #include <cstdarg> 23 #include <cstddef> 24 #include <cstdint> 25 #include <cstdio> 26 #include <cstdlib> 27 #include <cstring> 28 #include <memory> 29 #include <string> 30 #include <string_view> 31 #include <type_traits> 32 #include <vector> 33 34 #include "wabt/config.h" 35 36 #include "wabt/base-types.h" 37 #include "wabt/result.h" 38 #include "wabt/string-format.h" 39 #include "wabt/type.h" 40 41 #define WABT_FATAL(...) fprintf(stderr, __VA_ARGS__), exit(1) 42 #define WABT_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 43 44 #define WABT_USE(x) static_cast<void>(x) 45 46 // 64k 47 #define WABT_PAGE_SIZE 0x10000 48 // # of pages that fit in 32-bit address space 49 #define WABT_MAX_PAGES32 0x10000 50 // # of pages that fit in 64-bit address space 51 #define WABT_MAX_PAGES64 0x1000000000000 52 #define WABT_BYTES_TO_PAGES(x) ((x) >> 16) 53 #define WABT_ALIGN_UP_TO_PAGE(x) \ 54 (((x) + WABT_PAGE_SIZE - 1) & ~(WABT_PAGE_SIZE - 1)) 55 56 #define WABT_ENUM_COUNT(name) \ 57 (static_cast<int>(name::Last) - static_cast<int>(name::First) + 1) 58 59 #define WABT_DISALLOW_COPY_AND_ASSIGN(type) \ 60 type(const type&) = delete; \ 61 type& operator=(const type&) = delete; 62 63 #if WITH_EXCEPTIONS 64 #define WABT_TRY try { 65 #define WABT_CATCH_BAD_ALLOC \ 66 } \ 67 catch (std::bad_alloc&) { \ 68 } 69 #define WABT_CATCH_BAD_ALLOC_AND_EXIT \ 70 } \ 71 catch (std::bad_alloc&) { \ 72 WABT_FATAL("Memory allocation failure.\n"); \ 73 } 74 #else 75 #define WABT_TRY 76 #define WABT_CATCH_BAD_ALLOC 77 #define WABT_CATCH_BAD_ALLOC_AND_EXIT 78 #endif 79 80 #define PRIindex "u" 81 #define PRIaddress PRIu64 82 #define PRIoffset PRIzx 83 84 namespace wabt { 85 inline void MemcpyEndianAware(void* dst, 86 const void* src, 87 size_t dsize, 88 size_t ssize, 89 size_t doff, 90 size_t soff, 91 size_t len) { 92 #if WABT_BIG_ENDIAN 93 memcpy(static_cast<char*>(dst) + (dsize) - (len) - (doff), 94 static_cast<const char*>(src) + (ssize) - (len) - (soff), (len)); 95 #else 96 memcpy(static_cast<char*>(dst) + (doff), 97 static_cast<const char*>(src) + (soff), (len)); 98 #endif 99 } 100 } 101 102 struct v128 { 103 v128() = default; 104 v128(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) { 105 set_u32(0, x0); 106 set_u32(1, x1); 107 set_u32(2, x2); 108 set_u32(3, x3); 109 } 110 111 bool operator==(const v128& other) const { 112 return std::equal(std::begin(v), std::end(v), std::begin(other.v)); 113 } 114 bool operator!=(const v128& other) const { return !(*this == other); } 115 116 uint8_t u8(int lane) const { return To<uint8_t>(lane); } 117 uint16_t u16(int lane) const { return To<uint16_t>(lane); } 118 uint32_t u32(int lane) const { return To<uint32_t>(lane); } 119 uint64_t u64(int lane) const { return To<uint64_t>(lane); } 120 uint32_t f32_bits(int lane) const { return To<uint32_t>(lane); } 121 uint64_t f64_bits(int lane) const { return To<uint64_t>(lane); } 122 123 void set_u8(int lane, uint8_t x) { return From<uint8_t>(lane, x); } 124 void set_u16(int lane, uint16_t x) { return From<uint16_t>(lane, x); } 125 void set_u32(int lane, uint32_t x) { return From<uint32_t>(lane, x); } 126 void set_u64(int lane, uint64_t x) { return From<uint64_t>(lane, x); } 127 void set_f32_bits(int lane, uint32_t x) { return From<uint32_t>(lane, x); } 128 void set_f64_bits(int lane, uint64_t x) { return From<uint64_t>(lane, x); } 129 130 bool is_zero() const { 131 return std::all_of(std::begin(v), std::end(v), 132 [](uint8_t x) { return x == 0; }); 133 } 134 void set_zero() { std::fill(std::begin(v), std::end(v), 0); } 135 136 template <typename T> 137 T To(int lane) const { 138 static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); 139 assert((lane + 1) * sizeof(T) <= sizeof(v)); 140 T result; 141 wabt::MemcpyEndianAware(&result, v, sizeof(result), sizeof(v), 0, 142 lane * sizeof(T), sizeof(result)); 143 return result; 144 } 145 146 template <typename T> 147 void From(int lane, T data) { 148 static_assert(sizeof(T) <= sizeof(v), "Invalid cast!"); 149 assert((lane + 1) * sizeof(T) <= sizeof(v)); 150 wabt::MemcpyEndianAware(v, &data, sizeof(v), sizeof(data), lane * sizeof(T), 151 0, sizeof(data)); 152 } 153 154 uint8_t v[16]; 155 }; 156 157 namespace wabt { 158 159 template <typename Dst, typename Src> 160 Dst WABT_VECTORCALL Bitcast(Src&& value) { 161 static_assert(sizeof(Src) == sizeof(Dst), "Bitcast sizes must match."); 162 Dst result; 163 memcpy(&result, &value, sizeof(result)); 164 return result; 165 } 166 167 template <typename T> 168 void ZeroMemory(T& v) { 169 WABT_STATIC_ASSERT(std::is_trivial<T>::value); 170 memset(&v, 0, sizeof(v)); 171 } 172 173 // Placement construct 174 template <typename T, typename... Args> 175 void Construct(T& placement, Args&&... args) { 176 new (&placement) T(std::forward<Args>(args)...); 177 } 178 179 // Placement destruct 180 template <typename T> 181 void Destruct(T& placement) { 182 placement.~T(); 183 } 184 185 enum class LabelType { 186 Func, 187 InitExpr, 188 Block, 189 Loop, 190 If, 191 Else, 192 Try, 193 Catch, 194 195 First = Func, 196 Last = Catch, 197 }; 198 constexpr int kLabelTypeCount = WABT_ENUM_COUNT(LabelType); 199 200 struct Location { 201 enum class Type { 202 Text, 203 Binary, 204 }; 205 206 Location() : line(0), first_column(0), last_column(0) {} 207 Location(std::string_view filename, 208 int line, 209 int first_column, 210 int last_column) 211 : filename(filename), 212 line(line), 213 first_column(first_column), 214 last_column(last_column) {} 215 explicit Location(size_t offset) : offset(offset) {} 216 217 std::string_view filename; 218 union { 219 // For text files. 220 struct { 221 int line; 222 int first_column; 223 int last_column; 224 }; 225 // For binary files. 226 struct { 227 size_t offset; 228 }; 229 }; 230 }; 231 232 enum class SegmentKind { 233 Active, 234 Passive, 235 Declared, 236 }; 237 238 // Used in test asserts for special expected values "nan:canonical" and 239 // "nan:arithmetic" 240 enum class ExpectedNan { 241 None, 242 Canonical, 243 Arithmetic, 244 }; 245 246 // Matches binary format, do not change. 247 enum SegmentFlags : uint8_t { 248 SegFlagsNone = 0, 249 SegPassive = 1, // bit 0: Is passive 250 SegExplicitIndex = 2, // bit 1: Has explict index (Implies table 0 if absent) 251 SegDeclared = 3, // Only used for declared segments 252 SegUseElemExprs = 4, // bit 2: Is elemexpr (Or else index sequence) 253 254 SegFlagMax = (SegUseElemExprs << 1) - 1, // All bits set. 255 }; 256 257 enum class RelocType { 258 FuncIndexLEB = 0, // e.g. Immediate of call instruction 259 TableIndexSLEB = 1, // e.g. Loading address of function 260 TableIndexI32 = 2, // e.g. Function address in DATA 261 MemoryAddressLEB = 3, // e.g. Memory address in load/store offset immediate 262 MemoryAddressSLEB = 4, // e.g. Memory address in i32.const 263 MemoryAddressI32 = 5, // e.g. Memory address in DATA 264 TypeIndexLEB = 6, // e.g. Immediate type in call_indirect 265 GlobalIndexLEB = 7, // e.g. Immediate of global.get inst 266 FunctionOffsetI32 = 8, // e.g. Code offset in DWARF metadata 267 SectionOffsetI32 = 9, // e.g. Section offset in DWARF metadata 268 TagIndexLEB = 10, // Used in throw instructions 269 MemoryAddressRelSLEB = 11, // In PIC code, addr relative to __memory_base 270 TableIndexRelSLEB = 12, // In PIC code, table index relative to __table_base 271 GlobalIndexI32 = 13, // e.g. Global index in data (e.g. DWARF) 272 MemoryAddressLEB64 = 14, // Memory64: Like MemoryAddressLEB 273 MemoryAddressSLEB64 = 15, // Memory64: Like MemoryAddressSLEB 274 MemoryAddressI64 = 16, // Memory64: Like MemoryAddressI32 275 MemoryAddressRelSLEB64 = 17, // Memory64: Like MemoryAddressRelSLEB 276 TableIndexSLEB64 = 18, // Memory64: Like TableIndexSLEB 277 TableIndexI64 = 19, // Memory64: Like TableIndexI32 278 TableNumberLEB = 20, // e.g. Immediate of table.get 279 MemoryAddressTLSSLEB = 21, // Address relative to __tls_base 280 MemoryAddressTLSI32 = 22, // Address relative to __tls_base 281 282 First = FuncIndexLEB, 283 Last = MemoryAddressTLSI32, 284 }; 285 constexpr int kRelocTypeCount = WABT_ENUM_COUNT(RelocType); 286 287 struct Reloc { 288 Reloc(RelocType, size_t offset, Index index, int32_t addend = 0); 289 290 RelocType type; 291 size_t offset; 292 Index index; 293 int32_t addend; 294 }; 295 296 enum class LinkingEntryType { 297 SegmentInfo = 5, 298 InitFunctions = 6, 299 ComdatInfo = 7, 300 SymbolTable = 8, 301 }; 302 303 enum class DylinkEntryType { 304 MemInfo = 1, 305 Needed = 2, 306 ExportInfo = 3, 307 ImportInfo = 4, 308 }; 309 310 enum class SymbolType { 311 Function = 0, 312 Data = 1, 313 Global = 2, 314 Section = 3, 315 Tag = 4, 316 Table = 5, 317 }; 318 319 enum class ComdatType { 320 Data = 0x0, 321 Function = 0x1, 322 }; 323 324 #define WABT_SYMBOL_MASK_VISIBILITY 0x4 325 #define WABT_SYMBOL_MASK_BINDING 0x3 326 #define WABT_SYMBOL_FLAG_UNDEFINED 0x10 327 #define WABT_SYMBOL_FLAG_EXPORTED 0x20 328 #define WABT_SYMBOL_FLAG_EXPLICIT_NAME 0x40 329 #define WABT_SYMBOL_FLAG_NO_STRIP 0x80 330 #define WABT_SYMBOL_FLAG_TLS 0x100 331 #define WABT_SYMBOL_FLAG_ABS 0x200 332 #define WABT_SYMBOL_FLAG_MAX 0x3ff 333 334 #define WABT_SEGMENT_FLAG_STRINGS 0x1 335 #define WABT_SEGMENT_FLAG_TLS 0x2 336 #define WASM_SEGMENT_FLAG_RETAIN 0x4 337 #define WABT_SEGMENT_FLAG_MAX 0xff 338 339 enum class SymbolVisibility { 340 Default = 0, 341 Hidden = 4, 342 }; 343 344 enum class SymbolBinding { 345 Global = 0, 346 Weak = 1, 347 Local = 2, 348 }; 349 350 /* matches binary format, do not change */ 351 enum class ExternalKind { 352 Func = 0, 353 Table = 1, 354 Memory = 2, 355 Global = 3, 356 Tag = 4, 357 358 First = Func, 359 Last = Tag, 360 }; 361 constexpr int kExternalKindCount = WABT_ENUM_COUNT(ExternalKind); 362 363 struct Limits { 364 Limits() = default; 365 explicit Limits(uint64_t initial) : initial(initial) {} 366 Limits(uint64_t initial, uint64_t max) 367 : initial(initial), max(max), has_max(true) {} 368 Limits(uint64_t initial, uint64_t max, bool is_shared) 369 : initial(initial), max(max), has_max(true), is_shared(is_shared) {} 370 Limits(uint64_t initial, uint64_t max, bool is_shared, bool is_64) 371 : initial(initial), 372 max(max), 373 has_max(true), 374 is_shared(is_shared), 375 is_64(is_64) {} 376 Type IndexType() const { return is_64 ? Type::I64 : Type::I32; } 377 378 uint64_t initial = 0; 379 uint64_t max = 0; 380 bool has_max = false; 381 bool is_shared = false; 382 bool is_64 = false; 383 }; 384 385 enum { WABT_USE_NATURAL_ALIGNMENT = 0xFFFFFFFFFFFFFFFF }; 386 387 Result ReadFile(std::string_view filename, std::vector<uint8_t>* out_data); 388 389 void InitStdio(); 390 391 /* external kind */ 392 393 extern const char* g_kind_name[]; 394 395 static inline const char* GetKindName(ExternalKind kind) { 396 return static_cast<size_t>(kind) < kExternalKindCount 397 ? g_kind_name[static_cast<size_t>(kind)] 398 : "<error_kind>"; 399 } 400 401 /* reloc */ 402 403 extern const char* g_reloc_type_name[]; 404 405 static inline const char* GetRelocTypeName(RelocType reloc) { 406 return static_cast<size_t>(reloc) < kRelocTypeCount 407 ? g_reloc_type_name[static_cast<size_t>(reloc)] 408 : "<error_reloc_type>"; 409 } 410 411 /* symbol */ 412 413 static inline const char* GetSymbolTypeName(SymbolType type) { 414 switch (type) { 415 case SymbolType::Function: 416 return "func"; 417 case SymbolType::Global: 418 return "global"; 419 case SymbolType::Data: 420 return "data"; 421 case SymbolType::Section: 422 return "section"; 423 case SymbolType::Tag: 424 return "tag"; 425 case SymbolType::Table: 426 return "table"; 427 default: 428 return "<error_symbol_type>"; 429 } 430 } 431 432 template <typename T> 433 void ConvertBackslashToSlash(T begin, T end) { 434 std::replace(begin, end, '\\', '/'); 435 } 436 437 inline void ConvertBackslashToSlash(char* s, size_t length) { 438 ConvertBackslashToSlash(s, s + length); 439 } 440 441 inline void ConvertBackslashToSlash(char* s) { 442 ConvertBackslashToSlash(s, strlen(s)); 443 } 444 445 inline void ConvertBackslashToSlash(std::string* s) { 446 ConvertBackslashToSlash(s->begin(), s->end()); 447 } 448 449 inline void SwapBytesSized(void* addr, size_t size) { 450 auto bytes = static_cast<uint8_t*>(addr); 451 for (size_t i = 0; i < size / 2; i++) { 452 std::swap(bytes[i], bytes[size - 1 - i]); 453 } 454 } 455 456 } // namespace wabt 457 458 #endif // WABT_COMMON_H_