[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:
parent
a5d71c2cac
commit
48eff34c32
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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") \
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user