[es6] don't "replace" Object.prototype.toString for --harmony-tostring

When ObjectToString is installed on Object.prototype twice (once in v8natives.js, and once in harmony-tostring.js), this pollutes old code spaces on some devices. To prevent this, the function is only installed once, preventing test failures when the --harmony-tostring flag is flipped on by default.

BUG=v8:3502
LOG=N
R=arv@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27720}
This commit is contained in:
caitpotter88 2015-04-09 13:53:46 -07:00 committed by Commit bot
parent a5d71c2cac
commit 48eff34c32
9 changed files with 53 additions and 28 deletions

View File

@ -1690,7 +1690,6 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_classes)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tostring)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
@ -1762,6 +1761,17 @@ void Genesis::InitializeGlobal_harmony_reflect() {
}
void Genesis::InitializeGlobal_harmony_tostring() {
Handle<JSObject> builtins(native_context()->builtins());
Handle<HeapObject> flag(FLAG_harmony_tostring ? heap()->true_value()
: heap()->false_value());
Runtime::SetObjectProperty(isolate(), builtins,
factory()->harmony_tostring_string(), flag,
STRICT).Assert();
}
Handle<JSFunction> Genesis::InstallInternalArray(
Handle<JSBuiltinsObject> builtins,
const char* name,

View File

@ -32,23 +32,3 @@ function HarmonyToStringExtendSymbolPrototype() {
}
HarmonyToStringExtendSymbolPrototype();
function HarmonyToStringExtendObjectPrototype() {
%CheckIsBootstrapping();
// Can't use InstallFunctions() because will fail in Debug mode.
// Emulate InstallFunctions() here.
%FunctionSetName(ObjectToStringHarmony, "toString");
%FunctionRemovePrototype(ObjectToStringHarmony);
%SetNativeFlag(ObjectToStringHarmony);
// Set up the non-enumerable functions on the Array prototype object.
var desc = ToPropertyDescriptor({
value: ObjectToStringHarmony
});
DefineOwnProperty($Object.prototype, "toString", desc, false);
%ToFastProperties($Object.prototype);
}
HarmonyToStringExtendObjectPrototype();

View File

@ -232,6 +232,7 @@ namespace internal {
V(sticky_string, "sticky") \
V(unicode_string, "unicode") \
V(harmony_regexps_string, "harmony_regexps") \
V(harmony_tostring_string, "harmony_tostring") \
V(harmony_unicode_regexps_string, "harmony_unicode_regexps") \
V(input_string, "input") \
V(index_string, "index") \

View File

@ -248,7 +248,7 @@ function NoSideEffectToString(obj) {
}
if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString);
if (IS_OBJECT(obj)
&& %GetDataProperty(obj, "toString") === DefaultObjectToString) {
&& %GetDataProperty(obj, "toString") === ObjectToString) {
var constructor = %GetDataProperty(obj, "constructor");
if (typeof constructor == "function") {
var constructorName = constructor.name;

View File

@ -342,5 +342,11 @@ RUNTIME_FUNCTION(Runtime_Unlikely) {
DCHECK(args.length() == 1);
return args[0];
}
RUNTIME_FUNCTION(Runtime_HarmonyToString) {
// TODO(caitp): Delete this runtime method when removing --harmony-tostring
return isolate->heap()->ToBoolean(FLAG_harmony_tostring);
}
}
} // namespace v8::internal

View File

@ -291,7 +291,8 @@ namespace internal {
F(GetFromCache, 2, 1) \
F(IncrementStatsCounter, 1, 1) \
F(Likely, 1, 1) \
F(Unlikely, 1, 1)
F(Unlikely, 1, 1) \
F(HarmonyToString, 0, 1)
#define FOR_EACH_INTRINSIC_JSON(F) \

View File

@ -216,7 +216,7 @@ SetUpGlobal();
// ----------------------------------------------------------------------------
// Object
var DefaultObjectToString = NoSideEffectsObjectToString;
var DefaultObjectToString = ObjectToString;
// ECMA-262 - 15.2.4.2
function NoSideEffectsObjectToString() {
if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
@ -225,6 +225,27 @@ function NoSideEffectsObjectToString() {
}
function ObjectToString() {
if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
if (IS_NULL(this)) return "[object Null]";
var O = TO_OBJECT_INLINE(this);
var builtinTag = %_ClassOf(O);
var tag;
// TODO(caitp): cannot wait to get rid of this flag :>
if (harmony_tostring) {
var tag = O[symbolToStringTag];
if (!IS_STRING(tag)) {
tag = builtinTag;
}
} else {
tag = builtinTag;
}
return `[object ${tag}]`;
}
// ECMA-262 - 15.2.4.3
function ObjectToLocaleString() {
CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString");
@ -1410,7 +1431,7 @@ function SetUpObject() {
// Set up non-enumerable functions on the Object.prototype object.
InstallFunctions($Object.prototype, DONT_ENUM, $Array(
"toString", NoSideEffectsObjectToString,
"toString", ObjectToString,
"toLocaleString", ObjectToLocaleString,
"valueOf", ObjectValueOf,
"hasOwnProperty", ObjectHasOwnProperty,

View File

@ -48,6 +48,9 @@ var funcs = [
for (var fun of funcs) {
var p = fun.prototype;
// @@toStringTag is tested separately, and interferes with this test.
if (Symbol.toStringTag) delete p[Symbol.toStringTag];
assertEquals('[object Object]', Object.prototype.toString.call(p));
}
@ -60,5 +63,5 @@ var funcs = [
for (var fun of funcs) {
var p = fun.prototype;
assertEquals('[object ' + fun.name + ']', Object.prototype.toString.call(p));
assertEquals(`[object ${fun.name}]`, Object.prototype.toString.call(p));
}

View File

@ -25,6 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The arguments property of functions should be null when not
// The arguments property of sloppy functions should be null when not
// executing inside the function.
assertTrue(toString.arguments === null);
function sloppy() {}
assertTrue(sloppy.arguments === null);