• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
11var $Symbol = global.Symbol;
12
13// -------------------------------------------------------------------
14
15function SymbolConstructor(x) {
16  if (%_IsConstructCall()) {
17    throw MakeTypeError('not_constructor', ["Symbol"]);
18  }
19  // NOTE: Passing in a Symbol value will throw on ToString().
20  return %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
21}
22
23
24function SymbolToString() {
25  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
26    throw MakeTypeError(
27      'incompatible_method_receiver', ["Symbol.prototype.toString", this]);
28  }
29  var description = %SymbolDescription(%_ValueOf(this));
30  return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")";
31}
32
33
34function SymbolValueOf() {
35  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
36    throw MakeTypeError(
37      'incompatible_method_receiver', ["Symbol.prototype.valueOf", this]);
38  }
39  return %_ValueOf(this);
40}
41
42
43function InternalSymbol(key) {
44  var internal_registry = %SymbolRegistry().for_intern;
45  if (IS_UNDEFINED(internal_registry[key])) {
46    internal_registry[key] = %CreateSymbol(key);
47  }
48  return internal_registry[key];
49}
50
51
52function SymbolFor(key) {
53  key = TO_STRING_INLINE(key);
54  var registry = %SymbolRegistry();
55  if (IS_UNDEFINED(registry.for[key])) {
56    var symbol = %CreateSymbol(key);
57    registry.for[key] = symbol;
58    registry.keyFor[symbol] = key;
59  }
60  return registry.for[key];
61}
62
63
64function SymbolKeyFor(symbol) {
65  if (!IS_SYMBOL(symbol)) throw MakeTypeError("not_a_symbol", [symbol]);
66  return %SymbolRegistry().keyFor[symbol];
67}
68
69
70// ES6 19.1.2.8
71function ObjectGetOwnPropertySymbols(obj) {
72  if (!IS_SPEC_OBJECT(obj)) {
73    throw MakeTypeError("called_on_non_object",
74                        ["Object.getOwnPropertySymbols"]);
75  }
76
77  // TODO(arv): Proxies use a shared trap for String and Symbol keys.
78
79  return ObjectGetOwnPropertyKeys(obj, true);
80}
81
82
83//-------------------------------------------------------------------
84
85var symbolCreate = InternalSymbol("Symbol.create");
86var symbolHasInstance = InternalSymbol("Symbol.hasInstance");
87var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable");
88var symbolIsRegExp = InternalSymbol("Symbol.isRegExp");
89var symbolIterator = InternalSymbol("Symbol.iterator");
90var symbolToStringTag = InternalSymbol("Symbol.toStringTag");
91var symbolUnscopables = InternalSymbol("Symbol.unscopables");
92
93
94//-------------------------------------------------------------------
95
96function SetUpSymbol() {
97  %CheckIsBootstrapping();
98
99  %SetCode($Symbol, SymbolConstructor);
100  %FunctionSetPrototype($Symbol, new $Object());
101
102  InstallConstants($Symbol, $Array(
103    "create", symbolCreate,
104    "hasInstance", symbolHasInstance,
105    "isConcatSpreadable", symbolIsConcatSpreadable,
106    "isRegExp", symbolIsRegExp,
107    "iterator", symbolIterator,
108    "toStringTag", symbolToStringTag,
109    "unscopables", symbolUnscopables
110  ));
111  InstallFunctions($Symbol, DONT_ENUM, $Array(
112    "for", SymbolFor,
113    "keyFor", SymbolKeyFor
114  ));
115
116  %SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
117  InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
118    "toString", SymbolToString,
119    "valueOf", SymbolValueOf
120  ));
121}
122
123SetUpSymbol();
124
125
126function ExtendObject() {
127  %CheckIsBootstrapping();
128
129  InstallFunctions($Object, DONT_ENUM, $Array(
130    "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
131  ));
132}
133
134ExtendObject();
135