js/public/Id.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/public/Id.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,185 @@
     1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99:
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#ifndef js_Id_h
    1.11 +#define js_Id_h
    1.12 +
    1.13 +// A jsid is an identifier for a property or method of an object which is
    1.14 +// either a 31-bit signed integer, interned string or object.
    1.15 +//
    1.16 +// Also, there is an additional jsid value, JSID_VOID, which does not occur in
    1.17 +// JS scripts but may be used to indicate the absence of a valid jsid.  A void
    1.18 +// jsid is not a valid id and only arises as an exceptional API return value,
    1.19 +// such as in JS_NextProperty. Embeddings must not pass JSID_VOID into JSAPI
    1.20 +// entry points expecting a jsid and do not need to handle JSID_VOID in hooks
    1.21 +// receiving a jsid except when explicitly noted in the API contract.
    1.22 +//
    1.23 +// A jsid is not implicitly convertible to or from a jsval; JS_ValueToId or
    1.24 +// JS_IdToValue must be used instead.
    1.25 +
    1.26 +#include "mozilla/NullPtr.h"
    1.27 +
    1.28 +#include "jstypes.h"
    1.29 +
    1.30 +#include "js/HeapAPI.h"
    1.31 +#include "js/RootingAPI.h"
    1.32 +#include "js/TypeDecls.h"
    1.33 +#include "js/Utility.h"
    1.34 +
    1.35 +struct jsid
    1.36 +{
    1.37 +    size_t asBits;
    1.38 +    bool operator==(jsid rhs) const { return asBits == rhs.asBits; }
    1.39 +    bool operator!=(jsid rhs) const { return asBits != rhs.asBits; }
    1.40 +};
    1.41 +#define JSID_BITS(id) (id.asBits)
    1.42 +
    1.43 +#define JSID_TYPE_STRING                 0x0
    1.44 +#define JSID_TYPE_INT                    0x1
    1.45 +#define JSID_TYPE_VOID                   0x2
    1.46 +#define JSID_TYPE_OBJECT                 0x4
    1.47 +#define JSID_TYPE_MASK                   0x7
    1.48 +
    1.49 +// Avoid using canonical 'id' for jsid parameters since this is a magic word in
    1.50 +// Objective-C++ which, apparently, wants to be able to #include jsapi.h.
    1.51 +#define id iden
    1.52 +
    1.53 +static MOZ_ALWAYS_INLINE bool
    1.54 +JSID_IS_STRING(jsid id)
    1.55 +{
    1.56 +    return (JSID_BITS(id) & JSID_TYPE_MASK) == 0;
    1.57 +}
    1.58 +
    1.59 +static MOZ_ALWAYS_INLINE JSString *
    1.60 +JSID_TO_STRING(jsid id)
    1.61 +{
    1.62 +    MOZ_ASSERT(JSID_IS_STRING(id));
    1.63 +    return (JSString *)JSID_BITS(id);
    1.64 +}
    1.65 +
    1.66 +static MOZ_ALWAYS_INLINE bool
    1.67 +JSID_IS_ZERO(jsid id)
    1.68 +{
    1.69 +    return JSID_BITS(id) == 0;
    1.70 +}
    1.71 +
    1.72 +static MOZ_ALWAYS_INLINE bool
    1.73 +JSID_IS_INT(jsid id)
    1.74 +{
    1.75 +    return !!(JSID_BITS(id) & JSID_TYPE_INT);
    1.76 +}
    1.77 +
    1.78 +static MOZ_ALWAYS_INLINE int32_t
    1.79 +JSID_TO_INT(jsid id)
    1.80 +{
    1.81 +    MOZ_ASSERT(JSID_IS_INT(id));
    1.82 +    return ((uint32_t)JSID_BITS(id)) >> 1;
    1.83 +}
    1.84 +
    1.85 +#define JSID_INT_MIN  0
    1.86 +#define JSID_INT_MAX  INT32_MAX
    1.87 +
    1.88 +static MOZ_ALWAYS_INLINE bool
    1.89 +INT_FITS_IN_JSID(int32_t i)
    1.90 +{
    1.91 +    return i >= 0;
    1.92 +}
    1.93 +
    1.94 +static MOZ_ALWAYS_INLINE jsid
    1.95 +INT_TO_JSID(int32_t i)
    1.96 +{
    1.97 +    jsid id;
    1.98 +    MOZ_ASSERT(INT_FITS_IN_JSID(i));
    1.99 +    JSID_BITS(id) = ((i << 1) | JSID_TYPE_INT);
   1.100 +    return id;
   1.101 +}
   1.102 +
   1.103 +static MOZ_ALWAYS_INLINE bool
   1.104 +JSID_IS_OBJECT(jsid id)
   1.105 +{
   1.106 +    return (JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_OBJECT &&
   1.107 +           (size_t)JSID_BITS(id) != JSID_TYPE_OBJECT;
   1.108 +}
   1.109 +
   1.110 +static MOZ_ALWAYS_INLINE JSObject *
   1.111 +JSID_TO_OBJECT(jsid id)
   1.112 +{
   1.113 +    MOZ_ASSERT(JSID_IS_OBJECT(id));
   1.114 +    return (JSObject *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK);
   1.115 +}
   1.116 +
   1.117 +static MOZ_ALWAYS_INLINE jsid
   1.118 +OBJECT_TO_JSID(JSObject *obj)
   1.119 +{
   1.120 +    jsid id;
   1.121 +    MOZ_ASSERT(obj != nullptr);
   1.122 +    MOZ_ASSERT(((size_t)obj & JSID_TYPE_MASK) == 0);
   1.123 +    JS_ASSERT(!js::gc::IsInsideNursery(js::gc::GetGCThingRuntime(obj), obj));
   1.124 +    JSID_BITS(id) = ((size_t)obj | JSID_TYPE_OBJECT);
   1.125 +    return id;
   1.126 +}
   1.127 +
   1.128 +static MOZ_ALWAYS_INLINE bool
   1.129 +JSID_IS_GCTHING(jsid id)
   1.130 +{
   1.131 +    return JSID_IS_STRING(id) || JSID_IS_OBJECT(id);
   1.132 +}
   1.133 +
   1.134 +static MOZ_ALWAYS_INLINE void *
   1.135 +JSID_TO_GCTHING(jsid id)
   1.136 +{
   1.137 +    return (void *)(JSID_BITS(id) & ~(size_t)JSID_TYPE_MASK);
   1.138 +}
   1.139 +
   1.140 +static MOZ_ALWAYS_INLINE bool
   1.141 +JSID_IS_VOID(const jsid id)
   1.142 +{
   1.143 +    MOZ_ASSERT_IF(((size_t)JSID_BITS(id) & JSID_TYPE_MASK) == JSID_TYPE_VOID,
   1.144 +                 JSID_BITS(id) == JSID_TYPE_VOID);
   1.145 +    return ((size_t)JSID_BITS(id) == JSID_TYPE_VOID);
   1.146 +}
   1.147 +
   1.148 +static MOZ_ALWAYS_INLINE bool
   1.149 +JSID_IS_EMPTY(const jsid id)
   1.150 +{
   1.151 +    return ((size_t)JSID_BITS(id) == JSID_TYPE_OBJECT);
   1.152 +}
   1.153 +
   1.154 +#undef id
   1.155 +
   1.156 +extern JS_PUBLIC_DATA(const jsid) JSID_VOID;
   1.157 +extern JS_PUBLIC_DATA(const jsid) JSID_EMPTY;
   1.158 +
   1.159 +extern JS_PUBLIC_DATA(const JS::HandleId) JSID_VOIDHANDLE;
   1.160 +extern JS_PUBLIC_DATA(const JS::HandleId) JSID_EMPTYHANDLE;
   1.161 +
   1.162 +namespace js {
   1.163 +
   1.164 +inline bool
   1.165 +IsPoisonedId(jsid iden)
   1.166 +{
   1.167 +    if (JSID_IS_STRING(iden))
   1.168 +        return JS::IsPoisonedPtr(JSID_TO_STRING(iden));
   1.169 +    if (JSID_IS_OBJECT(iden))
   1.170 +        return JS::IsPoisonedPtr(JSID_TO_OBJECT(iden));
   1.171 +    return false;
   1.172 +}
   1.173 +
   1.174 +template <> struct GCMethods<jsid>
   1.175 +{
   1.176 +    static jsid initial() { return JSID_VOID; }
   1.177 +    static ThingRootKind kind() { return THING_ROOT_ID; }
   1.178 +    static bool poisoned(jsid id) { return IsPoisonedId(id); }
   1.179 +    static bool needsPostBarrier(jsid id) { return false; }
   1.180 +#ifdef JSGC_GENERATIONAL
   1.181 +    static void postBarrier(jsid *idp) {}
   1.182 +    static void relocate(jsid *idp) {}
   1.183 +#endif
   1.184 +};
   1.185 +
   1.186 +}
   1.187 +
   1.188 +#endif /* js_Id_h */

mercurial