michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* JS::PropertyKey implementation. */ michael@0: michael@0: #ifndef js_PropertyKey_h michael@0: #define js_PropertyKey_h michael@0: michael@0: #include "js/TypeDecls.h" michael@0: #include "js/Value.h" michael@0: michael@0: namespace JS { michael@0: michael@0: class PropertyKey; michael@0: michael@0: namespace detail { michael@0: michael@0: extern JS_PUBLIC_API(bool) michael@0: ToPropertyKeySlow(JSContext *cx, HandleValue v, PropertyKey *key); michael@0: michael@0: } // namespace detail michael@0: michael@0: /* michael@0: * A PropertyKey is a key used to access some property on an object. It is a michael@0: * natural way to represent a property accessed using a JavaScript value. michael@0: * michael@0: * PropertyKey can represent indexes, named properties, and ES6 symbols. The michael@0: * latter aren't implemented in SpiderMonkey yet, but PropertyKey carves out michael@0: * space for them. michael@0: */ michael@0: class PropertyKey michael@0: { michael@0: Value v; michael@0: friend JS_PUBLIC_API(bool) detail::ToPropertyKeySlow(JSContext *cx, HandleValue v, PropertyKey *key); michael@0: michael@0: public: michael@0: explicit PropertyKey(uint32_t index) : v(PrivateUint32Value(index)) {} michael@0: michael@0: /* michael@0: * An index is a string property name whose characters exactly spell out an michael@0: * unsigned 32-bit integer in decimal: "0", "1", "2", ...., "4294967294", michael@0: * "4294967295". michael@0: */ michael@0: bool isIndex(uint32_t *index) { michael@0: // The implementation here assumes that private uint32_t are stored michael@0: // using the int32_t representation. This is purely an implementation michael@0: // detail: embedders must not rely upon this! michael@0: if (!v.isInt32()) michael@0: return false; michael@0: *index = v.toPrivateUint32(); michael@0: return true; michael@0: } michael@0: michael@0: /* michael@0: * A name is a string property name which is *not* an index. Note that by michael@0: * the ECMAScript language grammar, any dotted property access |obj.prop| michael@0: * will access a named property. michael@0: */ michael@0: bool isName(JSString **str) { michael@0: uint32_t dummy; michael@0: if (isIndex(&dummy)) michael@0: return false; michael@0: *str = v.toString(); michael@0: return true; michael@0: } michael@0: michael@0: /* michael@0: * A symbol is a property name that's a Symbol, a particular kind of object michael@0: * in ES6. It is the only kind of property name that's not a string. michael@0: * michael@0: * SpiderMonkey doesn't yet implement symbols, but we're carving out API michael@0: * space for them in advance. michael@0: */ michael@0: bool isSymbol() { michael@0: return false; michael@0: } michael@0: }; michael@0: michael@0: inline bool michael@0: ToPropertyKey(JSContext *cx, HandleValue v, PropertyKey *key) michael@0: { michael@0: if (v.isInt32() && v.toInt32() >= 0) { michael@0: *key = PropertyKey(uint32_t(v.toInt32())); michael@0: return true; michael@0: } michael@0: michael@0: return detail::ToPropertyKeySlow(cx, v, key); michael@0: } michael@0: michael@0: } // namespace JS michael@0: michael@0: #endif /* js_PropertyKey_h */