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