lib: move setupAllowedFlags() into per_thread.js

Because most of its code (the getter) has nothing to do with
the actual bootstrapping and it is run per-thread.

PR-URL: https://github.com/nodejs/node/pull/24704
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Christopher Hiller <boneskull@boneskull.com>
This commit is contained in:
Joyee Cheung 2018-11-29 04:01:06 +08:00
parent 01c5c16aba
commit 36f483b79b
No known key found for this signature in database
GPG Key ID: 92B78A53C8303B8D
2 changed files with 126 additions and 124 deletions

View File

@ -223,7 +223,7 @@
perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
setupAllowedFlags();
perThreadSetup.setupAllowedFlags();
startExecution();
}
@ -739,128 +739,5 @@
new vm.Script(source, { displayErrors: true, filename });
}
function setupAllowedFlags() {
// This builds process.allowedNodeEnvironmentFlags
// from data in the config binding
const replaceUnderscoresRegex = /_/g;
const leadingDashesRegex = /^--?/;
const trailingValuesRegex = /=.*$/;
// Save references so user code does not interfere
const replace = Function.call.bind(String.prototype.replace);
const has = Function.call.bind(Set.prototype.has);
const test = Function.call.bind(RegExp.prototype.test);
const get = () => {
const {
envSettings: { kAllowedInEnvironment }
} = internalBinding('options');
const { options, aliases } = NativeModule.require('internal/options');
const allowedNodeEnvironmentFlags = [];
for (const [name, info] of options) {
if (info.envVarSettings === kAllowedInEnvironment) {
allowedNodeEnvironmentFlags.push(name);
}
}
for (const [ from, expansion ] of aliases) {
let isAccepted = true;
for (const to of expansion) {
if (!to.startsWith('-') || to === '--') continue;
const recursiveExpansion = aliases.get(to);
if (recursiveExpansion) {
if (recursiveExpansion[0] === to)
recursiveExpansion.splice(0, 1);
expansion.push(...recursiveExpansion);
continue;
}
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;
if (!isAccepted) break;
}
if (isAccepted) {
let canonical = from;
if (canonical.endsWith('='))
canonical = canonical.substr(0, canonical.length - 1);
if (canonical.endsWith(' <arg>'))
canonical = canonical.substr(0, canonical.length - 4);
allowedNodeEnvironmentFlags.push(canonical);
}
}
const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
// Save these for comparison against flags provided to
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
// Avoid interference w/ user code by flattening `Set.prototype` into
// each object.
const nodeFlags = Object.defineProperties(
new Set(allowedNodeEnvironmentFlags.map(trimLeadingDashes)),
Object.getOwnPropertyDescriptors(Set.prototype)
);
class NodeEnvironmentFlagsSet extends Set {
constructor(...args) {
super(...args);
// the super constructor consumes `add`, but
// disallow any future adds.
this.add = () => this;
}
delete() {
// noop, `Set` API compatible
return false;
}
clear() {
// noop
}
has(key) {
// This will return `true` based on various possible
// permutations of a flag, including present/missing leading
// dash(es) and/or underscores-for-dashes.
// Strips any values after `=`, inclusive.
// TODO(addaleax): It might be more flexible to run the option parser
// on a dummy option set and see whether it rejects the argument or
// not.
if (typeof key === 'string') {
key = replace(key, replaceUnderscoresRegex, '-');
if (test(leadingDashesRegex, key)) {
key = replace(key, trailingValuesRegex, '');
return has(this, key);
}
return has(nodeFlags, key);
}
return false;
}
}
Object.freeze(NodeEnvironmentFlagsSet.prototype.constructor);
Object.freeze(NodeEnvironmentFlagsSet.prototype);
return process.allowedNodeEnvironmentFlags = Object.freeze(
new NodeEnvironmentFlagsSet(
allowedNodeEnvironmentFlags
));
};
Object.defineProperty(process, 'allowedNodeEnvironmentFlags', {
get,
set(value) {
Object.defineProperty(this, 'allowedNodeEnvironmentFlags', {
value,
configurable: true,
enumerable: true,
writable: true
});
},
enumerable: true,
configurable: true
});
}
startup();
});

