Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/util/Preconditions.java
41159 views
1
/*
2
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package jdk.internal.util;
26
27
import jdk.internal.vm.annotation.IntrinsicCandidate;
28
29
import java.util.List;
30
import java.util.function.BiFunction;
31
import java.util.function.Function;
32
33
/**
34
* Utility methods to check if state or arguments are correct.
35
*
36
*/
37
public class Preconditions {
38
39
/**
40
* Maps out-of-bounds values to a runtime exception.
41
*
42
* @param checkKind the kind of bounds check, whose name may correspond
43
* to the name of one of the range check methods, checkIndex,
44
* checkFromToIndex, checkFromIndexSize
45
* @param args the out-of-bounds arguments that failed the range check.
46
* If the checkKind corresponds a the name of a range check method
47
* then the bounds arguments are those that can be passed in order
48
* to the method.
49
* @param oobef the exception formatter that when applied with a checkKind
50
* and a list out-of-bounds arguments returns a runtime exception.
51
* If {@code null} then, it is as if an exception formatter was
52
* supplied that returns {@link IndexOutOfBoundsException} for any
53
* given arguments.
54
* @return the runtime exception
55
*/
56
private static RuntimeException outOfBounds(
57
BiFunction<String, List<Number>, ? extends RuntimeException> oobef,
58
String checkKind,
59
Number... args) {
60
List<Number> largs = List.of(args);
61
RuntimeException e = oobef == null
62
? null : oobef.apply(checkKind, largs);
63
return e == null
64
? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
65
}
66
67
private static RuntimeException outOfBoundsCheckIndex(
68
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
69
int index, int length) {
70
return outOfBounds(oobe, "checkIndex", index, length);
71
}
72
73
private static RuntimeException outOfBoundsCheckFromToIndex(
74
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
75
int fromIndex, int toIndex, int length) {
76
return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
77
}
78
79
private static RuntimeException outOfBoundsCheckFromIndexSize(
80
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
81
int fromIndex, int size, int length) {
82
return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
83
}
84
85
private static RuntimeException outOfBoundsCheckIndex(
86
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
87
long index, long length) {
88
return outOfBounds(oobe, "checkIndex", index, length);
89
}
90
91
private static RuntimeException outOfBoundsCheckFromToIndex(
92
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
93
long fromIndex, long toIndex, long length) {
94
return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
95
}
96
97
private static RuntimeException outOfBoundsCheckFromIndexSize(
98
BiFunction<String, List<Number>, ? extends RuntimeException> oobe,
99
long fromIndex, long size, long length) {
100
return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
101
}
102
103
/**
104
* Returns an out-of-bounds exception formatter from an given exception
105
* factory. The exception formatter is a function that formats an
106
* out-of-bounds message from its arguments and applies that message to the
107
* given exception factory to produce and relay an exception.
108
*
109
* <p>The exception formatter accepts two arguments: a {@code String}
110
* describing the out-of-bounds range check that failed, referred to as the
111
* <em>check kind</em>; and a {@code List<Number>} containing the
112
* out-of-bound integral values that failed the check. The list of
113
* out-of-bound values is not modified.
114
*
115
* <p>Three check kinds are supported {@code checkIndex},
116
* {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
117
* respectively to the specified application of an exception formatter as an
118
* argument to the out-of-bounds range check methods
119
* {@link #checkIndex(int, int, BiFunction) checkIndex},
120
* {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
121
* {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
122
* Thus a supported check kind corresponds to a method name and the
123
* out-of-bound integral values correspond to method argument values, in
124
* order, preceding the exception formatter argument (similar in many
125
* respects to the form of arguments required for a reflective invocation of
126
* such a range check method).
127
*
128
* <p>Formatter arguments conforming to such supported check kinds will
129
* produce specific exception messages describing failed out-of-bounds
130
* checks. Otherwise, more generic exception messages will be produced in
131
* any of the following cases: the check kind is supported but fewer
132
* or more out-of-bounds values are supplied, the check kind is not
133
* supported, the check kind is {@code null}, or the list of out-of-bound
134
* values is {@code null}.
135
*
136
* @apiNote
137
* This method produces an out-of-bounds exception formatter that can be
138
* passed as an argument to any of the supported out-of-bounds range check
139
* methods declared by {@code Objects}. For example, a formatter producing
140
* an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
141
* {@code static final} field as follows:
142
* <pre>{@code
143
* static final
144
* BiFunction<String, List<Number>, ArrayIndexOutOfBoundsException> AIOOBEF =
145
* outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
146
* }</pre>
147
* The formatter instance {@code AIOOBEF} may be passed as an argument to an
148
* out-of-bounds range check method, such as checking if an {@code index}
149
* is within the bounds of a {@code limit}:
150
* <pre>{@code
151
* checkIndex(index, limit, AIOOBEF);
152
* }</pre>
153
* If the bounds check fails then the range check method will throw an
154
* {@code ArrayIndexOutOfBoundsException} with an appropriate exception
155
* message that is a produced from {@code AIOOBEF} as follows:
156
* <pre>{@code
157
* AIOOBEF.apply("checkIndex", List.of(index, limit));
158
* }</pre>
159
*
160
* @param f the exception factory, that produces an exception from a message
161
* where the message is produced and formatted by the returned
162
* exception formatter. If this factory is stateless and side-effect
163
* free then so is the returned formatter.
164
* Exceptions thrown by the factory are relayed to the caller
165
* of the returned formatter.
166
* @param <X> the type of runtime exception to be returned by the given
167
* exception factory and relayed by the exception formatter
168
* @return the out-of-bounds exception formatter
169
*/
170
public static <X extends RuntimeException>
171
BiFunction<String, List<Number>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
172
// Use anonymous class to avoid bootstrap issues if this method is
173
// used early in startup
174
return new BiFunction<String, List<Number>, X>() {
175
@Override
176
public X apply(String checkKind, List<Number> args) {
177
return f.apply(outOfBoundsMessage(checkKind, args));
178
}
179
};
180
}
181
182
private static String outOfBoundsMessage(String checkKind, List<? extends Number> args) {
183
if (checkKind == null && args == null) {
184
return String.format("Range check failed");
185
} else if (checkKind == null) {
186
return String.format("Range check failed: %s", args);
187
} else if (args == null) {
188
return String.format("Range check failed: %s", checkKind);
189
}
190
191
int argSize = 0;
192
switch (checkKind) {
193
case "checkIndex":
194
argSize = 2;
195
break;
196
case "checkFromToIndex":
197
case "checkFromIndexSize":
198
argSize = 3;
199
break;
200
default:
201
}
202
203
// Switch to default if fewer or more arguments than required are supplied
204
switch ((args.size() != argSize) ? "" : checkKind) {
205
case "checkIndex":
206
return String.format("Index %s out of bounds for length %s",
207
args.get(0), args.get(1));
208
case "checkFromToIndex":
209
return String.format("Range [%s, %s) out of bounds for length %s",
210
args.get(0), args.get(1), args.get(2));
211
case "checkFromIndexSize":
212
return String.format("Range [%s, %<s + %s) out of bounds for length %s",
213
args.get(0), args.get(1), args.get(2));
214
default:
215
return String.format("Range check failed: %s %s", checkKind, args);
216
}
217
}
218
219
/**
220
* Checks if the {@code index} is within the bounds of the range from
221
* {@code 0} (inclusive) to {@code length} (exclusive).
222
*
223
* <p>The {@code index} is defined to be out of bounds if any of the
224
* following inequalities is true:
225
* <ul>
226
* <li>{@code index < 0}</li>
227
* <li>{@code index >= length}</li>
228
* <li>{@code length < 0}, which is implied from the former inequalities</li>
229
* </ul>
230
*
231
* <p>If the {@code index} is out of bounds, then a runtime exception is
232
* thrown that is the result of applying the following arguments to the
233
* exception formatter: the name of this method, {@code checkIndex};
234
* and an unmodifiable list of integers whose values are, in order, the
235
* out-of-bounds arguments {@code index} and {@code length}.
236
*
237
* @param <X> the type of runtime exception to throw if the arguments are
238
* out of bounds
239
* @param index the index
240
* @param length the upper-bound (exclusive) of the range
241
* @param oobef the exception formatter that when applied with this
242
* method name and out-of-bounds arguments returns a runtime
243
* exception. If {@code null} or returns {@code null} then, it is as
244
* if an exception formatter produced from an invocation of
245
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
246
* instead (though it may be more efficient).
247
* Exceptions thrown by the formatter are relayed to the caller.
248
* @return {@code index} if it is within bounds of the range
249
* @throws X if the {@code index} is out of bounds and the exception
250
* formatter is non-{@code null}
251
* @throws IndexOutOfBoundsException if the {@code index} is out of bounds
252
* and the exception formatter is {@code null}
253
* @since 9
254
*
255
* @implNote
256
* This method is made intrinsic in optimizing compilers to guide them to
257
* perform unsigned comparisons of the index and length when it is known the
258
* length is a non-negative value (such as that of an array length or from
259
* the upper bound of a loop)
260
*/
261
@IntrinsicCandidate
262
public static <X extends RuntimeException>
263
int checkIndex(int index, int length,
264
BiFunction<String, List<Number>, X> oobef) {
265
if (index < 0 || index >= length)
266
throw outOfBoundsCheckIndex(oobef, index, length);
267
return index;
268
}
269
270
/**
271
* Checks if the sub-range from {@code fromIndex} (inclusive) to
272
* {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
273
* (inclusive) to {@code length} (exclusive).
274
*
275
* <p>The sub-range is defined to be out of bounds if any of the following
276
* inequalities is true:
277
* <ul>
278
* <li>{@code fromIndex < 0}</li>
279
* <li>{@code fromIndex > toIndex}</li>
280
* <li>{@code toIndex > length}</li>
281
* <li>{@code length < 0}, which is implied from the former inequalities</li>
282
* </ul>
283
*
284
* <p>If the sub-range is out of bounds, then a runtime exception is
285
* thrown that is the result of applying the following arguments to the
286
* exception formatter: the name of this method, {@code checkFromToIndex};
287
* and an unmodifiable list of integers whose values are, in order, the
288
* out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
289
*
290
* @param <X> the type of runtime exception to throw if the arguments are
291
* out of bounds
292
* @param fromIndex the lower-bound (inclusive) of the sub-range
293
* @param toIndex the upper-bound (exclusive) of the sub-range
294
* @param length the upper-bound (exclusive) the range
295
* @param oobef the exception formatter that when applied with this
296
* method name and out-of-bounds arguments returns a runtime
297
* exception. If {@code null} or returns {@code null} then, it is as
298
* if an exception formatter produced from an invocation of
299
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
300
* instead (though it may be more efficient).
301
* Exceptions thrown by the formatter are relayed to the caller.
302
* @return {@code fromIndex} if the sub-range within bounds of the range
303
* @throws X if the sub-range is out of bounds and the exception factory
304
* function is non-{@code null}
305
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
306
* the exception factory function is {@code null}
307
* @since 9
308
*/
309
public static <X extends RuntimeException>
310
int checkFromToIndex(int fromIndex, int toIndex, int length,
311
BiFunction<String, List<Number>, X> oobef) {
312
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
313
throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
314
return fromIndex;
315
}
316
317
/**
318
* Checks if the sub-range from {@code fromIndex} (inclusive) to
319
* {@code fromIndex + size} (exclusive) is within the bounds of range from
320
* {@code 0} (inclusive) to {@code length} (exclusive).
321
*
322
* <p>The sub-range is defined to be out of bounds if any of the following
323
* inequalities is true:
324
* <ul>
325
* <li>{@code fromIndex < 0}</li>
326
* <li>{@code size < 0}</li>
327
* <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
328
* <li>{@code length < 0}, which is implied from the former inequalities</li>
329
* </ul>
330
*
331
* <p>If the sub-range is out of bounds, then a runtime exception is
332
* thrown that is the result of applying the following arguments to the
333
* exception formatter: the name of this method, {@code checkFromIndexSize};
334
* and an unmodifiable list of integers whose values are, in order, the
335
* out-of-bounds arguments {@code fromIndex}, {@code size}, and
336
* {@code length}.
337
*
338
* @param <X> the type of runtime exception to throw if the arguments are
339
* out of bounds
340
* @param fromIndex the lower-bound (inclusive) of the sub-interval
341
* @param size the size of the sub-range
342
* @param length the upper-bound (exclusive) of the range
343
* @param oobef the exception formatter that when applied with this
344
* method name and out-of-bounds arguments returns a runtime
345
* exception. If {@code null} or returns {@code null} then, it is as
346
* if an exception formatter produced from an invocation of
347
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
348
* instead (though it may be more efficient).
349
* Exceptions thrown by the formatter are relayed to the caller.
350
* @return {@code fromIndex} if the sub-range within bounds of the range
351
* @throws X if the sub-range is out of bounds and the exception factory
352
* function is non-{@code null}
353
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
354
* the exception factory function is {@code null}
355
* @since 9
356
*/
357
public static <X extends RuntimeException>
358
int checkFromIndexSize(int fromIndex, int size, int length,
359
BiFunction<String, List<Number>, X> oobef) {
360
if ((length | fromIndex | size) < 0 || size > length - fromIndex)
361
throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
362
return fromIndex;
363
}
364
365
/**
366
* Checks if the {@code index} is within the bounds of the range from
367
* {@code 0} (inclusive) to {@code length} (exclusive).
368
*
369
* <p>The {@code index} is defined to be out of bounds if any of the
370
* following inequalities is true:
371
* <ul>
372
* <li>{@code index < 0}</li>
373
* <li>{@code index >= length}</li>
374
* <li>{@code length < 0}, which is implied from the former inequalities</li>
375
* </ul>
376
*
377
* <p>If the {@code index} is out of bounds, then a runtime exception is
378
* thrown that is the result of applying the following arguments to the
379
* exception formatter: the name of this method, {@code checkIndex};
380
* and an unmodifiable list of longs whose values are, in order, the
381
* out-of-bounds arguments {@code index} and {@code length}.
382
*
383
* @param <X> the type of runtime exception to throw if the arguments are
384
* out of bounds
385
* @param index the index
386
* @param length the upper-bound (exclusive) of the range
387
* @param oobef the exception formatter that when applied with this
388
* method name and out-of-bounds arguments returns a runtime
389
* exception. If {@code null} or returns {@code null} then, it is as
390
* if an exception formatter produced from an invocation of
391
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
392
* instead (though it may be more efficient).
393
* Exceptions thrown by the formatter are relayed to the caller.
394
* @return {@code index} if it is within bounds of the range
395
* @throws X if the {@code index} is out of bounds and the exception
396
* formatter is non-{@code null}
397
* @throws IndexOutOfBoundsException if the {@code index} is out of bounds
398
* and the exception formatter is {@code null}
399
* @since 16
400
*
401
* @implNote
402
* This method is made intrinsic in optimizing compilers to guide them to
403
* perform unsigned comparisons of the index and length when it is known the
404
* length is a non-negative value (such as that of an array length or from
405
* the upper bound of a loop)
406
*/
407
@IntrinsicCandidate
408
public static <X extends RuntimeException>
409
long checkIndex(long index, long length,
410
BiFunction<String, List<Number>, X> oobef) {
411
if (index < 0 || index >= length)
412
throw outOfBoundsCheckIndex(oobef, index, length);
413
return index;
414
}
415
416
/**
417
* Checks if the sub-range from {@code fromIndex} (inclusive) to
418
* {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
419
* (inclusive) to {@code length} (exclusive).
420
*
421
* <p>The sub-range is defined to be out of bounds if any of the following
422
* inequalities is true:
423
* <ul>
424
* <li>{@code fromIndex < 0}</li>
425
* <li>{@code fromIndex > toIndex}</li>
426
* <li>{@code toIndex > length}</li>
427
* <li>{@code length < 0}, which is implied from the former inequalities</li>
428
* </ul>
429
*
430
* <p>If the sub-range is out of bounds, then a runtime exception is
431
* thrown that is the result of applying the following arguments to the
432
* exception formatter: the name of this method, {@code checkFromToIndex};
433
* and an unmodifiable list of longs whose values are, in order, the
434
* out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
435
*
436
* @param <X> the type of runtime exception to throw if the arguments are
437
* out of bounds
438
* @param fromIndex the lower-bound (inclusive) of the sub-range
439
* @param toIndex the upper-bound (exclusive) of the sub-range
440
* @param length the upper-bound (exclusive) the range
441
* @param oobef the exception formatter that when applied with this
442
* method name and out-of-bounds arguments returns a runtime
443
* exception. If {@code null} or returns {@code null} then, it is as
444
* if an exception formatter produced from an invocation of
445
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
446
* instead (though it may be more efficient).
447
* Exceptions thrown by the formatter are relayed to the caller.
448
* @return {@code fromIndex} if the sub-range within bounds of the range
449
* @throws X if the sub-range is out of bounds and the exception factory
450
* function is non-{@code null}
451
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
452
* the exception factory function is {@code null}
453
* @since 16
454
*/
455
public static <X extends RuntimeException>
456
long checkFromToIndex(long fromIndex, long toIndex, long length,
457
BiFunction<String, List<Number>, X> oobef) {
458
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
459
throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
460
return fromIndex;
461
}
462
463
/**
464
* Checks if the sub-range from {@code fromIndex} (inclusive) to
465
* {@code fromIndex + size} (exclusive) is within the bounds of range from
466
* {@code 0} (inclusive) to {@code length} (exclusive).
467
*
468
* <p>The sub-range is defined to be out of bounds if any of the following
469
* inequalities is true:
470
* <ul>
471
* <li>{@code fromIndex < 0}</li>
472
* <li>{@code size < 0}</li>
473
* <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
474
* <li>{@code length < 0}, which is implied from the former inequalities</li>
475
* </ul>
476
*
477
* <p>If the sub-range is out of bounds, then a runtime exception is
478
* thrown that is the result of applying the following arguments to the
479
* exception formatter: the name of this method, {@code checkFromIndexSize};
480
* and an unmodifiable list of longs whose values are, in order, the
481
* out-of-bounds arguments {@code fromIndex}, {@code size}, and
482
* {@code length}.
483
*
484
* @param <X> the type of runtime exception to throw if the arguments are
485
* out of bounds
486
* @param fromIndex the lower-bound (inclusive) of the sub-interval
487
* @param size the size of the sub-range
488
* @param length the upper-bound (exclusive) of the range
489
* @param oobef the exception formatter that when applied with this
490
* method name and out-of-bounds arguments returns a runtime
491
* exception. If {@code null} or returns {@code null} then, it is as
492
* if an exception formatter produced from an invocation of
493
* {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
494
* instead (though it may be more efficient).
495
* Exceptions thrown by the formatter are relayed to the caller.
496
* @return {@code fromIndex} if the sub-range within bounds of the range
497
* @throws X if the sub-range is out of bounds and the exception factory
498
* function is non-{@code null}
499
* @throws IndexOutOfBoundsException if the sub-range is out of bounds and
500
* the exception factory function is {@code null}
501
* @since 16
502
*/
503
public static <X extends RuntimeException>
504
long checkFromIndexSize(long fromIndex, long size, long length,
505
BiFunction<String, List<Number>, X> oobef) {
506
if ((length | fromIndex | size) < 0 || size > length - fromIndex)
507
throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
508
return fromIndex;
509
}
510
}
511
512