Improve Symbol() to string coercion error message
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 May 2016 01:21:38 +0000 (01:21 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 May 2016 01:21:38 +0000 (01:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157317

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Improve error messages related to Symbols.

* runtime/JSCJSValue.cpp:
(JSC::JSValue::toStringSlowCase):
* runtime/Symbol.cpp:
(JSC::Symbol::toNumber):
* runtime/SymbolConstructor.cpp:
(JSC::symbolConstructorKeyFor):
* runtime/SymbolPrototype.cpp:
(JSC::symbolProtoFuncToString):
(JSC::symbolProtoFuncValueOf):
* tests/stress/dfg-to-primitive-pass-symbol.js:
* tests/stress/floating-point-div-to-mul.js:
(i.catch):
* tests/stress/string-from-code-point.js:
(shouldThrow):
(string_appeared_here.shouldThrow):
* tests/stress/symbol-error-messages.js: Added.
(shouldThrow):
* tests/stress/symbol-registry.js:

LayoutTests:

* js/math-clz32-expected.txt:
* js/script-tests/symbol-abstract-relational-comparison.js:
(relationalOperators.forEach):
* js/script-tests/symbol-object.js:
* js/script-tests/symbol-prototype-is-ordinary-object.js:
* js/script-tests/symbol-tostring.js:
* js/string-code-point-at-expected.txt:
* js/symbol-abstract-relational-comparison-expected.txt:
* js/symbol-object-expected.txt:
* js/symbol-prototype-is-ordinary-object-expected.txt:
* js/symbol-tostring-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@200402 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/js/math-clz32-expected.txt
LayoutTests/js/script-tests/symbol-abstract-relational-comparison.js
LayoutTests/js/script-tests/symbol-object.js
LayoutTests/js/script-tests/symbol-prototype-is-ordinary-object.js
LayoutTests/js/script-tests/symbol-tostring.js
LayoutTests/js/string-code-point-at-expected.txt
LayoutTests/js/symbol-abstract-relational-comparison-expected.txt
LayoutTests/js/symbol-object-expected.txt
LayoutTests/js/symbol-prototype-is-ordinary-object-expected.txt
LayoutTests/js/symbol-tostring-expected.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSCJSValue.cpp
Source/JavaScriptCore/runtime/Symbol.cpp
Source/JavaScriptCore/runtime/SymbolConstructor.cpp
Source/JavaScriptCore/runtime/SymbolPrototype.cpp
Source/JavaScriptCore/tests/stress/dfg-to-primitive-pass-symbol.js
Source/JavaScriptCore/tests/stress/floating-point-div-to-mul.js
Source/JavaScriptCore/tests/stress/string-from-code-point.js
Source/JavaScriptCore/tests/stress/symbol-error-messages.js [new file with mode: 0644]
Source/JavaScriptCore/tests/stress/symbol-registry.js

index c9c494d..f3cf28a 100644 (file)
@@ -1,3 +1,22 @@
+2016-05-03  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Improve Symbol() to string coercion error message
+        https://bugs.webkit.org/show_bug.cgi?id=157317
+
+        Reviewed by Geoffrey Garen.
+
+        * js/math-clz32-expected.txt:
+        * js/script-tests/symbol-abstract-relational-comparison.js:
+        (relationalOperators.forEach):
+        * js/script-tests/symbol-object.js:
+        * js/script-tests/symbol-prototype-is-ordinary-object.js:
+        * js/script-tests/symbol-tostring.js:
+        * js/string-code-point-at-expected.txt:
+        * js/symbol-abstract-relational-comparison-expected.txt:
+        * js/symbol-object-expected.txt:
+        * js/symbol-prototype-is-ordinary-object-expected.txt:
+        * js/symbol-tostring-expected.txt:
+
 2016-05-03  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Give console.time/timeEnd a default label and warnings
index f4f3e44..74e914b 100644 (file)
@@ -31,7 +31,7 @@ PASS Math.clz32() is 32
 PASS Math.clz32(undefined) is 32
 PASS Math.clz32(null) is 32
 PASS Math.clz32("WebKit") is 32
-PASS Math.clz32(Symbol("WebKit")) threw exception TypeError: Type error.
+PASS Math.clz32(Symbol("WebKit")) threw exception TypeError: Cannot convert a symbol to a number.
 PASS Math.clz32({ webkit: "awesome" }) is 32
 PASS Math.clz32(objectConvertToString) is 25
 PASS Math.clz32(objectRecordToStringCall) is 28
index a2e775b..4c752ae 100644 (file)
@@ -29,8 +29,8 @@ relationalOperators.forEach(function (op) {
     ];
 
     targets.forEach(function (target) {
-        shouldThrow(target + " " + op + " symbol", "'TypeError: Type error'");
-        shouldThrow("symbol " + op + " " + target, "'TypeError: Type error'");
+        shouldThrow(target + " " + op + " symbol", `"TypeError: Cannot convert a symbol to a number"`);
+        shouldThrow("symbol " + op + " " + target, `"TypeError: Cannot convert a symbol to a number"`);
     });
 });
 
index 077c64e..396acf7 100644 (file)
@@ -11,7 +11,7 @@ var symbolObject = Object(Symbol.iterator);
 shouldBeTrue("symbolObject instanceof Symbol");
 // Since Symbol object's @@toPrimitive returns Symbol value,
 // ToString(symbol) will be called.
-shouldThrow("String(symbolObject)", "'TypeError: Type error'");
+shouldThrow("String(symbolObject)", `"TypeError: Cannot convert a symbol to a string"`);
 shouldBeEqualToString("symbolObject.toString()", "Symbol(Symbol.iterator)");
 
 var object = {};
index 9a8186e..8fe6237 100644 (file)
@@ -2,7 +2,7 @@ description(
 "This tests that Symbol.prototype object is ordinary object (not Symbol wrapper object)."
 );
 
-shouldThrow("Symbol.prototype.toString.call(Symbol.prototype)", "'TypeError: Type error'");
+shouldThrow("Symbol.prototype.toString.call(Symbol.prototype)", `"TypeError: Symbol.prototype.toString requires that |this| be a symbol or a symbol object"`);
 shouldBeEqualToString("Symbol.prototype.toString.call(Symbol.iterator)", "Symbol(Symbol.iterator)");
 
 successfullyParsed = true;
index 71836da..a15603e 100644 (file)
@@ -3,7 +3,7 @@ description(
 );
 
 shouldBeEqualToString("String(Symbol.iterator)", "Symbol(Symbol.iterator)");
-shouldThrow("String(Symbol.prototype)", "'TypeError: Type error'");
+shouldThrow("String(Symbol.prototype)", `"TypeError: Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object"`);
 shouldBeEqualToString("Symbol.prototype.toString.call(Symbol.iterator)", "Symbol(Symbol.iterator)");
 shouldBeEqualToString("Symbol.prototype.toString.call(Symbol('hello'))", "Symbol(hello)");
 shouldBeEqualToString("Symbol.prototype.toString.call(Symbol())", "Symbol()");
index 9f0b453..fac0f85 100644 (file)
@@ -34,7 +34,7 @@ PASS "".codePointAt.call(Math.PI, 3) is 52
 PASS "".codePointAt.call(true, 3) is 101
 PASS "".codePointAt.call(false, 3) is 115
 PASS "".codePointAt.call(new Object, 3) is 106
-PASS "".codePointAt.call(Symbol("WebKit"), 3) threw exception TypeError: Type error.
+PASS "".codePointAt.call(Symbol("WebKit"), 3) threw exception TypeError: Cannot convert a symbol to a string.
 PASS "".codePointAt.call(objectWithCustomToString, 0) is 248
 PASS "".codePointAt.call(objectThrowingOnToString, 0) threw exception Hehe.
 PASS "".codePointAt.call(objectCountingToString, 0) is 49
@@ -42,7 +42,7 @@ PASS objectCountingToString.counter is 1
 PASS "abcde".codePointAt(objectWithCustomValueOf) is 98
 PASS "".codePointAt.call(null, objectRecordsValueOf) threw exception TypeError: Type error.
 PASS "".codePointAt.call(undefined, objectRecordsValueOf) threw exception TypeError: Type error.
-PASS "".codePointAt.call(Symbol("WebKit"), objectRecordsValueOf) threw exception TypeError: Type error.
+PASS "".codePointAt.call(Symbol("WebKit"), objectRecordsValueOf) threw exception TypeError: Cannot convert a symbol to a string.
 PASS "".codePointAt.call(objectThrowingOnToString, objectRecordsValueOf) threw exception Hehe.
 PASS objectRecordsValueOf.valueOfEvaluated is false
 PASS "".codePointAt.call(evaluationOrderRecorder, evaluationOrderRecorder) is 114
@@ -66,7 +66,7 @@ PASS "abc".codePointAt(undefined) is 97
 PASS "abc".codePointAt("") is 97
 PASS "abc".codePointAt("WebKit!") is 97
 PASS "abc".codePointAt(new Object) is 97
-PASS "abc".codePointAt(Symbol("WebKit")) threw exception TypeError: Type error.
+PASS "abc".codePointAt(Symbol("WebKit")) threw exception TypeError: Cannot convert a symbol to a number.
 PASS testLeadSurrogateOutOfBounds() is true
 PASS testLeadSurrogateAsLastCharacter() is true
 PASS testTrailSurrogateOutOfbounds() is true
index 79071d3..76f049a 100644 (file)
@@ -3,110 +3,110 @@ This tests Abstract Relatioal Comparison results with Symbols.
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS 42 < symbol threw exception TypeError: Type error.
-PASS symbol < 42 threw exception TypeError: Type error.
-PASS NaN < symbol threw exception TypeError: Type error.
-PASS symbol < NaN threw exception TypeError: Type error.
-PASS Infinity < symbol threw exception TypeError: Type error.
-PASS symbol < Infinity threw exception TypeError: Type error.
-PASS true < symbol threw exception TypeError: Type error.
-PASS symbol < true threw exception TypeError: Type error.
-PASS false < symbol threw exception TypeError: Type error.
-PASS symbol < false threw exception TypeError: Type error.
-PASS null < symbol threw exception TypeError: Type error.
-PASS symbol < null threw exception TypeError: Type error.
-PASS undefined < symbol threw exception TypeError: Type error.
-PASS symbol < undefined threw exception TypeError: Type error.
-PASS 'Cappuccino' < symbol threw exception TypeError: Type error.
-PASS symbol < 'Cappuccino' threw exception TypeError: Type error.
-PASS symbol < symbol threw exception TypeError: Type error.
-PASS symbol < symbol threw exception TypeError: Type error.
-PASS Symbol.iterator < symbol threw exception TypeError: Type error.
-PASS symbol < Symbol.iterator threw exception TypeError: Type error.
-PASS object < symbol threw exception TypeError: Type error.
-PASS symbol < object threw exception TypeError: Type error.
-PASS array < symbol threw exception TypeError: Type error.
-PASS symbol < array threw exception TypeError: Type error.
-PASS date < symbol threw exception TypeError: Type error.
-PASS symbol < date threw exception TypeError: Type error.
-PASS 42 <= symbol threw exception TypeError: Type error.
-PASS symbol <= 42 threw exception TypeError: Type error.
-PASS NaN <= symbol threw exception TypeError: Type error.
-PASS symbol <= NaN threw exception TypeError: Type error.
-PASS Infinity <= symbol threw exception TypeError: Type error.
-PASS symbol <= Infinity threw exception TypeError: Type error.
-PASS true <= symbol threw exception TypeError: Type error.
-PASS symbol <= true threw exception TypeError: Type error.
-PASS false <= symbol threw exception TypeError: Type error.
-PASS symbol <= false threw exception TypeError: Type error.
-PASS null <= symbol threw exception TypeError: Type error.
-PASS symbol <= null threw exception TypeError: Type error.
-PASS undefined <= symbol threw exception TypeError: Type error.
-PASS symbol <= undefined threw exception TypeError: Type error.
-PASS 'Cappuccino' <= symbol threw exception TypeError: Type error.
-PASS symbol <= 'Cappuccino' threw exception TypeError: Type error.
-PASS symbol <= symbol threw exception TypeError: Type error.
-PASS symbol <= symbol threw exception TypeError: Type error.
-PASS Symbol.iterator <= symbol threw exception TypeError: Type error.
-PASS symbol <= Symbol.iterator threw exception TypeError: Type error.
-PASS object <= symbol threw exception TypeError: Type error.
-PASS symbol <= object threw exception TypeError: Type error.
-PASS array <= symbol threw exception TypeError: Type error.
-PASS symbol <= array threw exception TypeError: Type error.
-PASS date <= symbol threw exception TypeError: Type error.
-PASS symbol <= date threw exception TypeError: Type error.
-PASS 42 > symbol threw exception TypeError: Type error.
-PASS symbol > 42 threw exception TypeError: Type error.
-PASS NaN > symbol threw exception TypeError: Type error.
-PASS symbol > NaN threw exception TypeError: Type error.
-PASS Infinity > symbol threw exception TypeError: Type error.
-PASS symbol > Infinity threw exception TypeError: Type error.
-PASS true > symbol threw exception TypeError: Type error.
-PASS symbol > true threw exception TypeError: Type error.
-PASS false > symbol threw exception TypeError: Type error.
-PASS symbol > false threw exception TypeError: Type error.
-PASS null > symbol threw exception TypeError: Type error.
-PASS symbol > null threw exception TypeError: Type error.
-PASS undefined > symbol threw exception TypeError: Type error.
-PASS symbol > undefined threw exception TypeError: Type error.
-PASS 'Cappuccino' > symbol threw exception TypeError: Type error.
-PASS symbol > 'Cappuccino' threw exception TypeError: Type error.
-PASS symbol > symbol threw exception TypeError: Type error.
-PASS symbol > symbol threw exception TypeError: Type error.
-PASS Symbol.iterator > symbol threw exception TypeError: Type error.
-PASS symbol > Symbol.iterator threw exception TypeError: Type error.
-PASS object > symbol threw exception TypeError: Type error.
-PASS symbol > object threw exception TypeError: Type error.
-PASS array > symbol threw exception TypeError: Type error.
-PASS symbol > array threw exception TypeError: Type error.
-PASS date > symbol threw exception TypeError: Type error.
-PASS symbol > date threw exception TypeError: Type error.
-PASS 42 >= symbol threw exception TypeError: Type error.
-PASS symbol >= 42 threw exception TypeError: Type error.
-PASS NaN >= symbol threw exception TypeError: Type error.
-PASS symbol >= NaN threw exception TypeError: Type error.
-PASS Infinity >= symbol threw exception TypeError: Type error.
-PASS symbol >= Infinity threw exception TypeError: Type error.
-PASS true >= symbol threw exception TypeError: Type error.
-PASS symbol >= true threw exception TypeError: Type error.
-PASS false >= symbol threw exception TypeError: Type error.
-PASS symbol >= false threw exception TypeError: Type error.
-PASS null >= symbol threw exception TypeError: Type error.
-PASS symbol >= null threw exception TypeError: Type error.
-PASS undefined >= symbol threw exception TypeError: Type error.
-PASS symbol >= undefined threw exception TypeError: Type error.
-PASS 'Cappuccino' >= symbol threw exception TypeError: Type error.
-PASS symbol >= 'Cappuccino' threw exception TypeError: Type error.
-PASS symbol >= symbol threw exception TypeError: Type error.
-PASS symbol >= symbol threw exception TypeError: Type error.
-PASS Symbol.iterator >= symbol threw exception TypeError: Type error.
-PASS symbol >= Symbol.iterator threw exception TypeError: Type error.
-PASS object >= symbol threw exception TypeError: Type error.
-PASS symbol >= object threw exception TypeError: Type error.
-PASS array >= symbol threw exception TypeError: Type error.
-PASS symbol >= array threw exception TypeError: Type error.
-PASS date >= symbol threw exception TypeError: Type error.
-PASS symbol >= date threw exception TypeError: Type error.
+PASS 42 < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < 42 threw exception TypeError: Cannot convert a symbol to a number.
+PASS NaN < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < NaN threw exception TypeError: Cannot convert a symbol to a number.
+PASS Infinity < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < Infinity threw exception TypeError: Cannot convert a symbol to a number.
+PASS true < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < true threw exception TypeError: Cannot convert a symbol to a number.
+PASS false < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < false threw exception TypeError: Cannot convert a symbol to a number.
+PASS null < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < null threw exception TypeError: Cannot convert a symbol to a number.
+PASS undefined < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < undefined threw exception TypeError: Cannot convert a symbol to a number.
+PASS 'Cappuccino' < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < 'Cappuccino' threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS Symbol.iterator < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < Symbol.iterator threw exception TypeError: Cannot convert a symbol to a number.
+PASS object < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < object threw exception TypeError: Cannot convert a symbol to a number.
+PASS array < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < array threw exception TypeError: Cannot convert a symbol to a number.
+PASS date < symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol < date threw exception TypeError: Cannot convert a symbol to a number.
+PASS 42 <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= 42 threw exception TypeError: Cannot convert a symbol to a number.
+PASS NaN <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= NaN threw exception TypeError: Cannot convert a symbol to a number.
+PASS Infinity <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= Infinity threw exception TypeError: Cannot convert a symbol to a number.
+PASS true <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= true threw exception TypeError: Cannot convert a symbol to a number.
+PASS false <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= false threw exception TypeError: Cannot convert a symbol to a number.
+PASS null <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= null threw exception TypeError: Cannot convert a symbol to a number.
+PASS undefined <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= undefined threw exception TypeError: Cannot convert a symbol to a number.
+PASS 'Cappuccino' <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= 'Cappuccino' threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS Symbol.iterator <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= Symbol.iterator threw exception TypeError: Cannot convert a symbol to a number.
+PASS object <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= object threw exception TypeError: Cannot convert a symbol to a number.
+PASS array <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= array threw exception TypeError: Cannot convert a symbol to a number.
+PASS date <= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol <= date threw exception TypeError: Cannot convert a symbol to a number.
+PASS 42 > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > 42 threw exception TypeError: Cannot convert a symbol to a number.
+PASS NaN > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > NaN threw exception TypeError: Cannot convert a symbol to a number.
+PASS Infinity > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > Infinity threw exception TypeError: Cannot convert a symbol to a number.
+PASS true > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > true threw exception TypeError: Cannot convert a symbol to a number.
+PASS false > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > false threw exception TypeError: Cannot convert a symbol to a number.
+PASS null > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > null threw exception TypeError: Cannot convert a symbol to a number.
+PASS undefined > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > undefined threw exception TypeError: Cannot convert a symbol to a number.
+PASS 'Cappuccino' > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > 'Cappuccino' threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS Symbol.iterator > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > Symbol.iterator threw exception TypeError: Cannot convert a symbol to a number.
+PASS object > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > object threw exception TypeError: Cannot convert a symbol to a number.
+PASS array > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > array threw exception TypeError: Cannot convert a symbol to a number.
+PASS date > symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol > date threw exception TypeError: Cannot convert a symbol to a number.
+PASS 42 >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= 42 threw exception TypeError: Cannot convert a symbol to a number.
+PASS NaN >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= NaN threw exception TypeError: Cannot convert a symbol to a number.
+PASS Infinity >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= Infinity threw exception TypeError: Cannot convert a symbol to a number.
+PASS true >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= true threw exception TypeError: Cannot convert a symbol to a number.
+PASS false >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= false threw exception TypeError: Cannot convert a symbol to a number.
+PASS null >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= null threw exception TypeError: Cannot convert a symbol to a number.
+PASS undefined >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= undefined threw exception TypeError: Cannot convert a symbol to a number.
+PASS 'Cappuccino' >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= 'Cappuccino' threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS Symbol.iterator >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= Symbol.iterator threw exception TypeError: Cannot convert a symbol to a number.
+PASS object >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= object threw exception TypeError: Cannot convert a symbol to a number.
+PASS array >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= array threw exception TypeError: Cannot convert a symbol to a number.
+PASS date >= symbol threw exception TypeError: Cannot convert a symbol to a number.
+PASS symbol >= date threw exception TypeError: Cannot convert a symbol to a number.
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 3d59d98..4e46317 100644 (file)
@@ -6,7 +6,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 PASS new Symbol threw exception TypeError: function is not a constructor (evaluating 'new Symbol').
 PASS new Symbol('Cappuccino') threw exception TypeError: function is not a constructor (evaluating 'new Symbol('Cappuccino')').
 PASS symbolObject instanceof Symbol is true
-PASS String(symbolObject) threw exception TypeError: Type error.
+PASS String(symbolObject) threw exception TypeError: Cannot convert a symbol to a string.
 PASS symbolObject.toString() is "Symbol(Symbol.iterator)"
 PASS object[symbolObject] is 42
 PASS object['Symbol(Symbol.iterator)'] is undefined
index 8ff3c2b..110d477 100644 (file)
@@ -3,7 +3,7 @@ This tests that Symbol.prototype object is ordinary object (not Symbol wrapper o
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS Symbol.prototype.toString.call(Symbol.prototype) threw exception TypeError: Type error.
+PASS Symbol.prototype.toString.call(Symbol.prototype) threw exception TypeError: Symbol.prototype.toString requires that |this| be a symbol or a symbol object.
 PASS Symbol.prototype.toString.call(Symbol.iterator) is "Symbol(Symbol.iterator)"
 PASS successfullyParsed is true
 
index be39daf..3dd27db 100644 (file)
@@ -4,7 +4,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 
 PASS String(Symbol.iterator) is "Symbol(Symbol.iterator)"
-PASS String(Symbol.prototype) threw exception TypeError: Type error.
+PASS String(Symbol.prototype) threw exception TypeError: Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object.
 PASS Symbol.prototype.toString.call(Symbol.iterator) is "Symbol(Symbol.iterator)"
 PASS Symbol.prototype.toString.call(Symbol('hello')) is "Symbol(hello)"
 PASS Symbol.prototype.toString.call(Symbol()) is "Symbol()"
index b9d4b7c..57a5b24 100644 (file)
@@ -1,3 +1,31 @@
+2016-05-03  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Improve Symbol() to string coercion error message
+        https://bugs.webkit.org/show_bug.cgi?id=157317
+
+        Reviewed by Geoffrey Garen.
+
+        Improve error messages related to Symbols.
+
+        * runtime/JSCJSValue.cpp:
+        (JSC::JSValue::toStringSlowCase):
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::toNumber):
+        * runtime/SymbolConstructor.cpp:
+        (JSC::symbolConstructorKeyFor):
+        * runtime/SymbolPrototype.cpp:
+        (JSC::symbolProtoFuncToString):
+        (JSC::symbolProtoFuncValueOf):
+        * tests/stress/dfg-to-primitive-pass-symbol.js:
+        * tests/stress/floating-point-div-to-mul.js:
+        (i.catch):
+        * tests/stress/string-from-code-point.js:
+        (shouldThrow):
+        (string_appeared_here.shouldThrow):
+        * tests/stress/symbol-error-messages.js: Added.
+        (shouldThrow):
+        * tests/stress/symbol-registry.js:
+
 2016-05-03  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Give console.time/timeEnd a default label and warnings
index 75487d6..ca4f558 100644 (file)
@@ -391,7 +391,7 @@ JSString* JSValue::toStringSlowCase(ExecState* exec, bool returnEmptyStringOnErr
     if (isUndefined())
         return vm.smallStrings.undefinedString();
     if (isSymbol()) {
-        throwTypeError(exec);
+        throwTypeError(exec, "Cannot convert a symbol to a string");
         return errorValue();
     }
 
index a765609..cd051a7 100644 (file)
@@ -79,7 +79,7 @@ JSObject* Symbol::toObject(ExecState* exec, JSGlobalObject* globalObject) const
 
 double Symbol::toNumber(ExecState* exec) const
 {
-    throwTypeError(exec);
+    throwTypeError(exec, "Cannot convert a symbol to a number");
     return 0.0;
 }
 
index 740fb68..132e4a7 100644 (file)
@@ -111,11 +111,13 @@ EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState* exec)
     return JSValue::encode(Symbol::create(exec->vm(), exec->vm().symbolRegistry().symbolForKey(string)));
 }
 