View File

@ -234,7 +234,132 @@ function setupUncaughtExceptionCapture(exceptionHandlerState,
};
}
const replaceUnderscoresRegex = /_/g;
const leadingDashesRegex = /^--?/;
const trailingValuesRegex = /=.*$/;
// Save references so user code does not interfere
const replace = Function.call.bind(String.prototype.replace);
const has = Function.call.bind(Set.prototype.has);
const test = Function.call.bind(RegExp.prototype.test);
// This builds the initial process.allowedNodeEnvironmentFlags
// from data in the config binding.
function buildAllowedFlags() {
const {
envSettings: { kAllowedInEnvironment }
} = internalBinding('options');
const { options, aliases } = require('internal/options');
const allowedNodeEnvironmentFlags = [];
for (const [name, info] of options) {
if (info.envVarSettings === kAllowedInEnvironment) {
allowedNodeEnvironmentFlags.push(name);
}
}
for (const [ from, expansion ] of aliases) {
let isAccepted = true;
for (const to of expansion) {
if (!to.startsWith('-') || to === '--') continue;
const recursiveExpansion = aliases.get(to);
if (recursiveExpansion) {
if (recursiveExpansion[0] === to)
recursiveExpansion.splice(0, 1);
expansion.push(...recursiveExpansion);
continue;
}
isAccepted = options.get(to).envVarSettings === kAllowedInEnvironment;
if (!isAccepted) break;
}
if (isAccepted) {
let canonical = from;
if (canonical.endsWith('='))
canonical = canonical.substr(0, canonical.length - 1);
if (canonical.endsWith(' <arg>'))
canonical = canonical.substr(0, canonical.length - 4);
allowedNodeEnvironmentFlags.push(canonical);
}
}
const trimLeadingDashes = (flag) => replace(flag, leadingDashesRegex, '');
// Save these for comparison against flags provided to
// process.allowedNodeEnvironmentFlags.has() which lack leading dashes.
// Avoid interference w/ user code by flattening `Set.prototype` into
// each object.
const nodeFlags = Object.defineProperties(
new Set(allowedNodeEnvironmentFlags.map(trimLeadingDashes)),
Object.getOwnPropertyDescriptors(Set.prototype)
);
class NodeEnvironmentFlagsSet extends Set {
constructor(...args) {
super(...args);
// the super constructor consumes `add`, but
// disallow any future adds.
this.add = () => this;
}
delete() {
// noop, `Set` API compatible
return false;
}
clear() {
// noop
}
has(key) {
// This will return `true` based on various possible
// permutations of a flag, including present/missing leading
// dash(es) and/or underscores-for-dashes.
// Strips any values after `=`, inclusive.
// TODO(addaleax): It might be more flexible to run the option parser
// on a dummy option set and see whether it rejects the argument or
// not.
if (typeof key === 'string') {
key = replace(key, replaceUnderscoresRegex, '-');
if (test(leadingDashesRegex, key)) {
key = replace(key, trailingValuesRegex, '');
return has(this, key);
}
return has(nodeFlags, key);
}
return false;
}
}
Object.freeze(NodeEnvironmentFlagsSet.prototype.constructor);
Object.freeze(NodeEnvironmentFlagsSet.prototype);
return process.allowedNodeEnvironmentFlags = Object.freeze(
new NodeEnvironmentFlagsSet(
allowedNodeEnvironmentFlags
));
}
function setupAllowedFlags() {
Object.defineProperty(process, 'allowedNodeEnvironmentFlags', {
get: buildAllowedFlags,
set(value) {
// If the user tries to set this to another value, override
// this completely to that value.
Object.defineProperty(this, 'allowedNodeEnvironmentFlags', {
value,
configurable: true,
enumerable: true,
writable: true
});
},
enumerable: true,
configurable: true
});
}
module.exports = {
setupAllowedFlags,
setupAssert,
setupCpuUsage,
setupHrtime,