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 |
)); |