[es6] Implement spec compliant ToPrimitive in the runtime.
[platform/upstream/v8.git] / src / symbol.js
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Expects following symbols to be set in the bootstrapper during genesis:
6 // - symbolHasInstance
7 // - symbolIsConcatSpreadable
8 // - symbolIsRegExp
9 // - symbolIterator
10 // - symbolToPrimitive
11 // - symbolToStringTag
12 // - symbolUnscopables
13
14 var $symbolToString;
15
16 (function(global, utils) {
17
18 "use strict";
19
20 %CheckIsBootstrapping();
21
22 // -------------------------------------------------------------------
23 // Imports
24
25 var GlobalObject = global.Object;
26 var GlobalSymbol = global.Symbol;
27 var ObjectGetOwnPropertyKeys;
28 var ToString;
29
30 utils.Import(function(from) {
31   ObjectGetOwnPropertyKeys = from.ObjectGetOwnPropertyKeys;
32   ToString = from.ToString;
33 });
34
35 // -------------------------------------------------------------------
36
37 function SymbolConstructor(x) {
38   if (%_IsConstructCall()) throw MakeTypeError(kNotConstructor, "Symbol");
39   // NOTE: Passing in a Symbol value will throw on ToString().
40   return %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
41 }
42
43
44 // 19.4.3.4 Symbol.prototype [ @@toPrimitive ] ( hint )
45 function SymbolToPrimitive(hint) {
46   if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
47     throw MakeTypeError(kIncompatibleMethodReceiver,
48                         "Symbol.prototype [ @@toPrimitive ]", this);
49   }
50   return %_ValueOf(this);
51 }
52
53
54 function SymbolToString() {
55   if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
56     throw MakeTypeError(kIncompatibleMethodReceiver,
57                         "Symbol.prototype.toString", this);
58   }
59   var description = %SymbolDescription(%_ValueOf(this));
60   return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")";
61 }
62
63
64 function SymbolValueOf() {
65   if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
66     throw MakeTypeError(kIncompatibleMethodReceiver,
67                         "Symbol.prototype.valueOf", this);
68   }
69   return %_ValueOf(this);
70 }
71
72
73 function SymbolFor(key) {
74   key = TO_STRING_INLINE(key);
75   var registry = %SymbolRegistry();
76   if (IS_UNDEFINED(registry.for[key])) {
77     var symbol = %CreateSymbol(key);
78     registry.for[key] = symbol;
79     registry.keyFor[symbol] = key;
80   }
81   return registry.for[key];
82 }
83
84
85 function SymbolKeyFor(symbol) {
86   if (!IS_SYMBOL(symbol)) throw MakeTypeError(kSymbolKeyFor, symbol);
87   return %SymbolRegistry().keyFor[symbol];
88 }
89
90
91 // ES6 19.1.2.8
92 function ObjectGetOwnPropertySymbols(obj) {
93   obj = TO_OBJECT(obj);
94
95   // TODO(arv): Proxies use a shared trap for String and Symbol keys.
96
97   return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
98 }
99
100 //-------------------------------------------------------------------
101
102 %SetCode(GlobalSymbol, SymbolConstructor);
103 %FunctionSetPrototype(GlobalSymbol, new GlobalObject());
104
105 utils.InstallConstants(GlobalSymbol, [
106   // TODO(rossberg): expose when implemented.
107   // "hasInstance", symbolHasInstance,
108   // "isConcatSpreadable", symbolIsConcatSpreadable,
109   // "isRegExp", symbolIsRegExp,
110   "iterator", symbolIterator,
111   "toPrimitive", symbolToPrimitive,
112   // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
113   // Move here when shipping
114   // "toStringTag", symbolToStringTag,
115   "unscopables", symbolUnscopables
116 ]);
117
118 utils.InstallFunctions(GlobalSymbol, DONT_ENUM, [
119   "for", SymbolFor,
120   "keyFor", SymbolKeyFor
121 ]);
122
123 %AddNamedProperty(
124     GlobalSymbol.prototype, "constructor", GlobalSymbol, DONT_ENUM);
125 utils.SetFunctionName(SymbolToPrimitive, symbolToPrimitive);
126 %AddNamedProperty(
127     GlobalSymbol.prototype, symbolToPrimitive, SymbolToPrimitive,
128     DONT_ENUM | READ_ONLY);
129 %AddNamedProperty(
130     GlobalSymbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);
131
132 utils.InstallFunctions(GlobalSymbol.prototype, DONT_ENUM, [
133   "toString", SymbolToString,
134   "valueOf", SymbolValueOf
135 ]);
136
137 utils.InstallFunctions(GlobalObject, DONT_ENUM, [
138   "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
139 ]);
140
141 $symbolToString = SymbolToString;
142
143 })