blob: d9cf79265f33320a500a04cd5532440cb53bc929 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Emily Bernierd0a1eb72015-03-24 16:35:39 -040011// 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019var $Symbol = global.Symbol;
20
21// -------------------------------------------------------------------
22
23function 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
32function 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
42function 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
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051function 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
63function 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
70function ObjectGetOwnPropertySymbols(obj) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040071 obj = ToObject(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072
73 // TODO(arv): Proxies use a shared trap for String and Symbol keys.
74
Emily Bernierd0a1eb72015-03-24 16:35:39 -040075 return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076}
77
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078//-------------------------------------------------------------------
79
80function 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,
Emily Bernierd0a1eb72015-03-24 16:35:39 -040092 // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
93 // Move here when shipping
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094 // "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);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 %AddNamedProperty(
104 $Symbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105 InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
106 "toString", SymbolToString,
107 "valueOf", SymbolValueOf
108 ));
109}
110
111SetUpSymbol();
112
113
114function ExtendObject() {
115 %CheckIsBootstrapping();
116
117 InstallFunctions($Object, DONT_ENUM, $Array(
118 "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
119 ));
120}
121
122ExtendObject();