v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
safe_math_clang_gcc_impl.h
Go to the documentation of this file.
1// Copyright 2017 The Chromium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Slightly adapted for inclusion in V8.
6// Copyright 2025 the V8 project authors. All rights reserved.
7
8#ifndef V8_BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
9#define V8_BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
10
11// IWYU pragma: private
12
13#include <stdint.h>
14
15#include <limits>
16#include <type_traits>
17
19
20#if !defined(__native_client__) && (defined(__ARMEL__) || defined(__arch64__))
21#include "src/base/numerics/safe_math_arm_impl.h" // IWYU pragma: export
22#define BASE_HAS_ASSEMBLER_SAFE_MATH (1)
23#else
24#define BASE_HAS_ASSEMBLER_SAFE_MATH (0)
25#endif
26
27namespace v8::base {
28namespace internal {
29
30// These are the non-functioning boilerplate implementations of the optimized
31// safe math routines.
32#if !BASE_HAS_ASSEMBLER_SAFE_MATH
33template <typename T, typename U>
35 static const bool is_supported = false;
36 template <typename V>
37 static constexpr bool Do(T, U, V*) {
38 // Force a compile failure if instantiated.
39 return CheckOnFailure::template HandleFailure<bool>();
40 }
41};
42
43template <typename T, typename U>
45 static const bool is_supported = false;
46 template <typename V>
47 static constexpr V Do(T, U) {
48 // Force a compile failure if instantiated.
49 return CheckOnFailure::template HandleFailure<V>();
50 }
51};
52
53template <typename T, typename U>
55 static const bool is_supported = false;
56 template <typename V>
57 static constexpr V Do(T, U) {
58 // Force a compile failure if instantiated.
59 return CheckOnFailure::template HandleFailure<V>();
60 }
61};
62
63template <typename T, typename U>
65 static const bool is_supported = false;
66 template <typename V>
67 static constexpr V Do(T, U) {
68 // Force a compile failure if instantiated.
69 return CheckOnFailure::template HandleFailure<V>();
70 }
71};
72#endif // BASE_HAS_ASSEMBLER_SAFE_MATH
73#undef BASE_HAS_ASSEMBLER_SAFE_MATH
74
75template <typename T, typename U>
76struct CheckedAddFastOp {
77 static const bool is_supported = true;
78 template <typename V>
79 __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
80 return !__builtin_add_overflow(x, y, result);
81 }
82};
83
84template <typename T, typename U>
85struct CheckedSubFastOp {
86 static const bool is_supported = true;
87 template <typename V>
88 __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
89 return !__builtin_sub_overflow(x, y, result);
90 }
91};
92
93template <typename T, typename U>
94struct CheckedMulFastOp {
95#if defined(__clang__)
96 // TODO(jschuh): Get the Clang runtime library issues sorted out so we can
97 // support full-width, mixed-sign multiply builtins.
98 // https://crbug.com/613003
99 // We can support intptr_t, uintptr_t, or a smaller common type.
100 static const bool is_supported =
101 (kIsTypeInRangeForNumericType<intptr_t, T> &&
102 kIsTypeInRangeForNumericType<intptr_t, U>) ||
103 (kIsTypeInRangeForNumericType<uintptr_t, T> &&
104 kIsTypeInRangeForNumericType<uintptr_t, U>);
105#else
106 static const bool is_supported = true;
107#endif
108 template <typename V>
109 __attribute__((always_inline)) static constexpr bool Do(T x, U y, V* result) {
112 : !__builtin_mul_overflow(x, y, result);
113 }
114};
115
116template <typename T, typename U>
117struct ClampedAddFastOp {
119 template <typename V>
120 __attribute__((always_inline)) static V Do(T x, U y) {
122 }
123};
124
125template <typename T, typename U>
126struct ClampedSubFastOp {
128 template <typename V>
129 __attribute__((always_inline)) static V Do(T x, U y) {
131 }
132};
133
134template <typename T, typename U>
135struct ClampedMulFastOp {
137 template <typename V>
138 __attribute__((always_inline)) static V Do(T x, U y) {
140 }
141};
142
143template <typename T>
144struct ClampedNegFastOp {
145 static const bool is_supported = std::is_signed_v<T>;
146 __attribute__((always_inline)) static T Do(T value) {
147 // Use this when there is no assembler path available.
149 T result;
150 return !__builtin_sub_overflow(T(0), value, &result)
151 ? result
152 : std::numeric_limits<T>::max();
153 }
154
155 // Fallback to the normal subtraction path.
156 return ClampedSubFastOp<T, T>::template Do<T>(T(0), value);
157 }
158};
159
160} // namespace internal
161} // namespace v8::base
162
163#endif // V8_BASE_NUMERICS_SAFE_MATH_CLANG_GCC_IMPL_H_
#define V(Name)
#define T
ZoneVector< RpoNumber > & result
int x
__attribute__((always_inline)) static const expr bool Do(T x
static constexpr bool Do(T, U, V *)
static constexpr bool Do(T x, U y, V *result)
__attribute__((always_inline)) static const expr bool Do(T x
static constexpr bool Do(T, U, V *)
static constexpr bool Do(T, U, V *)
__attribute__((always_inline)) static const expr bool Do(T x
__attribute__((always_inline)) static V Do(T x
__attribute__((always_inline)) static V Do(T x
__attribute__((always_inline)) static T Do(T value)
__attribute__((always_inline)) static V Do(T x