ered. function makeCallable(obj, target, isStatic, propertyNames) { propertyNames.forEach(function(propertyName) { var property = obj[propertyName]; target[propertyName] = function() { var recv = obj; var firstArgIndex = 0; if (!isStatic) { if (arguments.length == 0) throw 'There must be at least one argument, the receiver'; recv = arguments[0]; firstArgIndex = 1; } return Apply( property, recv, arguments, firstArgIndex, arguments.length); }; }); } function saveBuiltin(builtin, protoPropertyNames, staticPropertyNames) { var safe = function() { throw 'Safe objects cannot be called nor constructed. ' + 'Use $Foo.self() or new $Foo.self() instead.'; }; safe.self = builtin; makeCallable(builtin.prototype, safe, false, protoPropertyNames); if (staticPropertyNames) makeCallable(builtin, safe, true, staticPropertyNames); Save(builtin.name, safe); } // Save only what is needed by the extension modules. saveBuiltin(Object, ['hasOwnProperty'], ['assign', 'create', 'defineProperty', 'entries', 'freeze', 'getOwnPropertyDescriptor', 'getPrototypeOf', 'keys', 'setPrototypeOf']); saveBuiltin(Function, ['apply', 'bind', 'call']); saveBuiltin(Array, ['concat', 'forEach', 'includes', 'indexOf', 'join', 'push', 'slice', 'splice', 'map', 'filter', 'shift', 'unshift', 'pop', 'push', 'reverse', 'find'], ['from', 'isArray']); saveBuiltin(String, ['indexOf', 'slice', 'split', 'substr', 'toLowerCase', 'toUpperCase', 'replace'], ['fromCharCode']); // Use exec rather than test to defend against clobbering in the // presence of ES2015 semantics, which read RegExp.prototype.exec. saveBuiltin(RegExp, ['exec']); saveBuiltin(Error, [], ['captureStackTrace']); saveBuiltin(Promise, ['then', 'catch'], ['race', 'resolve']); // JSON is trickier because extensions can override toJSON in // incompatible ways, and we need to prevent that. var builtinTypes = [ Object, Function, Array, String, Boolean, Number, Date, RegExp ]; var builtinToJSONs = builtinTypes.map(function(t) { return t.toJSON; }); var builtinArray = Array; var builtinJSONStringify = JSON.stringify; Save('JSON', { parse: JSON.parse, stringify: function(obj) { var savedToJSONs = new builtinArray(builtinTypes.length); try { for (var i = 0; i < builtinTypes.length; ++i) { try { if (builtinTypes[i].prototype.toJSON !== builtinToJSONs[i]) { savedToJSONs[i] = builtinTypes[i].prototype.toJSON; builtinTypes[i].prototype.toJSON = builtinToJSONs[i]; } } catch (e) {} } } catch (e) {} try { return builtinJSONStringify(obj); } finally { for (var i = 0; i < builtinTypes.length; ++i) { try { if (i in savedToJSONs) builtinTypes[i].prototype.toJSON = savedToJSONs[i]; } catch (e) {} } } } }); }());