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