+const char* SymbolKeyForTypeError = "Symbol.keyFor requires that the first argument be a symbol";
+
 EncodedJSValue JSC_HOST_CALL symbolConstructorKeyFor(ExecState* exec)
 {
     JSValue symbolValue = exec->argument(0);
     if (!symbolValue.isSymbol())
-        return JSValue::encode(throwTypeError(exec));
+        return JSValue::encode(throwTypeError(exec, SymbolKeyForTypeError));
 
     SymbolImpl* uid = asSymbol(symbolValue)->privateName().uid();
     if (!uid->symbolRegistry())
index 46c0cc7..2bb407c 100644 (file)
@@ -72,18 +72,21 @@ bool SymbolPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, Prop
 
 // ------------------------------ Functions ---------------------------
 
+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)
 {
     JSValue thisValue = exec->thisValue();
     Symbol* symbol = nullptr;
     if (thisValue.isSymbol())
         symbol = asSymbol(thisValue);
-    else if (!thisValue.isObject())
-        return throwVMTypeError(exec);
     else {
+        if (!thisValue.isObject())
+            return throwVMTypeError(exec, SymbolToStringTypeError);
         JSObject* thisObject = asObject(thisValue);
         if (!thisObject->inherits(SymbolObject::info()))
-            return throwVMTypeError(exec);
+            return throwVMTypeError(exec, SymbolToStringTypeError);
         symbol = asSymbol(jsCast<SymbolObject*>(thisObject)->internalValue());
     }
 
@@ -97,11 +100,11 @@ EncodedJSValue JSC_HOST_CALL symbolProtoFuncValueOf(ExecState* exec)
         return JSValue::encode(thisValue);
 
     if (!thisValue.isObject())
-        return throwVMTypeError(exec);
+        return throwVMTypeError(exec, SymbolValueOfTypeError);
 
     JSObject* thisObject = asObject(thisValue);
     if (!thisObject->inherits(SymbolObject::info()))
-        return throwVMTypeError(exec);
+        return throwVMTypeError(exec, SymbolValueOfTypeError);
 
     return JSValue::encode(jsCast<SymbolObject*>(thisObject)->internalValue());
 }
