1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_PLATFORM_GLOBALS_H_
6#define RUNTIME_PLATFORM_GLOBALS_H_
7
8#if __cplusplus >= 201703L // C++17
9#define FALL_THROUGH [[fallthrough]] // NOLINT
10#elif defined(__GNUC__) && __GNUC__ >= 7
11#define FALL_THROUGH __attribute__((fallthrough));
12#elif defined(__clang__)
13#define FALL_THROUGH [[clang::fallthrough]] // NOLINT
14#else
15#define FALL_THROUGH ((void)0)
16#endif
17
18#if !defined(NDEBUG) && !defined(DEBUG)
19#if defined(GOOGLE3)
20// google3 builds use NDEBUG to indicate non-debug builds which is different
21// from the way the Dart project expects it: DEBUG indicating a debug build.
22#define DEBUG
23#else
24// Since <cassert> uses NDEBUG to signify that assert() macros should be turned
25// off, we'll define it when DEBUG is _not_ set.
26#define NDEBUG
27#endif // GOOGLE3
28#endif // !NDEBUG && !DEBUG
29
30// __STDC_FORMAT_MACROS has to be defined before including <inttypes.h> to
31// enable platform independent printf format specifiers.
32#ifndef __STDC_FORMAT_MACROS
33#define __STDC_FORMAT_MACROS
34#endif
35
36#if defined(_WIN32)
37// Cut down on the amount of stuff that gets included via windows.h.
38#if !defined(WIN32_LEAN_AND_MEAN)
39#define WIN32_LEAN_AND_MEAN
40#endif
41
42#if !defined(NOMINMAX)
43#define NOMINMAX
44#endif
45
46#if !defined(NOKERNEL)
47#define NOKERNEL
48#endif
49
50#if !defined(NOSERVICE)
51#define NOSERVICE
52#endif
53
54#if !defined(NOSOUND)
55#define NOSOUND
56#endif
57
58#if !defined(NOMCX)
59#define NOMCX
60#endif
61
62#if !defined(UNICODE)
63#define _UNICODE
64#define UNICODE
65#endif
66
67#include <Rpc.h>
68#include <VersionHelpers.h>
69#include <intrin.h>
70#include <shellapi.h>
71#include <windows.h>
72#include <winsock2.h>
73#endif // defined(_WIN32)
74
75#if !defined(_WIN32)
76#include <arpa/inet.h>
77#include <unistd.h>
78#endif // !defined(_WIN32)
79
80#include <float.h>
81#include <inttypes.h>
82#include <limits.h>
83#include <math.h>
84#include <stdarg.h>
85#include <stddef.h>
86#include <stdint.h>
87#include <stdio.h>
88#include <stdlib.h>
89#include <string.h>
90#include <sys/types.h>
91
92#include <cassert> // For assert() in constant expressions.
93
94#if defined(_WIN32)
95#include "platform/floating_point_win.h"
96#endif // defined(_WIN32)
97
98#if !defined(_WIN32)
99#include "platform/floating_point.h"
100#endif // !defined(_WIN32)
101
102// Target OS detection.
103// for more information on predefined macros:
104// - http://msdn.microsoft.com/en-us/library/b0084kay.aspx
105// - with gcc, run: "echo | gcc -E -dM -"
106#if defined(__ANDROID__)
107
108// Check for Android first, to determine its difference from Linux.
109#define DART_HOST_OS_ANDROID 1
110
111#elif defined(__linux__) || defined(__FreeBSD__)
112
113// Generic Linux.
114#define DART_HOST_OS_LINUX 1
115
116#elif defined(__APPLE__)
117
118// Define the flavor of Mac OS we are running on.
119#include <TargetConditionals.h>
120#define DART_HOST_OS_MACOS 1
121#if TARGET_OS_IPHONE
122#define DART_HOST_OS_IOS 1
123#endif
124
125#elif defined(_WIN32)
126
127// Windows, both 32- and 64-bit, regardless of the check for _WIN32.
128#define DART_HOST_OS_WINDOWS 1
129
130#elif defined(__Fuchsia__)
131#define DART_HOST_OS_FUCHSIA
132
133#elif !defined(DART_HOST_OS_FUCHSIA)
134#error Automatic target os detection failed.
135#endif
136
137#if defined(DEBUG)
138#define DEBUG_ONLY(code) code
139#else // defined(DEBUG)
140#define DEBUG_ONLY(code)
141#endif // defined(DEBUG)
142
143namespace dart {
144
145struct simd128_value_t {
146 union {
147 int32_t int_storage[4];
148 int64_t int64_storage[2];
149 float float_storage[4];
150 double double_storage[2];
151 };
152 simd128_value_t& readFrom(const float* v) {
153 float_storage[0] = v[0];
154 float_storage[1] = v[1];
155 float_storage[2] = v[2];
156 float_storage[3] = v[3];
157 return *this;
158 }
159 simd128_value_t& readFrom(const int32_t* v) {
160 int_storage[0] = v[0];
161 int_storage[1] = v[1];
162 int_storage[2] = v[2];
163 int_storage[3] = v[3];
164 return *this;
165 }
166 simd128_value_t& readFrom(const double* v) {
167 double_storage[0] = v[0];
168 double_storage[1] = v[1];
169 return *this;
170 }
171 simd128_value_t& readFrom(const simd128_value_t* v) {
172 *this = *v;
173 return *this;
174 }
175 void writeTo(float* v) {
176 v[0] = float_storage[0];
177 v[1] = float_storage[1];
178 v[2] = float_storage[2];
179 v[3] = float_storage[3];
180 }
181 void writeTo(int32_t* v) {
182 v[0] = int_storage[0];
183 v[1] = int_storage[1];
184 v[2] = int_storage[2];
185 v[3] = int_storage[3];
186 }
187 void writeTo(double* v) {
188 v[0] = double_storage[0];
189 v[1] = double_storage[1];
190 }
191 void writeTo(simd128_value_t* v) { *v = *this; }
192};
193
194// Processor architecture detection. For more info on what's defined, see:
195// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
196// http://www.agner.org/optimize/calling_conventions.pdf
197// or with gcc, run: "echo | gcc -E -dM -"
198#if defined(_M_X64) || defined(__x86_64__)
199#define HOST_ARCH_X64 1
200#define ARCH_IS_64_BIT 1
201#elif defined(_M_IX86) || defined(__i386__)
202#define HOST_ARCH_IA32 1
203#define ARCH_IS_32_BIT 1
204#elif defined(_M_ARM) || defined(__ARMEL__)
205#define HOST_ARCH_ARM 1
206#define ARCH_IS_32_BIT 1
207#elif defined(_M_ARM64) || defined(__aarch64__)
208#define HOST_ARCH_ARM64 1
209#define ARCH_IS_64_BIT 1
210#elif defined(__riscv)
211#if __SIZEOF_POINTER__ == 4
212#define HOST_ARCH_RISCV32 1
213#define ARCH_IS_32_BIT 1
214#elif __SIZEOF_POINTER__ == 8
215#define HOST_ARCH_RISCV64 1
216#define ARCH_IS_64_BIT 1
217#else
218#error Unknown XLEN
219#endif
220#else
221#error Architecture was not detected as supported by Dart.
222#endif
223
224// DART_FORCE_INLINE strongly hints to the compiler that a function should
225// be inlined. Your function is not guaranteed to be inlined but this is
226// stronger than just using "inline".
227// See: http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx for an
228// explanation of some the cases when a function can never be inlined.
229#ifdef _MSC_VER
230#define DART_FORCE_INLINE __forceinline
231#elif __GNUC__
232#define DART_FORCE_INLINE inline __attribute__((always_inline))
233#else
234#error Automatic compiler detection failed.
235#endif
236
237// DART_NOINLINE tells compiler to never inline a particular function.
238#ifdef _MSC_VER
239#define DART_NOINLINE __declspec(noinline)
240#elif __GNUC__
241#define DART_NOINLINE __attribute__((noinline))
242#else
243#error Automatic compiler detection failed.
244#endif
245
246#ifdef _MSC_VER
247#elif __GNUC__
248#define DART_HAS_COMPUTED_GOTO 1
249#else
250#error Automatic compiler detection failed.
251#endif
252
253// LIKELY/UNLIKELY give the compiler branch predictions that may affect block
254// scheduling.
255#ifdef __GNUC__
256#define LIKELY(cond) __builtin_expect((cond), 1)
257#define UNLIKELY(cond) __builtin_expect((cond), 0)
258#else
259#define LIKELY(cond) cond
260#define UNLIKELY(cond) cond
261#endif
262
263// DART_UNUSED indicates to the compiler that a variable or typedef is expected
264// to be unused and disables the related warning.
265#ifdef __GNUC__
266#define DART_UNUSED __attribute__((unused))
267#else
268#define DART_UNUSED
269#endif
270
271// DART_USED indicates to the compiler that a global variable or typedef is used
272// disables e.g. the gcc warning "unused-variable"
273#ifdef __GNUC__
274#define DART_USED __attribute__((used))
275#else
276#define DART_USED
277#endif
278
279// DART_NORETURN indicates to the compiler that a function does not return.
280// It should be used on functions that unconditionally call functions like
281// exit(), which end the program. We use it to avoid compiler warnings in
282// callers of DART_NORETURN functions.
283#ifdef _MSC_VER
284#define DART_NORETURN __declspec(noreturn)
285#elif __GNUC__
286#define DART_NORETURN __attribute__((noreturn))
287#else
288#error Automatic compiler detection failed.
289#endif
290
291#ifdef _MSC_VER
292#define DART_PRETTY_FUNCTION __FUNCSIG__
293#elif __GNUC__
294#define DART_PRETTY_FUNCTION __PRETTY_FUNCTION__
295#else
296#error Automatic compiler detection failed.
297#endif
298
299#if !defined(TARGET_ARCH_ARM) && !defined(TARGET_ARCH_X64) && \
300 !defined(TARGET_ARCH_IA32) && !defined(TARGET_ARCH_ARM64) && \
301 !defined(TARGET_ARCH_RISCV32) && !defined(TARGET_ARCH_RISCV64)
302// No target architecture specified pick the one matching the host architecture.
303#if defined(HOST_ARCH_ARM)
304#define TARGET_ARCH_ARM 1
305#elif defined(HOST_ARCH_X64)
306#define TARGET_ARCH_X64 1
307#elif defined(HOST_ARCH_IA32)
308#define TARGET_ARCH_IA32 1
309#elif defined(HOST_ARCH_ARM64)
310#define TARGET_ARCH_ARM64 1
311#elif defined(HOST_ARCH_RISCV32)
312#define TARGET_ARCH_RISCV32 1
313#elif defined(HOST_ARCH_RISCV64)
314#define TARGET_ARCH_RISCV64 1
315#else
316#error Automatic target architecture detection failed.
317#endif
318#endif
319
320#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \
321 defined(TARGET_ARCH_RISCV32)
322#define TARGET_ARCH_IS_32_BIT 1
323#elif defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \
324 defined(TARGET_ARCH_RISCV64)
325#define TARGET_ARCH_IS_64_BIT 1
326#else
327#error Automatic target architecture detection failed.
328#endif
329
330#if defined(TARGET_ARCH_IS_64_BIT) && !defined(DART_COMPRESSED_POINTERS)
331#define HAS_SMI_63_BITS 1
332#endif
333
334// Verify that host and target architectures match, we cannot
335// have a 64 bit Dart VM generating 32 bit code or vice-versa.
336#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_ARM64) || \
337 defined(TARGET_ARCH_RISCV64)
338#if !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
339#error Mismatched Host/Target architectures.
340#endif // !defined(ARCH_IS_64_BIT) && !defined(FFI_UNIT_TESTS)
341#elif defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM) || \
342 defined(TARGET_ARCH_RISCV32)
343#if defined(ARCH_IS_64_BIT) && defined(TARGET_ARCH_ARM)
344// This is simarm_x64 or simarm_arm64, which is the only case where host/target
345// architecture mismatch is allowed. Unless, we're running FFI unit tests.
346#define IS_SIMARM_HOST64 1
347#elif !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
348#error Mismatched Host/Target architectures.
349#endif // !defined(ARCH_IS_32_BIT) && !defined(FFI_UNIT_TESTS)
350#endif // defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
351
352// Determine whether we will be using the simulator.
353#if defined(TARGET_ARCH_IA32)
354#if !defined(HOST_ARCH_IA32)
355#define USING_SIMULATOR 1
356#endif
357#elif defined(TARGET_ARCH_X64)
358#if !defined(HOST_ARCH_X64)
359#define USING_SIMULATOR 1
360#endif
361#elif defined(TARGET_ARCH_ARM)
362#if !defined(HOST_ARCH_ARM)
363#define TARGET_HOST_MISMATCH 1
364#if !defined(IS_SIMARM_HOST64)
365#define USING_SIMULATOR 1
366#endif
367#endif
368#elif defined(TARGET_ARCH_ARM64)
369#if !defined(HOST_ARCH_ARM64)
370#define USING_SIMULATOR 1
371#endif
372#elif defined(TARGET_ARCH_RISCV32)
373#if !defined(HOST_ARCH_RISCV32)
374#define USING_SIMULATOR 1
375#endif
376#elif defined(TARGET_ARCH_RISCV64)
377#if !defined(HOST_ARCH_RISCV64)
378#define USING_SIMULATOR 1
379#endif
380#else
381#error Unknown architecture.
382#endif
383
384#if !defined(DART_TARGET_OS_ANDROID) && !defined(DART_TARGET_OS_FUCHSIA) && \
385 !defined(DART_TARGET_OS_MACOS_IOS) && !defined(DART_TARGET_OS_LINUX) && \
386 !defined(DART_TARGET_OS_MACOS) && !defined(DART_TARGET_OS_WINDOWS)
387// No target OS specified; pick the one matching the host OS.
388#if defined(DART_HOST_OS_ANDROID)
389#define DART_TARGET_OS_ANDROID 1
390#elif defined(DART_HOST_OS_FUCHSIA)
391#define DART_TARGET_OS_FUCHSIA 1
392#elif defined(DART_HOST_OS_IOS)
393#define DART_TARGET_OS_MACOS 1
394#define DART_TARGET_OS_MACOS_IOS 1
395#elif defined(DART_HOST_OS_LINUX)
396#define DART_TARGET_OS_LINUX 1
397#elif defined(DART_HOST_OS_MACOS)
398#define DART_TARGET_OS_MACOS 1
399#elif defined(DART_HOST_OS_WINDOWS)
400#define DART_TARGET_OS_WINDOWS 1
401#else
402#error Automatic target OS detection failed.
403#endif
404#endif
405
406// Determine whether dual mapping of code pages is supported.
407// We test dual mapping on linux x64 and deploy it on fuchsia.
408#if !defined(DART_PRECOMPILED_RUNTIME) && \
409 (defined(DART_TARGET_OS_LINUX) && defined(TARGET_ARCH_X64) || \
410 defined(DART_TARGET_OS_FUCHSIA))
411#define DUAL_MAPPING_SUPPORTED 1
412#endif
413
414// Short form printf format specifiers
415#define Pd PRIdPTR
416#define Pu PRIuPTR
417#define Px PRIxPTR
418#define PX PRIXPTR
419#define Pd32 PRId32
420#define Pu32 PRIu32
421#define Px32 PRIx32
422#define PX32 PRIX32
423#define Pd64 PRId64
424#define Pu64 PRIu64
425#define Px64 PRIx64
426#define PX64 PRIX64
427
428// Zero-padded pointer
429#if defined(ARCH_IS_32_BIT)
430#define Pp "08" PRIxPTR
431#else
432#define Pp "016" PRIxPTR
433#endif
434
435// Suffixes for 64-bit integer literals.
436#ifdef _MSC_VER
437#define DART_INT64_C(x) x##I64
438#define DART_UINT64_C(x) x##UI64
439#else
440#define DART_INT64_C(x) x##LL
441#define DART_UINT64_C(x) x##ULL
442#endif
443
444// Replace calls to strtoll with _strtoi64 on Windows.
445#ifdef _MSC_VER
446#define strtoll _strtoi64
447#endif
448
449// Byte sizes.
450constexpr int kInt8SizeLog2 = 0;
451constexpr int kInt8Size = 1 << kInt8SizeLog2;
452static_assert(kInt8Size == sizeof(int8_t), "Mismatched int8 size constant");
453constexpr int kInt16SizeLog2 = 1;
454constexpr int kInt16Size = 1 << kInt16SizeLog2;
455static_assert(kInt16Size == sizeof(int16_t), "Mismatched int16 size constant");
456constexpr int kInt32SizeLog2 = 2;
457constexpr int kInt32Size = 1 << kInt32SizeLog2;
458static_assert(kInt32Size == sizeof(int32_t), "Mismatched int32 size constant");
459constexpr int kInt64SizeLog2 = 3;
460constexpr int kInt64Size = 1 << kInt64SizeLog2;
461static_assert(kInt64Size == sizeof(int64_t), "Mismatched int64 size constant");
462
463constexpr int kDoubleSize = sizeof(double);
464constexpr int kFloatSize = sizeof(float);
465constexpr int kQuadSize = 4 * kFloatSize;
466constexpr int kSimd128Size = sizeof(simd128_value_t);
467
468// Bit sizes.
469constexpr int kBitsPerByteLog2 = 3;
470constexpr int kBitsPerByte = 1 << kBitsPerByteLog2;
471constexpr int kBitsPerInt8 = kInt8Size * kBitsPerByte;
472constexpr int kBitsPerInt16 = kInt16Size * kBitsPerByte;
473constexpr int kBitsPerInt32 = kInt32Size * kBitsPerByte;
474constexpr int kBitsPerInt64 = kInt64Size * kBitsPerByte;
475
476// The following macro works on both 32 and 64-bit platforms.
477// Usage: instead of writing 0x1234567890123456ULL
478// write DART_2PART_UINT64_C(0x12345678,90123456);
479#define DART_2PART_UINT64_C(a, b) \
480 (((static_cast<uint64_t>(a) << kBitsPerInt32) + 0x##b##u))
481
482// Integer constants.
483constexpr int8_t kMinInt8 = 0x80;
484constexpr int8_t kMaxInt8 = 0x7F;
485constexpr uint8_t kMaxUint8 = 0xFF;
486constexpr int16_t kMinInt16 = 0x8000;
487constexpr int16_t kMaxInt16 = 0x7FFF;
488constexpr uint16_t kMaxUint16 = 0xFFFF;
489constexpr int32_t kMinInt32 = 0x80000000;
490constexpr int32_t kMaxInt32 = 0x7FFFFFFF;
491constexpr uint32_t kMaxUint32 = 0xFFFFFFFF;
492constexpr int64_t kMinInt64 = DART_INT64_C(0x8000000000000000);
493constexpr int64_t kMaxInt64 = DART_INT64_C(0x7FFFFFFFFFFFFFFF);
494constexpr uint64_t kMaxUint64 = DART_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
495
496constexpr int kMinInt = INT_MIN;
497constexpr int kMaxInt = INT_MAX;
498constexpr int kMaxUint = UINT_MAX;
499
500constexpr int64_t kMinInt64RepresentableAsDouble = kMinInt64;
501constexpr int64_t kMaxInt64RepresentableAsDouble =
502 DART_INT64_C(0x7FFFFFFFFFFFFC00);
503constexpr int64_t kSignBitDouble = DART_INT64_C(0x8000000000000000);
504
505// Types for native machine words. Guaranteed to be able to hold pointers and
506// integers.
507typedef intptr_t word;
508typedef uintptr_t uword;
509
510// Byte sizes for native machine words.
511#ifdef ARCH_IS_32_BIT
512constexpr int kWordSizeLog2 = kInt32SizeLog2;
513#else
514constexpr int kWordSizeLog2 = kInt64SizeLog2;
515#endif
516constexpr int kWordSize = 1 << kWordSizeLog2;
517static_assert(kWordSize == sizeof(word), "Mismatched word size constant");
518
519// Bit sizes for native machine words.
520constexpr int kBitsPerWordLog2 = kWordSizeLog2 + kBitsPerByteLog2;
521constexpr int kBitsPerWord = 1 << kBitsPerWordLog2;
522
523// Integer constants for native machine words.
524constexpr word kWordMin = static_cast<uword>(1) << (kBitsPerWord - 1);
525constexpr word kWordMax = (static_cast<uword>(1) << (kBitsPerWord - 1)) - 1;
526constexpr uword kUwordMax = static_cast<uword>(-1);
527
528// Size of a class id assigned to concrete, abstract and top-level classes.
529//
530// We use a signed integer type here to make it comparable with intptr_t.
531typedef int32_t classid_t;
532
533// System-wide named constants.
534constexpr intptr_t KBLog2 = 10;
535constexpr intptr_t KB = 1 << KBLog2;
536constexpr intptr_t MBLog2 = KBLog2 + KBLog2;
537constexpr intptr_t MB = 1 << MBLog2;
538constexpr intptr_t GBLog2 = MBLog2 + KBLog2;
539constexpr intptr_t GB = 1 << GBLog2;
540
541constexpr intptr_t KBInWordsLog2 = KBLog2 - kWordSizeLog2;
542constexpr intptr_t KBInWords = 1 << KBInWordsLog2;
543constexpr intptr_t MBInWordsLog2 = KBLog2 + KBInWordsLog2;
544constexpr intptr_t MBInWords = 1 << MBInWordsLog2;
545constexpr intptr_t GBInWordsLog2 = MBLog2 + KBInWordsLog2;
546constexpr intptr_t GBInWords = 1 << GBInWordsLog2;
547
548// Helpers to round memory sizes to human readable values.
549constexpr intptr_t RoundWordsToKB(intptr_t size_in_words) {
550 return (size_in_words + (KBInWords >> 1)) >> KBInWordsLog2;
551}
552constexpr intptr_t RoundWordsToMB(intptr_t size_in_words) {
553 return (size_in_words + (MBInWords >> 1)) >> MBInWordsLog2;
554}
555constexpr intptr_t RoundWordsToGB(intptr_t size_in_words) {
556 return (size_in_words + (GBInWords >> 1)) >> GBInWordsLog2;
557}
558constexpr double WordsToMB(intptr_t size_in_words) {
559 return static_cast<double>(size_in_words) / MBInWords;
560}
561
562constexpr intptr_t kIntptrOne = 1;
563constexpr intptr_t kIntptrMin = (kIntptrOne << (kBitsPerWord - 1));
564constexpr intptr_t kIntptrMax = ~kIntptrMin;
565
566// Time constants.
567constexpr int kMillisecondsPerSecond = 1000;
568constexpr int kMicrosecondsPerMillisecond = 1000;
569constexpr int kMicrosecondsPerSecond =
570 (kMicrosecondsPerMillisecond * kMillisecondsPerSecond);
571constexpr int kNanosecondsPerMicrosecond = 1000;
572constexpr int kNanosecondsPerMillisecond =
573 (kNanosecondsPerMicrosecond * kMicrosecondsPerMillisecond);
574constexpr int kNanosecondsPerSecond =
575 (kNanosecondsPerMicrosecond * kMicrosecondsPerSecond);
576
577// Helpers to scale micro second times to human understandable values.
578constexpr double MicrosecondsToSeconds(int64_t micros) {
579 return static_cast<double>(micros) / kMicrosecondsPerSecond;
580}
581constexpr double MicrosecondsToMilliseconds(int64_t micros) {
582 return static_cast<double>(micros) / kMicrosecondsPerMillisecond;
583}
584
585// A macro to disallow the copy constructor and operator= functions.
586// This should be used in the private: declarations for a class.
587#if !defined(DISALLOW_COPY_AND_ASSIGN)
588#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
589 private: \
590 TypeName(const TypeName&) = delete; \
591 void operator=(const TypeName&) = delete
592#endif // !defined(DISALLOW_COPY_AND_ASSIGN)
593
594// A macro to disallow all the implicit constructors, namely the default
595// constructor, copy constructor and operator= functions. This should be
596// used in the private: declarations for a class that wants to prevent
597// anyone from instantiating it. This is especially useful for classes
598// containing only static methods.
599#if !defined(DISALLOW_IMPLICIT_CONSTRUCTORS)
600#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
601 private: \
602 TypeName() = delete; \
603 DISALLOW_COPY_AND_ASSIGN(TypeName)
604#endif // !defined(DISALLOW_IMPLICIT_CONSTRUCTORS)
605
606// Macro to disallow allocation in the C++ heap. This should be used
607// in the private section for a class. Don't use UNREACHABLE here to
608// avoid circular dependencies between platform/globals.h and
609// platform/assert.h.
610#if !defined(DISALLOW_ALLOCATION)
611#define DISALLOW_ALLOCATION() \
612 public: \
613 void operator delete(void* pointer) { \
614 fprintf(stderr, "unreachable code\n"); \
615 abort(); \
616 } \
617 \
618 private: \
619 void* operator new(size_t size);
620#endif // !defined(DISALLOW_ALLOCATION)
621
622// The USE(x) template is used to silence C++ compiler warnings issued
623// for unused variables.
624template <typename T>
625static inline void USE(T&&) {}
626
627// The type-based aliasing rule allows the compiler to assume that
628// pointers of different types (for some definition of different)
629// never alias each other. Thus the following code does not work:
630//
631// float f = foo();
632// int fbits = *(int*)(&f);
633//
634// The compiler 'knows' that the int pointer can't refer to f since
635// the types don't match, so the compiler may cache f in a register,
636// leaving random data in fbits. Using C++ style casts makes no
637// difference, however a pointer to char data is assumed to alias any
638// other pointer. This is the 'memcpy exception'.
639//
640// The bit_cast function uses the memcpy exception to move the bits
641// from a variable of one type to a variable of another type. Of
642// course the end result is likely to be implementation dependent.
643// Most compilers (gcc-4.2 and MSVC 2005) will completely optimize
644// bit_cast away.
645//
646// There is an additional use for bit_cast. Recent gccs will warn when
647// they see casts that may result in breakage due to the type-based
648// aliasing rule. If you have checked that there is no breakage you
649// can use bit_cast to cast one pointer type to another. This confuses
650// gcc enough that it can no longer see that you have cast one pointer
651// type to another thus avoiding the warning.
652template <class D, class S>
653DART_FORCE_INLINE D bit_cast(const S& source) {
654 static_assert(sizeof(D) == sizeof(S),
655 "Source and destination must have the same size");
656
657 D destination;
658 // This use of memcpy is safe: source and destination cannot overlap.
659 memcpy(&destination, &source, sizeof(destination));
660 return destination;
661}
662
663// Similar to bit_cast, but allows copying from types of unrelated
664// sizes. This method was introduced to enable the strict aliasing
665// optimizations of GCC 4.4. Basically, GCC mindlessly relies on
666// obscure details in the C++ standard that make reinterpret_cast
667// virtually useless.
668template <class D, class S>
669DART_FORCE_INLINE D bit_copy(const S& source) {
670 D destination;
671 // This use of memcpy is safe: source and destination cannot overlap.
672 memcpy(&destination, reinterpret_cast<const void*>(&source),
673 sizeof(destination));
674 return destination;
675}
676
677// On Windows the reentrant version of strtok is called
678// strtok_s. Unify on the posix name strtok_r.
679#if defined(DART_HOST_OS_WINDOWS)
680#define snprintf _sprintf_p
681#define strtok_r strtok_s
682#endif
683
684#if !defined(DART_HOST_OS_WINDOWS)
685#if defined(TEMP_FAILURE_RETRY)
686// TEMP_FAILURE_RETRY is defined in unistd.h on some platforms. We should
687// not use that version, but instead the one in signal_blocker.h, to ensure
688// we disable signal interrupts.
689#undef TEMP_FAILURE_RETRY
690#endif // defined(TEMP_FAILURE_RETRY)
691#endif // !defined(DART_HOST_OS_WINDOWS)
692
693#if __GNUC__
694// Tell the compiler to do printf format string checking if the
695// compiler supports it; see the 'format' attribute in
696// <http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html>.
697//
698// N.B.: As the GCC manual states, "[s]ince non-static C++ methods
699// have an implicit 'this' argument, the arguments of such methods
700// should be counted from two, not one."
701#define PRINTF_ATTRIBUTE(string_index, first_to_check) \
702 __attribute__((__format__(__printf__, string_index, first_to_check)))
703#else
704#define PRINTF_ATTRIBUTE(string_index, first_to_check)
705#endif
706
707#if defined(_WIN32)
708#define STDIN_FILENO 0
709#define STDOUT_FILENO 1
710#define STDERR_FILENO 2
711#endif
712
713#ifndef PATH_MAX
714// Most platforms use PATH_MAX, but in Windows it's called MAX_PATH.
715#define PATH_MAX MAX_PATH
716#endif
717
718// Undefine math.h definition which clashes with our condition names.
719#undef OVERFLOW
720
721// Include IL printer and disassembler functionality into non-PRODUCT builds,
722// in all AOT compiler builds or when forced.
723#if !defined(PRODUCT) || defined(DART_PRECOMPILER) || \
724 defined(FORCE_INCLUDE_DISASSEMBLER)
725#if defined(DART_PRECOMPILED_RUNTIME) && defined(PRODUCT)
726#error Requested to include IL printer into PRODUCT AOT runtime
727#endif
728#define INCLUDE_IL_PRINTER 1
729#if !defined(FORCE_INCLUDE_DISASSEMBLER)
730#define FORCE_INCLUDE_DISASSEMBLER 1
731#endif
732#endif
733
734// Include HeapSnapshotWriter functionality if not in PRODUCT.
735#if !defined(DART_ENABLE_HEAP_SNAPSHOT_WRITER) && !defined(PRODUCT)
736#define DART_ENABLE_HEAP_SNAPSHOT_WRITER 1
737#endif
738
739#if defined(DART_HOST_OS_ANDROID)
740#define kHostOperatingSystemName "android"
741#elif defined(DART_HOST_OS_FUCHSIA)
742#define kHostOperatingSystemName "fuchsia"
743#elif defined(DART_HOST_OS_IOS)
744#define kHostOperatingSystemName "ios"
745#elif defined(DART_HOST_OS_LINUX)
746#define kHostOperatingSystemName "linux"
747#elif defined(DART_HOST_OS_MACOS)
748#define kHostOperatingSystemName "macos"
749#elif defined(DART_HOST_OS_WINDOWS)
750#define kHostOperatingSystemName "windows"
751#else
752#error Host operating system detection failed.
753#endif
754
755#if defined(HOST_ARCH_ARM)
756#define kHostArchitectureName "arm"
757#elif defined(HOST_ARCH_ARM64)
758#define kHostArchitectureName "arm64"
759#elif defined(HOST_ARCH_IA32)
760#define kHostArchitectureName "ia32"
761#elif defined(HOST_ARCH_RISCV32)
762#define kHostArchitectureName "riscv32"
763#elif defined(HOST_ARCH_RISCV64)
764#define kHostArchitectureName "riscv64"
765#elif defined(HOST_ARCH_X64)
766#define kHostArchitectureName "x64"
767#else
768#error Host architecture detection failed.
769#endif
770
771#if defined(TARGET_ARCH_ARM)
772#define kTargetArchitectureName "arm"
773#elif defined(TARGET_ARCH_ARM64)
774#define kTargetArchitectureName "arm64"
775#elif defined(TARGET_ARCH_IA32)
776#define kTargetArchitectureName "ia32"
777#elif defined(TARGET_ARCH_RISCV32)
778#define kTargetArchitectureName "riscv32"
779#elif defined(TARGET_ARCH_RISCV64)
780#define kTargetArchitectureName "riscv64"
781#elif defined(TARGET_ARCH_X64)
782#define kTargetArchitectureName "x64"
783#else
784#error Target architecture detection failed.
785#endif
786
787// The ordering between DART_TARGET_OS_MACOS_IOS and DART_TARGET_OS_MACOS
788// below is important, since the latter is sometimes defined when the former
789// is, and sometimes not (e.g., ffi tests), so we need to test the former
790// before the latter.
791#if defined(DART_TARGET_OS_ANDROID)
792#define kTargetOperatingSystemName "android"
793#elif defined(DART_TARGET_OS_FUCHSIA)
794#define kTargetOperatingSystemName "fuchsia"
795#elif defined(DART_TARGET_OS_LINUX)
796#define kTargetOperatingSystemName "linux"
797#elif defined(DART_TARGET_OS_MACOS_IOS)
798#define kTargetOperatingSystemName "ios"
799#elif defined(DART_TARGET_OS_MACOS)
800#define kTargetOperatingSystemName "macos"
801#elif defined(DART_TARGET_OS_WINDOWS)
802#define kTargetOperatingSystemName "windows"
803#else
804#error Target operating system detection failed.
805#endif
806
807} // namespace dart
808
809#endif // RUNTIME_PLATFORM_GLOBALS_H_
810

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com

source code of flutter_engine/third_party/dart/runtime/platform/globals.h