summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2019-04-24 01:24:23 +0800
committerDaniel Bevenius <daniel.bevenius@gmail.com>2019-04-26 07:23:42 +0200
commit08a9c4a996964aca909cd75fa8ecafd652c54885 (patch)
tree41fdc49f11e9e293d26257b95be88a9cd04e84c3
parent5ab65cff8d95faa6ebd91f20b77156a520dc3ac2 (diff)
downloadandroid-node-v8-08a9c4a996964aca909cd75fa8ecafd652c54885.tar.gz
android-node-v8-08a9c4a996964aca909cd75fa8ecafd652c54885.tar.bz2
android-node-v8-08a9c4a996964aca909cd75fa8ecafd652c54885.zip
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: https://github.com/nodejs/node/pull/27371 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
-rw-r--r--lib/internal/per_context/domexception.js82
1 files changed, 51 insertions, 31 deletions
diff --git a/lib/internal/per_context/domexception.js b/lib/internal/per_context/domexception.js
index 83b8d55995..3852567ac6 100644
--- a/lib/internal/per_context/domexception.js
+++ b/lib/internal/per_context/domexception.js
@@ -15,12 +15,28 @@ class ERR_INVALID_THIS extends TypeError {
get code() { return 'ERR_INVALID_THIS'; }
}
-const internalsMap = new SafeWeakMap();
+let internalsMap;
+let nameToCodeMap;
+let isInitialized = false;
-const nameToCodeMap = new SafeMap();
+// We need to instantiate the maps lazily because they render
+// the snapshot non-rehashable.
+// https://bugs.chromium.org/p/v8/issues/detail?id=6593
+function ensureInitialized() {
+ if (isInitialized) {
+ return;
+ }
+ internalsMap = new SafeWeakMap();
+ nameToCodeMap = new SafeMap();
+ forEachCode((name, codeName, value) => {
+ nameToCodeMap.set(name, value);
+ });
+ isInitialized = true;
+}
class DOMException extends Error {
constructor(message = '', name = 'Error') {
+ ensureInitialized();
super();
internalsMap.set(this, {
message: `${message}`,
@@ -29,6 +45,7 @@ class DOMException extends Error {
}
get name() {
+ ensureInitialized();
const internals = internalsMap.get(this);
if (internals === undefined) {
throw new ERR_INVALID_THIS('DOMException');
@@ -37,6 +54,7 @@ class DOMException extends Error {
}
get message() {
+ ensureInitialized();
const internals = internalsMap.get(this);
if (internals === undefined) {
throw new ERR_INVALID_THIS('DOMException');
@@ -45,6 +63,7 @@ class DOMException extends Error {
}
get code() {
+ ensureInitialized();
const internals = internalsMap.get(this);
if (internals === undefined) {
throw new ERR_INVALID_THIS('DOMException');
@@ -61,39 +80,40 @@ Object.defineProperties(DOMException.prototype, {
code: { enumerable: true, configurable: true }
});
-for (const [name, codeName, value] of [
- ['IndexSizeError', 'INDEX_SIZE_ERR', 1],
- ['DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2],
- ['HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3],
- ['WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4],
- ['InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5],
- ['NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6],
- ['NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7],
- ['NotFoundError', 'NOT_FOUND_ERR', 8],
- ['NotSupportedError', 'NOT_SUPPORTED_ERR', 9],
- ['InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10],
- ['InvalidStateError', 'INVALID_STATE_ERR', 11],
- ['SyntaxError', 'SYNTAX_ERR', 12],
- ['InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13],
- ['NamespaceError', 'NAMESPACE_ERR', 14],
- ['InvalidAccessError', 'INVALID_ACCESS_ERR', 15],
- ['ValidationError', 'VALIDATION_ERR', 16],
- ['TypeMismatchError', 'TYPE_MISMATCH_ERR', 17],
- ['SecurityError', 'SECURITY_ERR', 18],
- ['NetworkError', 'NETWORK_ERR', 19],
- ['AbortError', 'ABORT_ERR', 20],
- ['URLMismatchError', 'URL_MISMATCH_ERR', 21],
- ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22],
- ['TimeoutError', 'TIMEOUT_ERR', 23],
- ['InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24],
- ['DataCloneError', 'DATA_CLONE_ERR', 25]
+function forEachCode(fn) {
+ fn('IndexSizeError', 'INDEX_SIZE_ERR', 1);
+ fn('DOMStringSizeError', 'DOMSTRING_SIZE_ERR', 2);
+ fn('HierarchyRequestError', 'HIERARCHY_REQUEST_ERR', 3);
+ fn('WrongDocumentError', 'WRONG_DOCUMENT_ERR', 4);
+ fn('InvalidCharacterError', 'INVALID_CHARACTER_ERR', 5);
+ fn('NoDataAllowedError', 'NO_DATA_ALLOWED_ERR', 6);
+ fn('NoModificationAllowedError', 'NO_MODIFICATION_ALLOWED_ERR', 7);
+ fn('NotFoundError', 'NOT_FOUND_ERR', 8);
+ fn('NotSupportedError', 'NOT_SUPPORTED_ERR', 9);
+ fn('InUseAttributeError', 'INUSE_ATTRIBUTE_ERR', 10);
+ fn('InvalidStateError', 'INVALID_STATE_ERR', 11);
+ fn('SyntaxError', 'SYNTAX_ERR', 12);
+ fn('InvalidModificationError', 'INVALID_MODIFICATION_ERR', 13);
+ fn('NamespaceError', 'NAMESPACE_ERR', 14);
+ fn('InvalidAccessError', 'INVALID_ACCESS_ERR', 15);
+ fn('ValidationError', 'VALIDATION_ERR', 16);
+ fn('TypeMismatchError', 'TYPE_MISMATCH_ERR', 17);
+ fn('SecurityError', 'SECURITY_ERR', 18);
+ fn('NetworkError', 'NETWORK_ERR', 19);
+ fn('AbortError', 'ABORT_ERR', 20);
+ fn('URLMismatchError', 'URL_MISMATCH_ERR', 21);
+ fn('QuotaExceededError', 'QUOTA_EXCEEDED_ERR', 22);
+ fn('TimeoutError', 'TIMEOUT_ERR', 23);
+ fn('InvalidNodeTypeError', 'INVALID_NODE_TYPE_ERR', 24);
+ fn('DataCloneError', 'DATA_CLONE_ERR', 25);
// There are some more error names, but since they don't have codes assigned,
// we don't need to care about them.
-]) {
+}
+
+forEachCode((name, codeName, value) => {
const desc = { enumerable: true, value };
Object.defineProperty(DOMException, codeName, desc);
Object.defineProperty(DOMException.prototype, codeName, desc);
- nameToCodeMap.set(name, value);
-}
+});
exports.DOMException = DOMException;