Commit 48eff34c authored by caitpotter88's avatar caitpotter88 Committed by Commit bot

[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}
parent a5d71c2c
...@@ -1690,7 +1690,6 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes) ...@@ -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_classes)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions) 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_proxies)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
...@@ -1762,6 +1761,17 @@ void Genesis::InitializeGlobal_harmony_reflect() { ...@@ -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<JSFunction> Genesis::InstallInternalArray(
Handle<JSBuiltinsObject> builtins, Handle<JSBuiltinsObject> builtins,
const char* name, const char* name,
......
...@@ -32,23 +32,3 @@ function HarmonyToStringExtendSymbolPrototype() { ...@@ -32,23 +32,3 @@ function HarmonyToStringExtendSymbolPrototype() {
} }
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();
...@@ -232,6 +232,7 @@ namespace internal { ...@@ -232,6 +232,7 @@ namespace internal {
V(sticky_string, "sticky") \ V(sticky_string, "sticky") \
V(unicode_string, "unicode") \ V(unicode_string, "unicode") \
V(harmony_regexps_string, "harmony_regexps") \ V(harmony_regexps_string, "harmony_regexps") \
V(harmony_tostring_string, "harmony_tostring") \
V(harmony_unicode_regexps_string, "harmony_unicode_regexps") \ V(harmony_unicode_regexps_string, "harmony_unicode_regexps") \
V(input_string, "input") \ V(input_string, "input") \
V(index_string, "index") \ V(index_string, "index") \
......
...@@ -248,7 +248,7 @@ function NoSideEffectToString(obj) { ...@@ -248,7 +248,7 @@ function NoSideEffectToString(obj) {
} }
if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString); if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString);
if (IS_OBJECT(obj) if (IS_OBJECT(obj)
&& %GetDataProperty(obj, "toString") === DefaultObjectToString) { && %GetDataProperty(obj, "toString") === ObjectToString) {
var constructor = %GetDataProperty(obj, "constructor"); var constructor = %GetDataProperty(obj, "constructor");
if (typeof constructor == "function") { if (typeof constructor == "function") {
var constructorName = constructor.name; var constructorName = constructor.name;
......
...@@ -342,5 +342,11 @@ RUNTIME_FUNCTION(Runtime_Unlikely) { ...@@ -342,5 +342,11 @@ RUNTIME_FUNCTION(Runtime_Unlikely) {
DCHECK(args.length() == 1); DCHECK(args.length() == 1);
return args[0]; 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 } // namespace v8::internal
...@@ -291,7 +291,8 @@ namespace internal { ...@@ -291,7 +291,8 @@ namespace internal {
F(GetFromCache, 2, 1) \ F(GetFromCache, 2, 1) \
F(IncrementStatsCounter, 1, 1) \ F(IncrementStatsCounter, 1, 1) \
F(Likely, 1, 1) \ F(Likely, 1, 1) \
F(Unlikely, 1, 1) F(Unlikely, 1, 1) \
F(HarmonyToString, 0, 1)
#define FOR_EACH_INTRINSIC_JSON(F) \ #define FOR_EACH_INTRINSIC_JSON(F) \
......
...@@ -216,7 +216,7 @@ SetUpGlobal(); ...@@ -216,7 +216,7 @@ SetUpGlobal();
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Object // Object
var DefaultObjectToString = NoSideEffectsObjectToString; var DefaultObjectToString = ObjectToString;
// ECMA-262 - 15.2.4.2 // ECMA-262 - 15.2.4.2
function NoSideEffectsObjectToString() { function NoSideEffectsObjectToString() {
if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]"; if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
...@@ -225,6 +225,27 @@ function NoSideEffectsObjectToString() { ...@@ -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 // ECMA-262 - 15.2.4.3
function ObjectToLocaleString() { function ObjectToLocaleString() {
CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString"); CHECK_OBJECT_COERCIBLE(this, "Object.prototype.toLocaleString");
...@@ -1410,7 +1431,7 @@ function SetUpObject() { ...@@ -1410,7 +1431,7 @@ function SetUpObject() {
// Set up non-enumerable functions on the Object.prototype object. // Set up non-enumerable functions on the Object.prototype object.
InstallFunctions($Object.prototype, DONT_ENUM, $Array( InstallFunctions($Object.prototype, DONT_ENUM, $Array(
"toString", NoSideEffectsObjectToString, "toString", ObjectToString,
"toLocaleString", ObjectToLocaleString, "toLocaleString", ObjectToLocaleString,
"valueOf", ObjectValueOf, "valueOf", ObjectValueOf,
"hasOwnProperty", ObjectHasOwnProperty, "hasOwnProperty", ObjectHasOwnProperty,
......
...@@ -48,6 +48,9 @@ var funcs = [ ...@@ -48,6 +48,9 @@ var funcs = [
for (var fun of funcs) { for (var fun of funcs) {
var p = fun.prototype; 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)); assertEquals('[object Object]', Object.prototype.toString.call(p));
} }
...@@ -60,5 +63,5 @@ var funcs = [ ...@@ -60,5 +63,5 @@ var funcs = [
for (var fun of funcs) { for (var fun of funcs) {
var p = fun.prototype; var p = fun.prototype;
assertEquals('[object ' + fun.name + ']', Object.prototype.toString.call(p)); assertEquals(`[object ${fun.name}]`, Object.prototype.toString.call(p));
} }
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // 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. // executing inside the function.
assertTrue(toString.arguments === null);
function sloppy() {}
assertTrue(sloppy.arguments === null);
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