symbol.js 3.25 KB
Newer Older
1
// Copyright 2013 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6

"use strict";

7 8 9 10
// This file relies on the fact that the following declaration has been made
// in runtime.js:
// var $Array = global.Array;

11 12 13 14 15 16 17 18
// And requires following symbols to be set in the bootstrapper during genesis:
// - symbolHasInstance
// - symbolIsConcatSpreadable
// - symbolIsRegExp
// - symbolIterator
// - symbolToStringTag
// - symbolUnscopables

19
var $Symbol = global.Symbol;
20

21 22
// -------------------------------------------------------------------

23 24
function SymbolConstructor(x) {
  if (%_IsConstructCall()) {
25
    throw MakeTypeError('not_constructor', ["Symbol"]);
26
  }
27 28
  // NOTE: Passing in a Symbol value will throw on ToString().
  return %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x));
29 30
}

31 32 33

function SymbolToString() {
  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
34
    throw MakeTypeError(
35
      'incompatible_method_receiver', ["Symbol.prototype.toString", this]);
36
  }
37 38
  var description = %SymbolDescription(%_ValueOf(this));
  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 48 49
  }
  return %_ValueOf(this);
}

50

51 52
function SymbolFor(key) {
  key = TO_STRING_INLINE(key);
53
  var registry = %SymbolRegistry();
54
  if (IS_UNDEFINED(registry.for[key])) {
55 56 57 58 59 60 61 62 63
    var symbol = %CreateSymbol(key);
    registry.for[key] = symbol;
    registry.keyFor[symbol] = key;
  }
  return registry.for[key];
}


function SymbolKeyFor(symbol) {
64 65
  if (!IS_SYMBOL(symbol)) throw MakeTypeError("not_a_symbol", [symbol]);
  return %SymbolRegistry().keyFor[symbol];
66 67 68
}


69 70
// ES6 19.1.2.8
function ObjectGetOwnPropertySymbols(obj) {
71
  obj = ToObject(obj);
72 73 74

  // TODO(arv): Proxies use a shared trap for String and Symbol keys.

75
  return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
76 77
}

78 79 80 81 82 83
//-------------------------------------------------------------------

function SetUpSymbol() {
  %CheckIsBootstrapping();

  %SetCode($Symbol, SymbolConstructor);
84
  %FunctionSetPrototype($Symbol, new $Object());
85

86
  InstallConstants($Symbol, $Array(
87 88 89 90
    // TODO(rossberg): expose when implemented.
    // "hasInstance", symbolHasInstance,
    // "isConcatSpreadable", symbolIsConcatSpreadable,
    // "isRegExp", symbolIsRegExp,
91
    "iterator", symbolIterator,
92 93
    // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
    // Move here when shipping
94
    // "toStringTag", symbolToStringTag,
95
    "unscopables", symbolUnscopables
96
  ));
97 98 99 100 101
  InstallFunctions($Symbol, DONT_ENUM, $Array(
    "for", SymbolFor,
    "keyFor", SymbolKeyFor
  ));

102
  %AddNamedProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
103 104
  %AddNamedProperty(
      $Symbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);
105 106 107 108 109 110 111
  InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
    "toString", SymbolToString,
    "valueOf", SymbolValueOf
  ));
}

SetUpSymbol();
112 113 114 115 116 117 118 119 120 121 122


function ExtendObject() {
  %CheckIsBootstrapping();

  InstallFunctions($Object, DONT_ENUM, $Array(
    "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
  ));
}

ExtendObject();