| Index: src/symbol.js
|
| diff --git a/src/symbol.js b/src/symbol.js
|
| index 050e7d918a02e83934883f280ec75be9424ba9db..9be1c1fd8c4c879f962e3e2b3c60372d4c8bd7f1 100644
|
| --- a/src/symbol.js
|
| +++ b/src/symbol.js
|
| @@ -36,36 +36,55 @@ var $Symbol = global.Symbol;
|
| // -------------------------------------------------------------------
|
|
|
| function SymbolConstructor(x) {
|
| - var value =
|
| - IS_SYMBOL(x) ? x : %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
|
| if (%_IsConstructCall()) {
|
| - %_SetValueOf(this, value);
|
| + throw MakeTypeError('not_constructor', ["Symbol"]);
|
| } else {
|
| + // NOTE: Passing in a Symbol value will throw on ToString().
|
| + var value = %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
|
| return value;
|
| }
|
| }
|
|
|
| -function SymbolGetName() {
|
| - var symbol = IS_SYMBOL_WRAPPER(this) ? %_ValueOf(this) : this;
|
| - if (!IS_SYMBOL(symbol)) {
|
| - throw MakeTypeError(
|
| - 'incompatible_method_receiver', ["Symbol.prototype.name", this]);
|
| +// The wrapper object for Symbols.
|
| +function $SymbolWrapper(x) {
|
| + if (!%_IsConstructCall()) {
|
| + throw MakeTypeError('constructor_not_function', ["Symbol"]);
|
| + } else if (!IS_SYMBOL(x)) {
|
| + // A bug elsewhere; shouldn't be possible.
|
| + throw MakeTypeError('symbol_value_expected', []);
|
| + } else {
|
| + %SymbolSetSymbolData(this, x);
|
| }
|
| - return %SymbolName(symbol);
|
| }
|
|
|
| function SymbolToString() {
|
| - throw MakeTypeError('symbol_to_string');
|
| + if (this === $SymbolWrapper.prototype) {
|
| + return "Symbol";
|
| + } else if (!IS_SYMBOL_WRAPPER(this)) {
|
| + throw MakeTypeError(
|
| + 'incompatible_method_receiver', ["Symbol.prototype.toString", this]);
|
| + } else {
|
| + var symbol = %SymbolGetSymbolData(this);
|
| + if (IS_UNDEFINED(symbol)) {
|
| + throw MakeTypeError('symbol_data_undefined', []);
|
| + } else {
|
| + var description = %SymbolDescription(symbol);
|
| + return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")";
|
| + }
|
| + }
|
| }
|
|
|
| function SymbolValueOf() {
|
| - // NOTE: Both Symbol objects and values can enter here as
|
| - // 'this'. This is not as dictated by ECMA-262.
|
| - if (!IS_SYMBOL(this) && !IS_SYMBOL_WRAPPER(this)) {
|
| + if (!IS_SYMBOL_WRAPPER(this)) {
|
| throw MakeTypeError(
|
| - 'incompatible_method_receiver', ["Symbol.prototype.valueOf", this]);
|
| + 'incompatible_method_receiver', ["Symbol.prototype.valueOf", this]);
|
| + } else {
|
| + var symbol = %SymbolGetSymbolData(this);
|
| + if (IS_UNDEFINED(symbol)) {
|
| + throw MakeTypeError('symbol_data_undefined', [])
|
| + }
|
| + return symbol;
|
| }
|
| - return %_ValueOf(this);
|
| }
|
|
|
| //-------------------------------------------------------------------
|
| @@ -73,12 +92,15 @@ function SymbolValueOf() {
|
| function SetUpSymbol() {
|
| %CheckIsBootstrapping();
|
|
|
| + // The global function for creating new Symbol values.
|
| %SetCode($Symbol, SymbolConstructor);
|
| - %FunctionSetPrototype($Symbol, new $Symbol());
|
| - %SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
|
| + %FunctionSetPrototype($Symbol, $Function.prototype);
|
| +
|
| + // A [[Class]] of "Symbol" is assumed for wrapper objects.
|
| + %FunctionSetInstanceClassName($SymbolWrapper, "Symbol");
|
| + %SetProperty($SymbolWrapper.prototype, "constructor", $Symbol, DONT_ENUM);
|
|
|
| - InstallGetter($Symbol.prototype, "name", SymbolGetName);
|
| - InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
|
| + InstallFunctions($SymbolWrapper.prototype, DONT_ENUM, $Array(
|
| "toString", SymbolToString,
|
| "valueOf", SymbolValueOf
|
| ));
|
|
|