Flutter Engine
The Flutter Engine
SkAssert.h
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkAssert_DEFINED
9#define SkAssert_DEFINED
10
13#include "include/private/base/SkDebug.h" // IWYU pragma: keep
14
15#include <cstddef>
16#include <limits>
17
18#if defined(__clang__) && defined(__has_attribute)
19 #if __has_attribute(likely)
20 #define SK_LIKELY [[likely]]
21 #define SK_UNLIKELY [[unlikely]]
22 #else
23 #define SK_LIKELY
24 #define SK_UNLIKELY
25 #endif
26#else
27 #define SK_LIKELY
28 #define SK_UNLIKELY
29#endif
30
31// c++23 will give us [[assume]] -- until then we're stuck with various other options:
32#if defined(__clang__)
33 #define SK_ASSUME(cond) __builtin_assume(cond)
34#elif defined(__GNUC__)
35 #if __GNUC__ >= 13
36 #define SK_ASSUME(cond) __attribute__((assume(cond)))
37 #else
38 // NOTE: This implementation could actually evaluate `cond`, which is not desirable.
39 #define SK_ASSUME(cond) ((cond) ? (void)0 : __builtin_unreachable())
40 #endif
41#elif defined(_MSC_VER)
42 #define SK_ASSUME(cond) __assume(cond)
43#else
44 #define SK_ASSUME(cond) ((void)0)
45#endif
46
47/** Called internally if we hit an unrecoverable error.
48 The platform implementation must not return, but should either throw
49 an exception or otherwise exit.
50*/
51[[noreturn]] SK_API extern void sk_abort_no_print(void);
52
53#if defined(SK_BUILD_FOR_GOOGLE3)
54 void SkDebugfForDumpStackTrace(const char* data, void* unused);
55 namespace base {
56 void DumpStackTrace(int skip_count, void w(const char*, void*), void* arg);
57 }
58# define SK_DUMP_GOOGLE3_STACK() ::base::DumpStackTrace(0, SkDebugfForDumpStackTrace, nullptr)
59#else
60# define SK_DUMP_GOOGLE3_STACK()
61#endif
62
63#if !defined(SK_ABORT)
64# if defined(SK_BUILD_FOR_WIN)
65 // This style lets Visual Studio follow errors back to the source file.
66# define SK_DUMP_LINE_FORMAT "%s(%d)"
67# else
68# define SK_DUMP_LINE_FORMAT "%s:%d"
69# endif
70# define SK_ABORT(message, ...) \
71 do { \
72 SkDebugf(SK_DUMP_LINE_FORMAT ": fatal error: \"" message "\"\n", \
73 __FILE__, __LINE__, ##__VA_ARGS__); \
74 SK_DUMP_GOOGLE3_STACK(); \
75 sk_abort_no_print(); \
76 } while (false)
77#endif
78
79// SkASSERT, SkASSERTF and SkASSERT_RELEASE can be used as standalone assertion expressions, e.g.
80// uint32_t foo(int x) {
81// SkASSERT(x > 4);
82// return x - 4;
83// }
84// and are also written to be compatible with constexpr functions:
85// constexpr uint32_t foo(int x) {
86// return SkASSERT(x > 4),
87// x - 4;
88// }
89#if defined(__clang__)
90#define SkASSERT_RELEASE(cond) \
91 static_cast<void>( __builtin_expect(static_cast<bool>(cond), 1) \
92 ? static_cast<void>(0) \
93 : []{ SK_ABORT("check(%s)", #cond); }() )
94
95#define SkASSERTF_RELEASE(cond, fmt, ...) \
96 static_cast<void>( __builtin_expect(static_cast<bool>(cond), 1) \
97 ? static_cast<void>(0) \
98 : [&]{ SK_ABORT("assertf(%s): " fmt, #cond, ##__VA_ARGS__); }() )
99#else
100#define SkASSERT_RELEASE(cond) \
101 static_cast<void>( (cond) ? static_cast<void>(0) : []{ SK_ABORT("check(%s)", #cond); }() )
102
103#define SkASSERTF_RELEASE(cond, fmt, ...) \
104 static_cast<void>( (cond) \
105 ? static_cast<void>(0) \
106 : [&]{ SK_ABORT("assertf(%s): " fmt, #cond, ##__VA_ARGS__); }() )
107#endif
108
109#if defined(SK_DEBUG)
110 #define SkASSERT(cond) SkASSERT_RELEASE(cond)
111 #define SkASSERTF(cond, fmt, ...) SkASSERTF_RELEASE(cond, fmt, ##__VA_ARGS__)
112 #define SkDEBUGFAIL(message) SK_ABORT("%s", message)
113 #define SkDEBUGFAILF(fmt, ...) SK_ABORT(fmt, ##__VA_ARGS__)
114 #define SkAssertResult(cond) SkASSERT(cond)
115#else
116 #define SkASSERT(cond) static_cast<void>(0)
117 #define SkASSERTF(cond, fmt, ...) static_cast<void>(0)
118 #define SkDEBUGFAIL(message)
119 #define SkDEBUGFAILF(fmt, ...)
120
121 // unlike SkASSERT, this macro executes its condition in the non-debug build.
122 // The if is present so that this can be used with functions marked [[nodiscard]].
123 #define SkAssertResult(cond) if (cond) {} do {} while(false)
124#endif
125
126#if !defined(SkUNREACHABLE)
127# if defined(_MSC_VER) && !defined(__clang__)
128# include <intrin.h>
129# define FAST_FAIL_INVALID_ARG 5
130// See https://developercommunity.visualstudio.com/content/problem/1128631/code-flow-doesnt-see-noreturn-with-extern-c.html
131// for why this is wrapped. Hopefully removable after msvc++ 19.27 is no longer supported.
132[[noreturn]] static inline void sk_fast_fail() { __fastfail(FAST_FAIL_INVALID_ARG); }
133# define SkUNREACHABLE sk_fast_fail()
134# else
135# define SkUNREACHABLE __builtin_trap()
136# endif
137#endif
138
139[[noreturn]] SK_API inline void sk_print_index_out_of_bounds(size_t i, size_t size) {
140 SK_ABORT("Index (%zu) out of bounds for size %zu.\n", i, size);
141}
142
143template <typename T> SK_API inline T sk_collection_check_bounds(T i, T size) {
144 if (0 <= i && i < size) SK_LIKELY {
145 return i;
146 }
147
149 #if defined(SK_DEBUG)
150 sk_print_index_out_of_bounds(static_cast<size_t>(i), static_cast<size_t>(size));
151 #else
153 #endif
154 }
155}
156
157[[noreturn]] SK_API inline void sk_print_length_too_big(size_t i, size_t size) {
158 SK_ABORT("Length (%zu) is too big for size %zu.\n", i, size);
159}
160
161template <typename T> SK_API inline T sk_collection_check_length(T i, T size) {
162 if (0 <= i && i <= size) SK_LIKELY {
163 return i;
164 }
165
167 #if defined(SK_DEBUG)
168 sk_print_length_too_big(static_cast<size_t>(i), static_cast<size_t>(size));
169 #else
171 #endif
172 }
173}
174
176 if (empty) SK_UNLIKELY {
177 #if defined(SK_DEBUG)
178 SK_ABORT("Collection is empty.\n");
179 #else
181 #endif
182 }
183}
184
185[[noreturn]] SK_API inline void sk_print_size_too_big(size_t size, size_t maxSize) {
186 SK_ABORT("Size (%zu) can't be represented in bytes. Max size is %zu.\n", size, maxSize);
187}
188
189template <typename T>
191 const size_t kMaxSize = std::numeric_limits<size_t>::max() / sizeof(T);
192 if (size > kMaxSize) {
193 #if defined(SK_DEBUG)
194 sk_print_size_too_big(size, kMaxSize);
195 #else
197 #endif
198 }
199 return size;
200}
201
202#endif // SkAssert_DEFINED
static bool unused
#define SK_API
Definition: SkAPI.h:35
#define SkUNREACHABLE
Definition: SkAssert.h:135
SK_ALWAYS_INLINE size_t check_size_bytes_too_big(size_t size)
Definition: SkAssert.h:190
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
SK_API void sk_collection_not_empty(bool empty)
Definition: SkAssert.h:175
SK_API void sk_print_size_too_big(size_t size, size_t maxSize)
Definition: SkAssert.h:185
SK_API void sk_abort_no_print(void)
SK_API T sk_collection_check_bounds(T i, T size)
Definition: SkAssert.h:143
SK_API void sk_print_length_too_big(size_t i, size_t size)
Definition: SkAssert.h:157
#define SK_LIKELY
Definition: SkAssert.h:27
SK_API void sk_print_index_out_of_bounds(size_t i, size_t size)
Definition: SkAssert.h:139
#define SK_UNLIKELY
Definition: SkAssert.h:28
SK_API T sk_collection_check_length(T i, T size)
Definition: SkAssert.h:161
#define SK_ALWAYS_INLINE
Definition: SkAttributes.h:30
EMSCRIPTEN_KEEPALIVE void empty()
static float max(float r, float g, float b)
Definition: hsl.cpp:49
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
SkScalar w
#define T
Definition: precompiler.cc:65
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63