Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/common/LETableReference.h
38825 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
/*
26
* -*- c++ -*-
27
*
28
* (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
29
*
30
* Range checking
31
*
32
*/
33
34
#ifndef __LETABLEREFERENCE_H
35
#define __LETABLEREFERENCE_H
36
37
#include "LETypes.h"
38
#include "LEFontInstance.h"
39
40
/**
41
* \def LE_ENABLE_RAW
42
* If this is 1, enables old non-safe raw access
43
*/
44
#ifndef LE_ENABLE_RAW
45
#define LE_ENABLE_RAW 0
46
#endif
47
48
#define kQuestionmarkTableTag 0x3F3F3F3FUL /* ???? */
49
#define kStaticTableTag 0x30303030UL /* 0000 */
50
#define kTildeTableTag 0x7e7e7e7eUL /* ~~~~ */
51
#ifdef __cplusplus
52
53
// internal - interface for range checking
54
U_NAMESPACE_BEGIN
55
56
#if LE_ASSERT_BAD_FONT
57
58
#ifndef LE_TRACE_TR
59
#define LE_TRACE_TR 0
60
#endif
61
62
class LETableReference; // fwd
63
/**
64
* defined in OpenTypeUtilities.cpp
65
* @internal
66
*/
67
U_CAPI void U_EXPORT2 _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
68
69
#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
70
#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
71
#if LE_TRACE_TR
72
#define _TRTRACE(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
73
#else
74
#define _TRTRACE(x)
75
#endif
76
77
#else
78
#define LE_DEBUG_TR(x)
79
#define LE_DEBUG_TR3(x,y,z)
80
#define _TRTRACE(x)
81
#endif
82
83
/**
84
* @internal
85
*/
86
class LETableReference {
87
public:
88
89
/**
90
* Dummy enum asserting that a value is actually static data
91
* and does not need to be range checked
92
*/
93
enum EStaticData { kStaticData = 0 };
94
95
/**
96
* @internal
97
* Construct from a specific tag
98
*/
99
LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
100
fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
101
loadTable(success);
102
_TRTRACE("INFO: new table load")
103
}
104
105
LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
106
if(LE_FAILURE(success)) {
107
clear();
108
}
109
_TRTRACE("INFO: new clone")
110
}
111
112
#if LE_ENABLE_RAW
113
/**
114
* Construct without a parent LETR.
115
*/
116
LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
117
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
118
_TRTRACE("INFO: new raw")
119
}
120
#endif
121
122
/**
123
* Construct without a parent LETR.
124
*/
125
LETableReference(EStaticData /* NOTUSED */, const le_uint8* data, size_t length) :
126
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
127
_TRTRACE("INFO: new EStaticData")
128
}
129
130
LETableReference() :
131
fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
132
_TRTRACE("INFO: new empty")
133
}
134
135
~LETableReference() {
136
fTag= (LETag)kTildeTableTag;
137
_TRTRACE("INFO: new dtor")
138
}
139
140
/**
141
* @internal
142
* @param length if LE_UINTPTR_MAX means "whole table"
143
* subset
144
*/
145
LETableReference(const LETableReference &parent, size_t offset, size_t length,
146
LEErrorCode &err) :
147
fFont(parent.fFont), fTag(parent.fTag), fParent(&parent),
148
fStart((parent.fStart)+offset), fLength(length) {
149
if(LE_SUCCESS(err)) {
150
if(isEmpty()) {
151
//err = LE_MISSING_FONT_TABLE_ERROR;
152
clear(); // it's just empty. Not an error.
153
} else if(offset >= fParent->fLength || (offset & 0x01)) {
154
LE_DEBUG_TR3("offset out of range or odd alignment: (%p) +%d", NULL, offset);
155
err = LE_INDEX_OUT_OF_BOUNDS_ERROR;
156
clear();
157
} else {
158
if(fLength == LE_UINTPTR_MAX &&
159
fParent->fLength != LE_UINTPTR_MAX) {
160
fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
161
}
162
if(fLength != LE_UINTPTR_MAX) { // if we have bounds:
163
if((offset+fLength < offset) || (offset+fLength > fParent->fLength)) {
164
LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
165
err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
166
clear();
167
}
168
}
169
}
170
} else {
171
clear();
172
}
173
_TRTRACE("INFO: new subset")
174
}
175
176
const void* getAlias() const { return (const void*)fStart; }
177
#ifndef LE_ENABLE_RAW
178
const void* getAliasRAW() const { LE_DEBUG_TR("getAliasRAW()"); return (const void*)fStart; }
179
#endif
180
le_bool isEmpty() const { return fStart==NULL || fLength==0; }
181
le_bool isValid() const { return !isEmpty(); }
182
le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
183
void clear() { fLength=0; fStart=NULL; }
184
size_t getLength() const { return fLength; }
185
const LEFontInstance* getFont() const { return fFont; }
186
LETag getTag() const { return fTag; }
187
const LETableReference* getParent() const { return fParent; }
188
189
void addOffset(size_t offset, LEErrorCode &success) {
190
if(hasBounds()) {
191
if(offset >= fLength) {
192
LE_DEBUG_TR("addOffset off end");
193
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
194
return;
195
} else {
196
fLength -= offset;
197
}
198
}
199
fStart += offset;
200
}
201
202
size_t ptrToOffset(const void *atPtr, LEErrorCode &success) const {
203
if(atPtr==NULL) return 0;
204
if(LE_FAILURE(success)) return LE_UINTPTR_MAX;
205
if((atPtr < fStart) ||
206
(hasBounds() && (atPtr >= fStart+fLength))) {
207
LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0);
208
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
209
return LE_UINTPTR_MAX;
210
}
211
return ((const le_uint8*)atPtr)-fStart;
212
}
213
214
/**
215
* Clamp down the length, for range checking.
216
*/
217
size_t contractLength(size_t newLength) {
218
if(fLength!=LE_UINTPTR_MAX&&newLength>0&&newLength<=fLength) {
219
fLength = newLength;
220
}
221
return fLength;
222
}
223
224
/**
225
* Throw an error if offset+length off end
226
*/
227
public:
228
size_t verifyLength(size_t offset, size_t length, LEErrorCode &success) {
229
if(isValid()&&
230
LE_SUCCESS(success) &&
231
fLength!=LE_UINTPTR_MAX && length!=LE_UINTPTR_MAX && offset!=LE_UINTPTR_MAX &&
232
(offset+length)>fLength) {
233
LE_DEBUG_TR3("verifyLength failed (%p) %d",NULL, offset+length);
234
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
235
#if LE_ASSERT_BAD_FONT
236
fprintf(stderr, "offset=%lu, len=%lu, would be at %p, (%lu) off end. End at %p\n", offset,length, fStart+offset+length, (offset+length-fLength), (offset+length-fLength)+fStart);
237
#endif
238
}
239
return fLength;
240
}
241
242
/**
243
* Throw an error if size*count overflows
244
*/
245
size_t verifyLength(size_t offset, size_t size, le_uint32 count, LEErrorCode &success) {
246
if(count!=0 && size>LE_UINT32_MAX/count) {
247
LE_DEBUG_TR3("verifyLength failed size=%u, count=%u", size, count);
248
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
249
return 0;
250
}
251
return verifyLength(offset, size*count, success);
252
}
253
254
/**
255
* Change parent link to another
256
*/
257
LETableReference &reparent(const LETableReference &base) {
258
fParent = &base;
259
return *this;
260
}
261
262
/**
263
* remove parent link. Factory functions should do this.
264
*/
265
void orphan(void) {
266
fParent=NULL;
267
}
268
269
protected:
270
const LEFontInstance* fFont;
271
LETag fTag;
272
const LETableReference *fParent;
273
const le_uint8 *fStart; // keep as 8 bit internally, for pointer math
274
size_t fLength;
275
276
void loadTable(LEErrorCode &success) {
277
if(LE_SUCCESS(success)) {
278
fStart = (const le_uint8*)(fFont->getFontTable(fTag, fLength)); // note - a null table is not an error.
279
}
280
}
281
282
void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
283
fFont = NULL;
284
fTag = (LETag)kQuestionmarkTableTag;
285
fParent = NULL;
286
fStart = (const le_uint8*)data;
287
fLength = length;
288
}
289
290
/**
291
* set this object pointing to static data
292
*/
293
void setTo(EStaticData /*notused*/, const void *data, size_t length) {
294
fFont = NULL;
295
fTag = (LETag)kStaticTableTag;
296
fParent = NULL;
297
fStart = (const le_uint8*)data;
298
fLength = length;
299
}
300
};
301
302
303
template<class T>
304
class LETableVarSizer {
305
public:
306
inline static size_t getSize();
307
};
308
309
// base definition- could override for adjustments
310
template<class T> inline
311
size_t LETableVarSizer<T>::getSize() {
312
return sizeof(T);
313
}
314
315
/**
316
* \def LE_VAR_ARRAY
317
* @param x Type (T)
318
* @param y some member that is of length ANY_NUMBER
319
* Call this after defining a class, for example:
320
* LE_VAR_ARRAY(FeatureListTable,featureRecordArray)
321
* this is roughly equivalent to:
322
* template<> inline size_t LETableVarSizer<FeatureListTable>::getSize() { return sizeof(FeatureListTable) - (sizeof(le_uint16)*ANY_NUMBER); }
323
* it's a specialization that informs the LETableReference subclasses to NOT include the variable array in the size.
324
* dereferencing NULL is valid here because we never actually dereference it, just inside sizeof.
325
*/
326
#define LE_VAR_ARRAY(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return sizeof(x) - (sizeof(((const x*)0)->y)); }
327
/**
328
* \def LE_CORRECT_SIZE
329
* @param x type (T)
330
* @param y fixed size for T
331
*/
332
#define LE_CORRECT_SIZE(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return y; }
333
334
/**
335
* Open a new entry based on an existing table
336
*/
337
338
template<class T>
339
class LEReferenceTo : public LETableReference {
340
public:
341
/**
342
* open a sub reference.
343
* @param parent parent reference
344
* @param success error status
345
* @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
346
*/
347
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
348
: LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
349
verifyLength(0, LETableVarSizer<T>::getSize(), success);
350
if(LE_FAILURE(success)) clear();
351
}
352
/**
353
* ptr plus offset
354
*/
355
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
356
: LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
357
verifyLength(0, LETableVarSizer<T>::getSize(), success);
358
if(LE_FAILURE(success)) clear();
359
}
360
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
361
: LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
362
verifyLength(0, LETableVarSizer<T>::getSize(), success);
363
if(LE_FAILURE(success)) clear();
364
}
365
inline LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
366
: LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
367
verifyLength(0, LETableVarSizer<T>::getSize(), success);
368
if(LE_FAILURE(success)) clear();
369
}
370
inline LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
371
: LETableReference(font, tableTag, success) {
372
verifyLength(0, LETableVarSizer<T>::getSize(), success);
373
if(LE_FAILURE(success)) clear();
374
}
375
#if LE_ENABLE_RAW
376
inline LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
377
inline LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
378
#endif
379
inline LEReferenceTo(EStaticData staticData, const le_uint8 *data, size_t length) : LETableReference(staticData, data, length) {}
380
inline LEReferenceTo(EStaticData staticData, const T *data, size_t length) : LETableReference(staticData, (const le_uint8*)data, length) {}
381
382
inline LEReferenceTo() : LETableReference() {}
383
384
#if LE_ENABLE_RAW
385
inline LEReferenceTo<T>& operator=(const T* other) {
386
setRaw(other);
387
return *this;
388
}
389
#endif
390
391
LEReferenceTo<T>& setTo(LETableReference::EStaticData staticData, const T* other, size_t length) {
392
LETableReference::setTo(staticData, other, length);
393
return *this;
394
}
395
396
LEReferenceTo<T> &reparent(const LETableReference &base) {
397
fParent = &base;
398
return *this;
399
}
400
401
/**
402
* roll forward by one <T> size.
403
* same as addOffset(LETableVarSizer<T>::getSize(),success)
404
*/
405
void addObject(LEErrorCode &success) {
406
addOffset(LETableVarSizer<T>::getSize(), success);
407
}
408
void addObject(size_t count, LEErrorCode &success) {
409
addOffset(LETableVarSizer<T>::getSize()*count, success);
410
}
411
412
const T *operator->() const { return getAlias(); }
413
const T *operator*() const { return getAlias(); }
414
const T *getAlias() const { return (const T*)fStart; }
415
#if LE_ENABLE_RAW
416
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
417
#endif
418
419
};
420
421
422
/**
423
* \def LE_UNBOUNDED_ARRAY
424
* define an array with no *known* bound. Will trim to available size.
425
* @internal
426
*/
427
#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
428
429
template<class T>
430
class LEReferenceToArrayOf : public LETableReference {
431
public:
432
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
433
: LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
434
_TRTRACE("INFO: new RTAO by offset")
435
if(LE_SUCCESS(success)) {
436
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
437
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
438
}
439
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
440
}
441
if(LE_FAILURE(success)) {
442
fCount=0;
443
clear();
444
}
445
}
446
447
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
448
: LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
449
_TRTRACE("INFO: new RTAO")
450
if(LE_SUCCESS(success)) {
451
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
452
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
453
}
454
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
455
}
456
if(LE_FAILURE(success)) clear();
457
}
458
LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
459
: LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
460
_TRTRACE("INFO: new RTAO")
461
if(LE_SUCCESS(success)) {
462
if(fCount == LE_UNBOUNDED_ARRAY) { // not a known length
463
fCount = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
464
}
465
LETableReference::verifyLength(0, LETableVarSizer<T>::getSize(), fCount, success);
466
}
467
if(LE_FAILURE(success)) clear();
468
}
469
470
LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
471
472
le_uint32 getCount() const { return fCount; }
473
474
const T *getAlias() const { return (const T*)fStart; }
475
476
const T *getAlias(le_uint32 i, LEErrorCode &success) const {
477
return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
478
}
479
480
#ifndef LE_ENABLE_RAW
481
const T *getAliasRAW() const { LE_DEBUG_TR("getAliasRAW<>"); return (const T*)fStart; }
482
#endif
483
484
const T& getObject(le_uint32 i, LEErrorCode &success) const {
485
const T *ret = getAlias(i, success);
486
if (LE_FAILURE(success) || ret==NULL) {
487
return *(new T(0));
488
} else {
489
return *ret;
490
}
491
}
492
493
/**
494
* by-value array accessor for integral types.
495
*/
496
const T operator[](le_uint32 i) const {
497
LEErrorCode success = LE_NO_ERROR;
498
const T *ret = getAlias(i, success);
499
if(LE_FAILURE(success) || ret==NULL) {
500
#if LE_ASSERT_BAD_FONT
501
LE_DEBUG_TR3("Range error, out of bounds? (%p) #%d", NULL, i);
502
#endif
503
return T(0); // will not work for all types.
504
}
505
return *ret;
506
}
507
508
const LEReferenceTo<T> getReference(le_uint32 i, LEErrorCode &success) const {
509
if(LE_FAILURE(success)) return LEReferenceTo<T>();
510
return LEReferenceTo<T>(*this, success, getAlias(i,success));
511
}
512
513
const T& operator()(le_uint32 i, LEErrorCode &success) const {
514
return *getAlias(i,success);
515
}
516
517
size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
518
if(LE_SUCCESS(success)&&i<getCount()) {
519
return LETableVarSizer<T>::getSize()*i;
520
} else {
521
LE_DEBUG_TR3("getOffsetFor failed (%p) index=%d",NULL, i);
522
success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
523
}
524
return 0;
525
}
526
527
LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
528
fParent = &base;
529
return *this;
530
}
531
532
LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
533
_TRTRACE("INFO: null RTAO")
534
}
535
536
private:
537
le_uint32 fCount;
538
};
539
540
541
542
543
#ifdef _TRTRACE
544
#undef _TRTRACE
545
#endif
546
547
U_NAMESPACE_END
548
549
#endif
550
551
#endif
552
553