8cac2c56a2f69cfa8397c6c13bb0d07ef9f33f1f
[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 // - symbolToStringTag
11 // - symbolUnscopables
12
13 var $symbolToString;
14
15 (function(global, utils) {
16
17 "use strict";
18
19 %CheckIsBootstrapping();
20
21 // -------------------------------------------------------------------
22 // Imports
23
24 var GlobalObject = global.Object;
25 var GlobalSymbol = global.Symbol;
26 var ObjectGetOwnPropertyKeys;
27 var ToString;
28
29 utils.Import(function(from) {
30   ObjectGetOwnPropertyKeys = from.ObjectGetOwnPropertyKeys;
31   ToString = from.ToString;
32 });
33
34 // -------------------------------------------------------------------
35
36 function SymbolConstructor(x) {
37   if (%_IsConstructCall()) throw MakeTypeError(kNotConstructor, "Symbol");
38   // NOTE: Passing in a Symbol value will throw on ToString().
39   return %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
40 }
41
42
43 function SymbolToString() {
44   if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
45     throw MakeTypeError(kIncompatibleMethodReceiver,
46                         "Symbol.prototype.toString", this);
47   }
48   var description = %SymbolDescription(%_ValueOf(this));
49   return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")";
50 }
51
52
53 function SymbolValueOf() {
54   if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
55     throw MakeTypeError(kIncompatibleMethodReceiver,
56                         "Symbol.prototype.valueOf", this);
57   }
58   return %_ValueOf(this);
59 }
60
61
62 function SymbolFor(key) {
63   key = TO_STRING_INLINE(key);
64   var registry = %SymbolRegistry();
65   if (IS_UNDEFINED(registry.for[key])) {
66     var symbol = %CreateSymbol(key);
67     registry.for[key] = symbol;
68     registry.keyFor[symbol] = key;
69   }
70   return registry.for[key];
71 }
72
73
74 function SymbolKeyFor(symbol) {
75   if (!IS_SYMBOL(symbol)) throw MakeTypeError(kSymbolKeyFor, symbol);
76   return %SymbolRegistry().keyFor[symbol];
77 }
78
79
80 // ES6 19.1.2.8
81 function ObjectGetOwnPropertySymbols(obj) {
82   obj = TO_OBJECT(obj);
83
84   // TODO(arv): Proxies use a shared trap for String and Symbol keys.
85
86   return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
87 }
88
89 //-------------------------------------------------------------------
90
91 %SetCode(GlobalSymbol, SymbolConstructor);
92 %FunctionSetPrototype(GlobalSymbol, new GlobalObject());
93
94 utils.InstallConstants(GlobalSymbol, [
95   // TODO(rossberg): expose when implemented.
96   // "hasInstance", symbolHasInstance,
97   // "isConcatSpreadable", symbolIsConcatSpreadable,
98   // "isRegExp", symbolIsRegExp,
99   "iterator", symbolIterator,
100   // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
101   // Move here when shipping
102   // "toStringTag", symbolToStringTag,
103   "unscopables", symbolUnscopables
104 ]);
105
106 utils.InstallFunctions(GlobalSymbol, DONT_ENUM, [
107   "for", SymbolFor,
108   "keyFor", SymbolKeyFor
109 ]);
110
111 %AddNamedProperty(
112     GlobalSymbol.prototype, "constructor", GlobalSymbol, DONT_ENUM);
113 %AddNamedProperty(
114     GlobalSymbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);
115
116 utils.InstallFunctions(GlobalSymbol.prototype, DONT_ENUM, [
117   "toString", SymbolToString,
118   "valueOf", SymbolValueOf
119 ]);
120
121 utils.InstallFunctions(GlobalObject, DONT_ENUM, [
122   "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
123 ]);
124
125 $symbolToString = SymbolToString;
126
127 })