Commit a59f62fc authored by littledan's avatar littledan Committed by Commit bot

Intl: Use private symbols to memoize bound functions

The Intl object used to keep around functions which are bound to the
receiver and memoized in the object (as required by the ECMA-402 spec)
in ordinary properties with names like __boundformat__. This patch
instead stores those methods in private symbol properties, so they are
not exposed to users. A search in GitHub didn't find any uses of
__boundformat__ (whereas the same search found plenty of usages of
other V8 Intl features), so I think this should be fine in terms of
web compatibility.

BUG=v8:3785
R=adamk
LOG=Y

Review URL: https://codereview.chromium.org/1728823002

Cr-Commit-Position: refs/heads/master@{#34230}
parent 8798ef2d
......@@ -202,44 +202,33 @@ function GetTimezoneNameLocationPartRE() {
*/
function addBoundMethod(obj, methodName, implementation, length) {
%CheckIsBootstrapping();
var internalName = %CreatePrivateSymbol(methodName);
function getter() {
if (!%IsInitializedIntlObject(this)) {
throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
}
var internalName = '__bound' + methodName + '__';
if (IS_UNDEFINED(this[internalName])) {
var that = this;
var boundMethod;
if (IS_UNDEFINED(length) || length === 2) {
boundMethod = function(x, y) {
if (!IS_UNDEFINED(new.target)) {
throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
}
return implementation(that, x, y);
}
boundMethod = (x, y) => implementation(this, x, y);
} else if (length === 1) {
boundMethod = function(x) {
if (!IS_UNDEFINED(new.target)) {
throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
}
return implementation(that, x);
}
boundMethod = x => implementation(this, x);
} else {
boundMethod = function() {
if (!IS_UNDEFINED(new.target)) {
throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
}
boundMethod = (...args) => {
// DateTimeFormat.format needs to be 0 arg method, but can stil
// receive optional dateValue param. If one was provided, pass it
// along.
if (arguments.length > 0) {
return implementation(that, arguments[0]);
if (args.length > 0) {
return implementation(this, args[0]);
} else {
return implementation(that);
return implementation(this);
}
}
}
%FunctionSetName(boundMethod, internalName);
// TODO(littledan): Once function name reform is shipped, remove the
// following line and wrap the boundMethod definition in an anonymous
// function macro.
%FunctionSetName(boundMethod, '__bound' + methodName + '__');
%FunctionRemovePrototype(boundMethod);
%SetNativeFlag(boundMethod);
this[internalName] = boundMethod;
......
......@@ -37,3 +37,6 @@ numberArray.forEach(nf.format);
// Formatting a number should work in a direct call.
nf.format(12345);
// Reading the format doesn't add any additional property keys
assertEquals(1, Object.getOwnPropertyNames(nf).length);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment