// Copyright 2013 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. "use strict"; // This file relies on the fact that the following declaration has been made // in runtime.js: // var $Array = global.Array; var $Symbol = global.Symbol; // ------------------------------------------------------------------- function SymbolConstructor(x) { if (%_IsConstructCall()) { throw MakeTypeError('not_constructor', ["Symbol"]); } // NOTE: Passing in a Symbol value will throw on ToString(). return %CreateSymbol(IS_UNDEFINED(x) ? x : ToString(x)); } function SymbolToString() { if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) { throw MakeTypeError( 'incompatible_method_receiver', ["Symbol.prototype.toString", this]); } var description = %SymbolDescription(%_ValueOf(this)); return "Symbol(" + (IS_UNDEFINED(description) ? "" : description) + ")"; } function SymbolValueOf() { if (!(IS_SYMBOL(this) || IS_SYMBOL_WRAPPER(this))) { throw MakeTypeError( 'incompatible_method_receiver', ["Symbol.prototype.valueOf", this]); } return %_ValueOf(this); } function InternalSymbol(key) { var internal_registry = %SymbolRegistry().for_intern; if (IS_UNDEFINED(internal_registry[key])) { internal_registry[key] = %CreateSymbol(key); } return internal_registry[key]; } function SymbolFor(key) { key = TO_STRING_INLINE(key); var registry = %SymbolRegistry(); if (IS_UNDEFINED(registry.for[key])) { var symbol = %CreateSymbol(key); registry.for[key] = symbol; registry.keyFor[symbol] = key; } return registry.for[key]; } function SymbolKeyFor(symbol) { if (!IS_SYMBOL(symbol)) throw MakeTypeError("not_a_symbol", [symbol]); return %SymbolRegistry().keyFor[symbol]; } // ES6 19.1.2.8 function ObjectGetOwnPropertySymbols(obj) { if (!IS_SPEC_OBJECT(obj)) { throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertySymbols"]); } // TODO(arv): Proxies use a shared trap for String and Symbol keys. return ObjectGetOwnPropertyKeys(obj, true); } //------------------------------------------------------------------- var symbolHasInstance = InternalSymbol("Symbol.hasInstance"); var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable"); var symbolIsRegExp = InternalSymbol("Symbol.isRegExp"); var symbolIterator = InternalSymbol("Symbol.iterator"); var symbolToStringTag = InternalSymbol("Symbol.toStringTag"); var symbolUnscopables = InternalSymbol("Symbol.unscopables"); //------------------------------------------------------------------- function SetUpSymbol() { %CheckIsBootstrapping(); %SetCode($Symbol, SymbolConstructor); %FunctionSetPrototype($Symbol, new $Object()); InstallConstants($Symbol, $Array( // TODO(rossberg): expose when implemented. // "hasInstance", symbolHasInstance, // "isConcatSpreadable", symbolIsConcatSpreadable, // "isRegExp", symbolIsRegExp, "iterator", symbolIterator, // "toStringTag", symbolToStringTag, "unscopables", symbolUnscopables )); InstallFunctions($Symbol, DONT_ENUM, $Array( "for", SymbolFor, "keyFor", SymbolKeyFor )); %AddNamedProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM); InstallFunctions($Symbol.prototype, DONT_ENUM, $Array( "toString", SymbolToString, "valueOf", SymbolValueOf )); } SetUpSymbol(); function ExtendObject() { %CheckIsBootstrapping(); InstallFunctions($Object, DONT_ENUM, $Array( "getOwnPropertySymbols", ObjectGetOwnPropertySymbols )); } ExtendObject();