Skip to content

Commit 08a9c4a

Browse files
joyeecheungdanbev
authored andcommitted
bootstrap: delay the instantiation of maps in per-context scripts
Instantiating maps renders the snapshot non-rehashable (v8 currently fails silently during `CreateBlob()`). Then the hash seed would always be the same and not recomputed if custom V8 snapshot is enabled. This patch delays the instantiation of the maps in domexception.js and make it lazy. PR-URL: #27371 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]>
1 parent 5ab65cf commit 08a9c4a

File tree

1 file changed

+51
-31
lines changed

1 file changed

+51
-31
lines changed

lib/internal/per_context/domexception.js

+51-31
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,28 @@ class ERR_INVALID_THIS extends TypeError {
1515
get code() { return 'ERR_INVALID_THIS'; }
1616
}
1717

18-
const internalsMap = new SafeWeakMap();
18+
let internalsMap;
19+
let nameToCodeMap;
20+
let isInitialized = false;
1921

20-
const nameToCodeMap = new SafeMap();
22+
// We need to instantiate the maps lazily because they render
23+
// the snapshot non-rehashable.
24+
// https://bugs.chromium.org/p/v8/issues/detail?id=6593
25+
function ensureInitialized() {
26+
if (isInitialized) {
27+
return;
28+
}
29+
internalsMap = new SafeWeakMap();
30+
nameToCodeMap = new SafeMap();
31+
forEachCode((name, codeName, value) => {
32+
nameToCodeMap.set(name, value);
33+
});
34+
isInitialized = true;
35+
}
2136

2237
class DOMException extends Error {
2338
constructor(message = '', name = 'Error') {
39+
ensureInitialized();
2440
super();
2541
internalsMap.set(this, {
2642
message: `${message}`,
@@ -29,6 +45,7 @@ class DOMException extends Error {
2945
}
3046

3147
get name() {
48+
ensureInitialized();
3249
const internals = internalsMap.get(this);
3350
if (internals === undefined) {
3451
throw new ERR_INVALID_THIS('DOMException');
@@ -37,6 +54,7 @@ class DOMException extends Error {
3754
}
3855

3956
get message() {
57+
ensureInitialized();
4058
const internals = internalsMap.get(this);
4159
if (internals === undefined) {
4260
throw new ERR_INVALID_THIS('DOMException');
@@ -45,6 +63,7 @@ class DOMException extends Error {
4563
}
4664

4765
get code() {
66+
ensureInitialized();
4867
const internals = internalsMap.get(this);
4968
if (internals === undefined) {
5069
throw new ERR_INVALID_THIS('DOMException');
@@ -61,39 +80,40 @@ Object.defineProperties(DOMException.prototype, {
6180
code: { enumerable: true, configurable: true }
6281
});
6382

64-
for (const [name, codeName, value] of [
65-
['IndexSizeError', 'INDEX_SIZE_ERR', 1],
66-
['DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2],
67-
['HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3],
68-
['WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4],
69-
['InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5],
70-
['NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6],
71-
['NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7],
72-
['NotFoundError', 'NOT_FOUND_ERR', 8],
73-
['NotSupportedError', 'NOT_SUPPORTED_ERR', 9],
74-
['InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10],
75-
['InvalidStateError', 'INVALID_STATE_ERR', 11],
76-
['SyntaxError', 'SYNTAX_ERR', 12],
77-
['InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13],
78-
['NamespaceError', 'NAMESPACE_ERR', 14],
79-
['InvalidAccessError', 'INVALID_ACCESS_ERR', 15],
80-
['ValidationError', 'VALIDATION_ERR', 16],
81-
['TypeMismatchError', 'TYPE_MISMATCH_ERR', 17],
82-
['SecurityError', 'SECURITY_ERR', 18],
83-
['NetworkError', 'NETWORK_ERR', 19],
84-
['AbortError', 'ABORT_ERR', 20],
85-
['URLMismatchError', 'URL_MISMATCH_ERR', 21],
86-
['QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22],
87-
['TimeoutError', 'TIMEOUT_ERR', 23],
88-
['InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24],
89-
['DataCloneError', 'DATA_CLONE_ERR', 25]
83+
function forEachCode(fn) {
84+
fn('IndexSizeError', 'INDEX_SIZE_ERR', 1);
85+
fn('DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2);
86+
fn('HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3);
87+
fn('WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4);
88+
fn('InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5);
89+
fn('NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6);
90+
fn('NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7);
91+
fn('NotFoundError', 'NOT_FOUND_ERR', 8);
92+
fn('NotSupportedError', 'NOT_SUPPORTED_ERR', 9);
93+
fn('InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10);
94+
fn('InvalidStateError', 'INVALID_STATE_ERR', 11);
95+
fn('SyntaxError', 'SYNTAX_ERR', 12);
96+
fn('InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13);
97+
fn('NamespaceError', 'NAMESPACE_ERR', 14);
98+
fn('InvalidAccessError', 'INVALID_ACCESS_ERR', 15);
99+
fn('ValidationError', 'VALIDATION_ERR', 16);
100+
fn('TypeMismatchError', 'TYPE_MISMATCH_ERR', 17);
101+
fn('SecurityError', 'SECURITY_ERR', 18);
102+
fn('NetworkError', 'NETWORK_ERR', 19);
103+
fn('AbortError', 'ABORT_ERR', 20);
104+
fn('URLMismatchError', 'URL_MISMATCH_ERR', 21);
105+
fn('QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22);
106+
fn('TimeoutError', 'TIMEOUT_ERR', 23);
107+
fn('InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24);
108+
fn('DataCloneError', 'DATA_CLONE_ERR', 25);
90109
// There are some more error names, but since they don't have codes assigned,
91110
// we don't need to care about them.
92-
]) {
111+
}
112+
113+
forEachCode((name, codeName, value) => {
93114
const desc = { enumerable: true, value };
94115
Object.defineProperty(DOMException, codeName, desc);
95116
Object.defineProperty(DOMException.prototype, codeName, desc);
96-
nameToCodeMap.set(name, value);
97-
}
117+
});
98118

99119
exports.DOMException = DOMException;

0 commit comments

Comments
 (0)