symbol.js 3.13 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
// Expects following symbols to be set in the bootstrapper during genesis:
6 7 8 9 10 11 12
// - symbolHasInstance
// - symbolIsConcatSpreadable
// - symbolIsRegExp
// - symbolIterator
// - symbolToStringTag
// - symbolUnscopables

13 14
var $symbolToString;

15
(function(global, shared, exports) {
16 17 18 19 20 21 22

"use strict";

%CheckIsBootstrapping();

var GlobalObject = global.Object;
var GlobalSymbol = global.Symbol;
23

24 25
// -------------------------------------------------------------------

26
function SymbolConstructor(x) {
27
  if (%_IsConstructCall()) throw MakeTypeError(kNotConstructor, "Symbol");
28
  // NOTE: Passing in a Symbol value will throw on ToString().
29
  return %CreateSymbol(IS_UNDEFINED(x) ? x : $toString(x));
30 31
}

32 33 34

function SymbolToString() {
  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
35 36
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        "Symbol.prototype.toString", this);
37
  }
38 39
  var description = %SymbolDescription(%_ValueOf(this));
  return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")";
40 41
}

42 43

function SymbolValueOf() {
44
  if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) {
45 46
    throw MakeTypeError(kIncompatibleMethodReceiver,
                        "Symbol.prototype.valueOf", this);
47 48 49 50
  }
  return %_ValueOf(this);
}

51

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


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


70 71
// ES6 19.1.2.8
function ObjectGetOwnPropertySymbols(obj) {
72
  obj = $toObject(obj);
73 74 75

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

76
  return $objectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
77 78
}

79 80
//-------------------------------------------------------------------

81 82 83
%SetCode(GlobalSymbol, SymbolConstructor);
%FunctionSetPrototype(GlobalSymbol, new GlobalObject());

84
$installConstants(GlobalSymbol, [
85 86 87 88 89 90 91 92 93
  // TODO(rossberg): expose when implemented.
  // "hasInstance", symbolHasInstance,
  // "isConcatSpreadable", symbolIsConcatSpreadable,
  // "isRegExp", symbolIsRegExp,
  "iterator", symbolIterator,
  // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
  // Move here when shipping
  // "toStringTag", symbolToStringTag,
  "unscopables", symbolUnscopables
94
]);
95

96
$installFunctions(GlobalSymbol, DONT_ENUM, [
97 98
  "for", SymbolFor,
  "keyFor", SymbolKeyFor
99
]);
100 101 102 103 104 105

%AddNamedProperty(
    GlobalSymbol.prototype, "constructor", GlobalSymbol, DONT_ENUM);
%AddNamedProperty(
    GlobalSymbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);

106
$installFunctions(GlobalSymbol.prototype, DONT_ENUM, [
107 108
  "toString", SymbolToString,
  "valueOf", SymbolValueOf
109
]);
110

111
$installFunctions(GlobalObject, DONT_ENUM, [
112
  "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
113
]);
114 115 116

$symbolToString = SymbolToString;

117
})