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 symbolCreate = InternalSymbol("Symbol.create"); 86var symbolHasInstance = InternalSymbol("Symbol.hasInstance"); 87var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable"); 88var symbolIsRegExp = InternalSymbol("Symbol.isRegExp"); 89var symbolIterator = InternalSymbol("Symbol.iterator"); 90var symbolToStringTag = InternalSymbol("Symbol.toStringTag"); 91var symbolUnscopables = InternalSymbol("Symbol.unscopables"); 92 93 94//------------------------------------------------------------------- 95 96function SetUpSymbol() { 97 %CheckIsBootstrapping(); 98 99 %SetCode($Symbol, SymbolConstructor); 100 %FunctionSetPrototype($Symbol, new $Object()); 101 102 InstallConstants($Symbol, $Array( 103 "create", symbolCreate, 104 "hasInstance", symbolHasInstance, 105 "isConcatSpreadable", symbolIsConcatSpreadable, 106 "isRegExp", symbolIsRegExp, 107 "iterator", symbolIterator, 108 "toStringTag", symbolToStringTag, 109 "unscopables", symbolUnscopables 110 )); 111 InstallFunctions($Symbol, DONT_ENUM, $Array( 112 "for", SymbolFor, 113 "keyFor", SymbolKeyFor 114 )); 115 116 %SetProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM); 117 InstallFunctions($Symbol.prototype, DONT_ENUM, $Array( 118 "toString", SymbolToString, 119 "valueOf", SymbolValueOf 120 )); 121} 122 123SetUpSymbol(); 124 125 126function ExtendObject() { 127 %CheckIsBootstrapping(); 128 129 InstallFunctions($Object, DONT_ENUM, $Array( 130 "getOwnPropertySymbols", ObjectGetOwnPropertySymbols 131 )); 132} 133 134ExtendObject(); 135