index 2a5ffa9..5d26574 100644 (file)
@@ -31,5 +31,5 @@ try {
     didThrow = e;
 }
 
-if (String(didThrow) !== "TypeError: Type error")
+if (String(didThrow) !== "TypeError: Cannot convert a symbol to a string")
     throw "Error: didn't throw or threw wrong exception: " + didThrow;
index 6146b68..6ce0503 100644 (file)
@@ -201,7 +201,7 @@ for (let i = 0; i < 1e3; ++i) {
         result = opaqueDivBy2(Symbol());
         throw "Failed opaqueDivBy2(Symbol())";
     } catch (exception) {
-        if (exception != "TypeError: Type error")
+        if (exception != "TypeError: Cannot convert a symbol to a number")
             throw "Wrong exception: " + exception;
     }
     result = opaqueDivBy4(true);
index 093658f..1ae22ec 100644 (file)
@@ -105,7 +105,7 @@ for (var test of invalidTests) {
 // toNumber causes errors.
 shouldThrow(function () {
     String.fromCodePoint(Symbol.iterator);
-}, "TypeError: Type error")
+}, "TypeError: Cannot convert a symbol to a number")
 
 var toNumberObject = {
     valueOf() {
@@ -119,7 +119,7 @@ shouldThrow(function () {
 
 shouldThrow(function () {
     String.fromCodePoint(Symbol.iterator, toNumberObject);
-}, "TypeError: Type error")
+}, "TypeError: Cannot convert a symbol to a number")
 
 var convertAndPassTests = [
     [ null, "\0" ],
diff --git a/Source/JavaScriptCore/tests/stress/symbol-error-messages.js b/Source/JavaScriptCore/tests/stress/symbol-error-messages.js
new file mode 100644 (file)
index 0000000..8e3531e
--- /dev/null
@@ -0,0 +1,46 @@
+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 symbol = Symbol("Cocoa");
+
+shouldThrow(() => {
+    // ToString => error.
+    "" + symbol;
+}, `TypeError: Cannot convert a symbol to a string`);
+
+shouldThrow(() => {
+    // ToNumber => error.
+    +symbol;
+}, `TypeError: Cannot convert a symbol to a number`);
+
+shouldThrow(() => {
+    Symbol.keyFor("Cappuccino");
+}, `TypeError: Symbol.keyFor requires that the first argument be a symbol`);
+
+shouldThrow(() => {
+    Symbol.prototype.toString.call(null);
+}, `TypeError: Symbol.prototype.toString requires that |this| be a symbol or a symbol object`);
+
+shouldThrow(() => {
+    Symbol.prototype.toString.call({});
+}, `TypeError: Symbol.prototype.toString requires that |this| be a symbol or a symbol object`);
+
+shouldThrow(() => {
+    Symbol.prototype.valueOf.call(null);
+}, `TypeError: Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object`);
+
+shouldThrow(() => {
+    Symbol.prototype.valueOf.call({});
+}, `TypeError: Symbol.prototype.valueOf requires that |this| be a symbol or a symbol object`);
index 8a1a05a..5ea3663 100644 (file)
@@ -89,7 +89,7 @@ function test(actual, expected) {
         }
         if (!error)
             throw new Error('not thrown');
-        if (String(error) !== 'TypeError: Type error')
+        if (String(error) !== 'TypeError: Symbol.keyFor requires that the first argument be a symbol')
             throw new Error('bad error: ' + String(error));
     }
 }());