Home | History | Annotate | Download | only in src
      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 
     11 var $Symbol = global.Symbol;
     12 
     13 // -------------------------------------------------------------------
     14 
     15 function 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 
     24 function 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 
     34 function 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 
     43 function 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 
     52 function 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 
     64 function 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
     71 function 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 
     85 var symbolHasInstance = InternalSymbol("Symbol.hasInstance");
     86 var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable");
     87 var symbolIsRegExp = InternalSymbol("Symbol.isRegExp");
     88 var symbolIterator = InternalSymbol("Symbol.iterator");
     89 var symbolToStringTag = InternalSymbol("Symbol.toStringTag");
     90 var symbolUnscopables = InternalSymbol("Symbol.unscopables");
     91 
     92 
     93 //-------------------------------------------------------------------
     94 
     95 function SetUpSymbol() {
     96   %CheckIsBootstrapping();
     97 
     98   %SetCode($Symbol, SymbolConstructor);
     99   %FunctionSetPrototype($Symbol, new $Object());
    100 
    101   InstallConstants($Symbol, $Array(
    102     // TODO(rossberg): expose when implemented.
    103     // "hasInstance", symbolHasInstance,
    104     // "isConcatSpreadable", symbolIsConcatSpreadable,
    105     // "isRegExp", symbolIsRegExp,
    106     "iterator", symbolIterator,
    107     // "toStringTag", symbolToStringTag,
    108     "unscopables", symbolUnscopables
    109   ));
    110   InstallFunctions($Symbol, DONT_ENUM, $Array(
    111     "for", SymbolFor,
    112     "keyFor", SymbolKeyFor
    113   ));
    114 
    115   %AddNamedProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
    116   InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
    117     "toString", SymbolToString,
    118     "valueOf", SymbolValueOf
    119   ));
    120 }
    121 
    122 SetUpSymbol();
    123 
    124 
    125 function ExtendObject() {
    126   %CheckIsBootstrapping();
    127 
    128   InstallFunctions($Object, DONT_ENUM, $Array(
    129     "getOwnPropertySymbols", ObjectGetOwnPropertySymbols
    130   ));
    131 }
    132 
    133 ExtendObject();
    134