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