ses
Version:
Hardened JavaScript for Fearless Cooperation
51 lines (44 loc) • 1.39 kB
JavaScript
import {
WeakSet,
defineProperty,
freeze,
functionPrototype,
functionToString,
stringEndsWith,
weaksetAdd,
weaksetHas,
} from './commons.js';
const nativeSuffix = ') { [native code] }';
// Note: Top level mutable state. Does not make anything worse, since the
// patching of `Function.prototype.toString` is also globally stateful. We
// use this top level state so that multiple calls to `tameFunctionToString` are
// idempotent, rather than creating redundant indirections.
let markVirtualizedNativeFunction;
/**
* Replace `Function.prototype.toString` with one that recognizes
* shimmed functions as honorary native functions.
*/
export const tameFunctionToString = () => {
if (markVirtualizedNativeFunction === undefined) {
const virtualizedNativeFunctions = new WeakSet();
const tamingMethods = {
toString() {
const str = functionToString(this);
if (
stringEndsWith(str, nativeSuffix) ||
!weaksetHas(virtualizedNativeFunctions, this)
) {
return str;
}
return `function ${this.name}() { [native code] }`;
},
};
defineProperty(functionPrototype, 'toString', {
value: tamingMethods.toString,
});
markVirtualizedNativeFunction = freeze(func =>
weaksetAdd(virtualizedNativeFunctions, func),
);
}
return markVirtualizedNativeFunction;
};