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 symbolHasInstance = InternalSymbol("Symbol.hasInstance"); 86var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable"); 87var symbolIsRegExp = InternalSymbol("Symbol.isRegExp"); 88var symbolIterator = InternalSymbol("Symbol.iterator"); 89var symbolToStringTag = InternalSymbol("Symbol.toStringTag"); 90var symbolUnscopables = InternalSymbol("Symbol.unscopables"); 91 92 93//------------------------------------------------------------------- 94 95function 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 122SetUpSymbol(); 123 124 125function ExtendObject() { 126 %CheckIsBootstrapping(); 127 128 InstallFunctions($Object, DONT_ENUM, $Array( 129 "getOwnPropertySymbols", ObjectGetOwnPropertySymbols 130 )); 131} 132 133ExtendObject(); 134