WebKit Bugzilla
Attachment 341490 Details for
Bug 186053
: [JSC] Add Symbol.prototype.description getter
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-186053-20180530011942.patch (text/plain), 10.21 KB, created by
Yusuke Suzuki
on 2018-05-29 09:19:43 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-05-29 09:19:43 PDT
Size:
10.21 KB
patch
obsolete
>Subversion Revision: 232255 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 9101f8a96c59fe58653ac0c00150e3c1a22c9ecc..60e1c62b91ac135497d132331396fcc9607a8fbb 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,26 @@ >+2018-05-29 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [JSC] Add Symbol.prototype.description getter >+ https://bugs.webkit.org/show_bug.cgi?id=186053 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Symbol.prototype.description accessor is now stage 3[1]. >+ This adds a getter to retrieve [[Description]] value from Symbol. >+ Previously, Symbol#toString() returns `Symbol(${description})` value. >+ So users need to extract `description` part if they want it. >+ >+ [1]: https://tc39.github.io/proposal-Symbol-description/ >+ >+ * runtime/Symbol.cpp: >+ (JSC::Symbol::description const): >+ * runtime/Symbol.h: >+ * runtime/SymbolPrototype.cpp: >+ (JSC::tryExtractSymbol): >+ (JSC::symbolProtoGetterDescription): >+ (JSC::symbolProtoFuncToString): >+ (JSC::symbolProtoFuncValueOf): >+ > 2018-05-27 Yusuke Suzuki <utatane.tea@gmail.com> > > [JSC] JSBigInt::digitDiv has undefined behavior which causes test failures >diff --git a/Source/JavaScriptCore/runtime/Symbol.cpp b/Source/JavaScriptCore/runtime/Symbol.cpp >index 55aad742e09138fa81f4b66d1b0e6597e90107d3..d3e465ae80d09536045148e95ee0f33b0ed18441 100644 >--- a/Source/JavaScriptCore/runtime/Symbol.cpp >+++ b/Source/JavaScriptCore/runtime/Symbol.cpp >@@ -103,6 +103,11 @@ String Symbol::descriptiveString() const > return makeString("Symbol(", String(privateName().uid()), ')'); > } > >+String Symbol::description() const >+{ >+ return privateName().uid(); >+} >+ > Symbol* Symbol::create(VM& vm) > { > Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm); >diff --git a/Source/JavaScriptCore/runtime/Symbol.h b/Source/JavaScriptCore/runtime/Symbol.h >index 1a4a2a0d83cfad94919f1d582769d706bd388cbd..71023e61abf00d44edcc851ba92264369710ecc6 100644 >--- a/Source/JavaScriptCore/runtime/Symbol.h >+++ b/Source/JavaScriptCore/runtime/Symbol.h >@@ -57,6 +57,7 @@ class Symbol final : public JSCell { > > const PrivateName& privateName() const { return m_privateName; } > String descriptiveString() const; >+ String description() const; > > JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; > bool getPrimitiveNumber(ExecState*, double& number, JSValue&) const; >diff --git a/Source/JavaScriptCore/runtime/SymbolPrototype.cpp b/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >index 3d798c6dce5ebba25812fc40a281b76b451bff20..354d5681fbd304e8dcc4b8cdebb1ef2647c45934 100644 >--- a/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >+++ b/Source/JavaScriptCore/runtime/SymbolPrototype.cpp >@@ -34,6 +34,7 @@ > > namespace JSC { > >+static EncodedJSValue JSC_HOST_CALL symbolProtoGetterDescription(ExecState*); > static EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState*); > static EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState*); > >@@ -47,6 +48,7 @@ const ClassInfo SymbolPrototype::s_info = { "Symbol", &Base::s_info, &symbolProt > > /* Source for SymbolPrototype.lut.h > @begin symbolPrototypeTable >+ description symbolProtoGetterDescription DontEnum|Accessor 0 > toString symbolProtoFuncToString DontEnum|Function 0 > valueOf symbolProtoFuncValueOf DontEnum|Function 0 > @end >@@ -69,47 +71,58 @@ void SymbolPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject) > > // ------------------------------ Functions --------------------------- > >+static const char* SymbolDescriptionTypeError = "Symbol.prototype.description requires that |this| be a symbol or a symbol object"; > static const char* SymbolToStringTypeError = "Symbol.prototype.toString requires that |this| be a symbol or a symbol object"; > static const char* SymbolValueOfTypeError = "Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object"; > >-EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState* exec) >+static inline Symbol* tryExtractSymbol(VM& vm, JSValue thisValue) >+{ >+ if (thisValue.isSymbol()) >+ return asSymbol(thisValue); >+ >+ if (!thisValue.isObject()) >+ return nullptr; >+ JSObject* thisObject = asObject(thisValue); >+ if (!thisObject->inherits<SymbolObject>(vm)) >+ return nullptr; >+ return asSymbol(jsCast<SymbolObject*>(thisObject)->internalValue()); >+} >+ >+EncodedJSValue JSC_HOST_CALL symbolProtoGetterDescription(ExecState* exec) > { > VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >- JSValue thisValue = exec->thisValue(); >- Symbol* symbol = nullptr; >- if (thisValue.isSymbol()) >- symbol = asSymbol(thisValue); >- else { >- if (!thisValue.isObject()) >- return throwVMTypeError(exec, scope, SymbolToStringTypeError); >- JSObject* thisObject = asObject(thisValue); >- if (!thisObject->inherits<SymbolObject>(vm)) >- return throwVMTypeError(exec, scope, SymbolToStringTypeError); >- symbol = asSymbol(jsCast<SymbolObject*>(thisObject)->internalValue()); >- } >- >- return JSValue::encode(jsNontrivialString(exec, symbol->descriptiveString())); >+ Symbol* symbol = tryExtractSymbol(vm, exec->thisValue()); >+ if (!symbol) >+ return throwVMTypeError(exec, scope, SymbolDescriptionTypeError); >+ scope.release(); >+ return JSValue::encode(jsString(&vm, symbol->description())); > } > >-EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState* exec) >+EncodedJSValue JSC_HOST_CALL symbolProtoFuncToString(ExecState* exec) > { > VM& vm = exec->vm(); > auto scope = DECLARE_THROW_SCOPE(vm); > >- JSValue thisValue = exec->thisValue(); >- if (thisValue.isSymbol()) >- return JSValue::encode(thisValue); >+ Symbol* symbol = tryExtractSymbol(vm, exec->thisValue()); >+ if (!symbol) >+ return throwVMTypeError(exec, scope, SymbolToStringTypeError); >+ scope.release(); >+ return JSValue::encode(jsNontrivialString(&vm, symbol->descriptiveString())); >+} > >- if (!thisValue.isObject()) >- return throwVMTypeError(exec, scope, SymbolValueOfTypeError); >+EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState* exec) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); > >- JSObject* thisObject = asObject(thisValue); >- if (!thisObject->inherits<SymbolObject>(vm)) >+ Symbol* symbol = tryExtractSymbol(vm, exec->thisValue()); >+ if (!symbol) > return throwVMTypeError(exec, scope, SymbolValueOfTypeError); > >- return JSValue::encode(jsCast<SymbolObject*>(thisObject)->internalValue()); >+ scope.release(); >+ return JSValue::encode(symbol); > } > > } // namespace JSC >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index d9757587d901ba6d880cfe9e0e60677bbc348d94..35f447cff54a89ca1342ff1af246f0992707a1b0 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-05-29 Yusuke Suzuki <utatane.tea@gmail.com> >+ >+ [JSC] Add Symbol.prototype.description getter >+ https://bugs.webkit.org/show_bug.cgi?id=186053 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/symbol-description.js: Added. >+ (shouldBe): >+ (shouldThrow): >+ > 2018-05-27 Caio Lima <ticaiolima@gmail.com> > > [ESNext][BigInt] Implement "+" and "-" unary operation >diff --git a/JSTests/stress/symbol-description.js b/JSTests/stress/symbol-description.js >new file mode 100644 >index 0000000000000000000000000000000000000000..27e39797c11c0787110bf6b6f22e123e86d94b2f >--- /dev/null >+++ b/JSTests/stress/symbol-description.js >@@ -0,0 +1,83 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error(`bad value: ${String(actual)}`); >+} >+ >+function shouldThrow(func, errorMessage) { >+ var errorThrown = false; >+ var error = null; >+ try { >+ func(); >+ } catch (e) { >+ errorThrown = true; >+ error = e; >+ } >+ if (!errorThrown) >+ throw new Error('not thrown'); >+ if (String(error) !== errorMessage) >+ throw new Error(`bad error: ${String(error)}`); >+} >+ >+var s0 = Symbol("Cocoa"); >+var s1 = Symbol("Cappuccino"); >+ >+shouldBe(s0.description, "Cocoa"); >+shouldBe(s0.toString(), "Symbol(Cocoa)"); >+shouldBe(s1.description, "Cappuccino"); >+shouldBe(s1.toString(), "Symbol(Cappuccino)"); >+ >+var o0 = Object(s0); >+var o1 = Object(s1); >+ >+shouldBe(o0.description, "Cocoa"); >+shouldBe(o0.toString(), "Symbol(Cocoa)"); >+shouldBe(o1.description, "Cappuccino"); >+shouldBe(o1.toString(), "Symbol(Cappuccino)"); >+ >+var descriptor = Object.getOwnPropertyDescriptor(Symbol.prototype, "description"); >+shouldBe(descriptor.enumerable, false); >+shouldBe(descriptor.configurable, true); >+shouldBe(descriptor.set, undefined); >+shouldBe(typeof descriptor.get, "function"); >+ >+shouldThrow(() => { >+ "use strict"; >+ s0.description = "Matcha"; >+}, `TypeError: Attempted to assign to readonly property.`); >+shouldThrow(() => { >+ "use strict"; >+ o0.description = "Matcha"; >+}, `TypeError: Attempted to assign to readonly property.`); >+ >+shouldThrow(() => { >+ descriptor.get.call({}); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call(null); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call(undefined); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call(42); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call("Hello"); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call(42.195); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldThrow(() => { >+ descriptor.get.call(false); >+}, `TypeError: Symbol.prototype.description requires that |this| be a symbol or a symbol object`); >+ >+shouldBe(descriptor.get.call(s0), "Cocoa"); >+shouldBe(descriptor.get.call(o0), "Cocoa"); >+o0.__proto__ = {}; >+shouldBe(descriptor.get.call(o0), "Cocoa");
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 186053
:
341490
|
341496
|
341497