[bigint] Install Symbol.toStringTag and adapt O.p.toString.
Bug: v8:6791 Change-Id: I10bb316284ba3a0e326daad4f9b995f88d76c2a2 Reviewed-on: https://chromium-review.googlesource.com/739501 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#48982}
This commit is contained in:
parent
0b0bfc4bc3
commit
401b39b1dd
@ -4361,10 +4361,11 @@ void Genesis::InitializeGlobal_harmony_regexp_dotall() {
|
||||
void Genesis::InitializeGlobal_harmony_bigint() {
|
||||
if (!FLAG_harmony_bigint) return;
|
||||
|
||||
Factory* factory = isolate()->factory();
|
||||
Handle<JSGlobalObject> global(native_context()->global_object());
|
||||
Handle<JSFunction> bigint_fun = InstallFunction(
|
||||
global, "BigInt", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
isolate()->factory()->the_hole_value(), Builtins::kBigIntConstructor);
|
||||
Handle<JSFunction> bigint_fun =
|
||||
InstallFunction(global, "BigInt", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
factory->the_hole_value(), Builtins::kBigIntConstructor);
|
||||
bigint_fun->shared()->DontAdaptArguments();
|
||||
bigint_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate(), BigIntConstructor_ConstructStub));
|
||||
@ -4400,6 +4401,10 @@ void Genesis::InitializeGlobal_harmony_bigint() {
|
||||
// valueOf()
|
||||
SimpleInstallFunction(prototype, "valueOf", Builtins::kBigIntPrototypeValueOf,
|
||||
0, false);
|
||||
// @@toStringTag
|
||||
JSObject::AddProperty(prototype, factory->to_string_tag_symbol(),
|
||||
factory->BigInt_string(),
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
}
|
||||
|
||||
#ifdef V8_INTL_SUPPORT
|
||||
|
@ -303,7 +303,7 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) {
|
||||
if_error(this), if_function(this), if_number(this, Label::kDeferred),
|
||||
if_object(this), if_primitive(this), if_proxy(this, Label::kDeferred),
|
||||
if_regexp(this), if_string(this), if_symbol(this, Label::kDeferred),
|
||||
if_value(this);
|
||||
if_value(this), if_bigint(this, Label::kDeferred);
|
||||
|
||||
Node* receiver = Parameter(Descriptor::kReceiver);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
@ -427,19 +427,19 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) {
|
||||
|
||||
BIND(&if_primitive);
|
||||
{
|
||||
Label return_null(this), return_undefined(this);
|
||||
Label return_undefined(this);
|
||||
|
||||
GotoIf(IsStringInstanceType(receiver_instance_type), &if_string);
|
||||
GotoIf(IsBigIntInstanceType(receiver_instance_type), &if_bigint);
|
||||
GotoIf(IsBooleanMap(receiver_map), &if_boolean);
|
||||
GotoIf(IsHeapNumberMap(receiver_map), &if_number);
|
||||
GotoIf(IsSymbolMap(receiver_map), &if_symbol);
|
||||
Branch(IsUndefined(receiver), &return_undefined, &return_null);
|
||||
GotoIf(IsUndefined(receiver), &return_undefined);
|
||||
CSA_ASSERT(this, IsNull(receiver));
|
||||
Return(LoadRoot(Heap::knull_to_stringRootIndex));
|
||||
|
||||
BIND(&return_undefined);
|
||||
Return(LoadRoot(Heap::kundefined_to_stringRootIndex));
|
||||
|
||||
BIND(&return_null);
|
||||
Return(LoadRoot(Heap::knull_to_stringRootIndex));
|
||||
}
|
||||
|
||||
BIND(&if_proxy);
|
||||
@ -507,6 +507,20 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) {
|
||||
Goto(&checkstringtag);
|
||||
}
|
||||
|
||||
BIND(&if_bigint);
|
||||
{
|
||||
Node* native_context = LoadNativeContext(context);
|
||||
Node* bigint_constructor =
|
||||
LoadContextElement(native_context, Context::BIGINT_FUNCTION_INDEX);
|
||||
Node* bigint_initial_map = LoadObjectField(
|
||||
bigint_constructor, JSFunction::kPrototypeOrInitialMapOffset);
|
||||
Node* bigint_prototype =
|
||||
LoadObjectField(bigint_initial_map, Map::kPrototypeOffset);
|
||||
var_default.Bind(LoadRoot(Heap::kobject_to_stringRootIndex));
|
||||
var_holder.Bind(bigint_prototype);
|
||||
Goto(&checkstringtag);
|
||||
}
|
||||
|
||||
BIND(&if_value);
|
||||
{
|
||||
Node* receiver_value = LoadJSValueValue(receiver);
|
||||
@ -514,7 +528,12 @@ TF_BUILTIN(ObjectPrototypeToString, ObjectBuiltinsAssembler) {
|
||||
Node* receiver_value_map = LoadMap(receiver_value);
|
||||
GotoIf(IsHeapNumberMap(receiver_value_map), &if_number);
|
||||
GotoIf(IsBooleanMap(receiver_value_map), &if_boolean);
|
||||
Branch(IsSymbolMap(receiver_value_map), &if_symbol, &if_string);
|
||||
GotoIf(IsSymbolMap(receiver_value_map), &if_symbol);
|
||||
Node* receiver_value_instance_type =
|
||||
LoadMapInstanceType(receiver_value_map);
|
||||
GotoIf(IsBigIntInstanceType(receiver_value_instance_type), &if_bigint);
|
||||
CSA_ASSERT(this, IsStringInstanceType(receiver_value_instance_type));
|
||||
Goto(&if_string);
|
||||
}
|
||||
|
||||
BIND(&checkstringtag);
|
||||
|
@ -20,6 +20,32 @@ const six = BigInt(6);
|
||||
assertSame(BigInt, BigInt.prototype.constructor)
|
||||
}
|
||||
|
||||
// BigInt.prototype[Symbol.toStringTag]
|
||||
{
|
||||
const toStringTag = Object.getOwnPropertyDescriptor(
|
||||
BigInt.prototype, Symbol.toStringTag);
|
||||
assertTrue(toStringTag.configurable);
|
||||
assertFalse(toStringTag.enumerable);
|
||||
assertFalse(toStringTag.writable);
|
||||
assertEquals("BigInt", toStringTag.value);
|
||||
}
|
||||
|
||||
// Object.prototype.toString
|
||||
{
|
||||
const toString = Object.prototype.toString;
|
||||
|
||||
assertEquals("[object BigInt]", toString.call(42n));
|
||||
assertEquals("[object BigInt]", toString.call(Object(42n)));
|
||||
|
||||
delete BigInt.prototype[Symbol.toStringTag];
|
||||
assertEquals("[object Object]", toString.call(42n));
|
||||
assertEquals("[object Object]", toString.call(Object(42n)));
|
||||
|
||||
BigInt.prototype[Symbol.toStringTag] = "foo";
|
||||
assertEquals("[object foo]", toString.call(42n));
|
||||
assertEquals("[object foo]", toString.call(Object(42n)));
|
||||
}
|
||||
|
||||
// typeof
|
||||
{
|
||||
assertEquals(typeof zero, "bigint");
|
||||
|
Loading…
Reference in New Issue
Block a user