js/public/Class.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/js/public/Class.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,542 @@
     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 +/* JSClass definition and its component types, plus related interfaces. */
    1.11 +
    1.12 +#ifndef js_Class_h
    1.13 +#define js_Class_h
    1.14 +
    1.15 +#include "mozilla/NullPtr.h"
    1.16 + 
    1.17 +#include "jstypes.h"
    1.18 +
    1.19 +#include "js/CallArgs.h"
    1.20 +#include "js/Id.h"
    1.21 +#include "js/TypeDecls.h"
    1.22 +
    1.23 +/*
    1.24 + * A JSClass acts as a vtable for JS objects that allows JSAPI clients to
    1.25 + * control various aspects of the behavior of an object like property lookup.
    1.26 + * js::Class is an engine-private extension that allows more control over
    1.27 + * object behavior and, e.g., allows custom slow layout.
    1.28 + */
    1.29 +
    1.30 +class JSFreeOp;
    1.31 +struct JSFunctionSpec;
    1.32 +
    1.33 +namespace js {
    1.34 +
    1.35 +class Class;
    1.36 +class FreeOp;
    1.37 +class PropertyName;
    1.38 +class Shape;
    1.39 +
    1.40 +// This is equal to JSFunction::class_.  Use it in places where you don't want
    1.41 +// to #include jsfun.h.
    1.42 +extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr;
    1.43 +
    1.44 +} // namespace js
    1.45 +
    1.46 +// JSClass operation signatures.
    1.47 +
    1.48 +// Add or get a property named by id in obj.  Note the jsid id type -- id may
    1.49 +// be a string (Unicode property identifier) or an int (element index).  The
    1.50 +// *vp out parameter, on success, is the new property value after the action.
    1.51 +typedef bool
    1.52 +(* JSPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    1.53 +                 JS::MutableHandleValue vp);
    1.54 +
    1.55 +// Set a property named by id in obj, treating the assignment as strict
    1.56 +// mode code if strict is true. Note the jsid id type -- id may be a string
    1.57 +// (Unicode property identifier) or an int (element index). The *vp out
    1.58 +// parameter, on success, is the new property value after the
    1.59 +// set.
    1.60 +typedef bool
    1.61 +(* JSStrictPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    1.62 +                       bool strict, JS::MutableHandleValue vp);
    1.63 +
    1.64 +// Delete a property named by id in obj.
    1.65 +//
    1.66 +// If an error occurred, return false as per normal JSAPI error practice.
    1.67 +//
    1.68 +// If no error occurred, but the deletion attempt wasn't allowed (perhaps
    1.69 +// because the property was non-configurable), set *succeeded to false and
    1.70 +// return true.  This will cause |delete obj[id]| to evaluate to false in
    1.71 +// non-strict mode code, and to throw a TypeError in strict mode code.
    1.72 +//
    1.73 +// If no error occurred and the deletion wasn't disallowed (this is *not* the
    1.74 +// same as saying that a deletion actually occurred -- deleting a non-existent
    1.75 +// property, or an inherited property, is allowed -- it's just pointless),
    1.76 +// set *succeeded to true and return true.
    1.77 +typedef bool
    1.78 +(* JSDeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    1.79 +                       bool *succeeded);
    1.80 +
    1.81 +// This function type is used for callbacks that enumerate the properties of
    1.82 +// a JSObject.  The behavior depends on the value of enum_op:
    1.83 +//
    1.84 +//  JSENUMERATE_INIT
    1.85 +//    A new, opaque iterator state should be allocated and stored in *statep.
    1.86 +//    (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored).
    1.87 +//
    1.88 +//    The number of properties that will be enumerated should be returned as
    1.89 +//    an integer jsval in *idp, if idp is non-null, and provided the number of
    1.90 +//    enumerable properties is known.  If idp is non-null and the number of
    1.91 +//    enumerable properties can't be computed in advance, *idp should be set
    1.92 +//    to JSVAL_ZERO.
    1.93 +//
    1.94 +//  JSENUMERATE_INIT_ALL
    1.95 +//    Used identically to JSENUMERATE_INIT, but exposes all properties of the
    1.96 +//    object regardless of enumerability.
    1.97 +//
    1.98 +//  JSENUMERATE_NEXT
    1.99 +//    A previously allocated opaque iterator state is passed in via statep.
   1.100 +//    Return the next jsid in the iteration using *idp.  The opaque iterator
   1.101 +//    state pointed at by statep is destroyed and *statep is set to JSVAL_NULL
   1.102 +//    if there are no properties left to enumerate.
   1.103 +//
   1.104 +//  JSENUMERATE_DESTROY
   1.105 +//    Destroy the opaque iterator state previously allocated in *statep by a
   1.106 +//    call to this function when enum_op was JSENUMERATE_INIT or
   1.107 +//    JSENUMERATE_INIT_ALL.
   1.108 +//
   1.109 +// The return value is used to indicate success, with a value of false
   1.110 +// indicating failure.
   1.111 +typedef bool
   1.112 +(* JSNewEnumerateOp)(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op,
   1.113 +                     JS::MutableHandleValue statep, JS::MutableHandleId idp);
   1.114 +
   1.115 +// The old-style JSClass.enumerate op should define all lazy properties not
   1.116 +// yet reflected in obj.
   1.117 +typedef bool
   1.118 +(* JSEnumerateOp)(JSContext *cx, JS::HandleObject obj);
   1.119 +
   1.120 +// Resolve a lazy property named by id in obj by defining it directly in obj.
   1.121 +// Lazy properties are those reflected from some peer native property space
   1.122 +// (e.g., the DOM attributes for a given node reflected as obj) on demand.
   1.123 +//
   1.124 +// JS looks for a property in an object, and if not found, tries to resolve
   1.125 +// the given id.  If resolve succeeds, the engine looks again in case resolve
   1.126 +// defined obj[id].  If no such property exists directly in obj, the process
   1.127 +// is repeated with obj's prototype, etc.
   1.128 +//
   1.129 +// NB: JSNewResolveOp provides a cheaper way to resolve lazy properties.
   1.130 +typedef bool
   1.131 +(* JSResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
   1.132 +
   1.133 +// Like JSResolveOp, except the *objp out parameter, on success, should be null
   1.134 +// to indicate that id was not resolved; and non-null, referring to obj or one
   1.135 +// of its prototypes, if id was resolved.  The hook may assume *objp is null on
   1.136 +// entry.
   1.137 +//
   1.138 +// This hook instead of JSResolveOp is called via the JSClass.resolve member
   1.139 +// if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
   1.140 +typedef bool
   1.141 +(* JSNewResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   1.142 +                   JS::MutableHandleObject objp);
   1.143 +
   1.144 +// Convert obj to the given type, returning true with the resulting value in
   1.145 +// *vp on success, and returning false on error or exception.
   1.146 +typedef bool
   1.147 +(* JSConvertOp)(JSContext *cx, JS::HandleObject obj, JSType type,
   1.148 +                JS::MutableHandleValue vp);
   1.149 +
   1.150 +// Finalize obj, which the garbage collector has determined to be unreachable
   1.151 +// from other live objects or from GC roots.  Obviously, finalizers must never
   1.152 +// store a reference to obj.
   1.153 +typedef void
   1.154 +(* JSFinalizeOp)(JSFreeOp *fop, JSObject *obj);
   1.155 +
   1.156 +// Finalizes external strings created by JS_NewExternalString.
   1.157 +struct JSStringFinalizer {
   1.158 +    void (*finalize)(const JSStringFinalizer *fin, jschar *chars);
   1.159 +};
   1.160 +
   1.161 +// Check whether v is an instance of obj.  Return false on error or exception,
   1.162 +// true on success with true in *bp if v is an instance of obj, false in
   1.163 +// *bp otherwise.
   1.164 +typedef bool
   1.165 +(* JSHasInstanceOp)(JSContext *cx, JS::HandleObject obj, JS::MutableHandleValue vp,
   1.166 +                    bool *bp);
   1.167 +
   1.168 +// Function type for trace operation of the class called to enumerate all
   1.169 +// traceable things reachable from obj's private data structure. For each such
   1.170 +// thing, a trace implementation must call one of the JS_Call*Tracer variants
   1.171 +// on the thing.
   1.172 +//
   1.173 +// JSTraceOp implementation can assume that no other threads mutates object
   1.174 +// state. It must not change state of the object or corresponding native
   1.175 +// structures. The only exception for this rule is the case when the embedding
   1.176 +// needs a tight integration with GC. In that case the embedding can check if
   1.177 +// the traversal is a part of the marking phase through calling
   1.178 +// JS_IsGCMarkingTracer and apply a special code like emptying caches or
   1.179 +// marking its native structures.
   1.180 +typedef void
   1.181 +(* JSTraceOp)(JSTracer *trc, JSObject *obj);
   1.182 +
   1.183 +// A generic type for functions mapping an object to another object, or null
   1.184 +// if an error or exception was thrown on cx.
   1.185 +typedef JSObject *
   1.186 +(* JSObjectOp)(JSContext *cx, JS::HandleObject obj);
   1.187 +
   1.188 +// Hook that creates an iterator object for a given object. Returns the
   1.189 +// iterator object or null if an error or exception was thrown on cx.
   1.190 +typedef JSObject *
   1.191 +(* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, bool keysonly);
   1.192 +
   1.193 +typedef JSObject *
   1.194 +(* JSWeakmapKeyDelegateOp)(JSObject *obj);
   1.195 +
   1.196 +/* js::Class operation signatures. */
   1.197 +
   1.198 +namespace js {
   1.199 +
   1.200 +typedef bool
   1.201 +(* LookupGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   1.202 +                    JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   1.203 +typedef bool
   1.204 +(* LookupPropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   1.205 +                 JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   1.206 +typedef bool
   1.207 +(* LookupElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index,
   1.208 +                    JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   1.209 +typedef bool
   1.210 +(* DefineGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
   1.211 +                    JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   1.212 +typedef bool
   1.213 +(* DefinePropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   1.214 +                 JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter,
   1.215 +                 unsigned attrs);
   1.216 +typedef bool
   1.217 +(* DefineElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
   1.218 +                    JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   1.219 +typedef bool
   1.220 +(* GenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
   1.221 +                JS::MutableHandleValue vp);
   1.222 +typedef bool
   1.223 +(* PropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
   1.224 +                 JS::Handle<PropertyName*> name, JS::MutableHandleValue vp);
   1.225 +typedef bool
   1.226 +(* ElementIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index,
   1.227 +                JS::MutableHandleValue vp);
   1.228 +typedef bool
   1.229 +(* StrictGenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   1.230 +                      JS::MutableHandleValue vp, bool strict);
   1.231 +typedef bool
   1.232 +(* StrictPropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   1.233 +                       JS::MutableHandleValue vp, bool strict);
   1.234 +typedef bool
   1.235 +(* StrictElementIdOp)(JSContext *cx, JS::HandleObject obj, uint32_t index,
   1.236 +                      JS::MutableHandleValue vp, bool strict);
   1.237 +typedef bool
   1.238 +(* GenericAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
   1.239 +typedef bool
   1.240 +(* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   1.241 +                         unsigned *attrsp);
   1.242 +typedef bool
   1.243 +(* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   1.244 +                     bool *succeeded);
   1.245 +typedef bool
   1.246 +(* DeleteElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
   1.247 +
   1.248 +typedef bool
   1.249 +(* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
   1.250 +
   1.251 +typedef bool
   1.252 +(* UnwatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
   1.253 +
   1.254 +typedef bool
   1.255 +(* SliceOp)(JSContext *cx, JS::HandleObject obj, uint32_t begin, uint32_t end,
   1.256 +            JS::HandleObject result); // result is actually preallocted.
   1.257 +
   1.258 +typedef JSObject *
   1.259 +(* ObjectOp)(JSContext *cx, JS::HandleObject obj);
   1.260 +typedef void
   1.261 +(* FinalizeOp)(FreeOp *fop, JSObject *obj);
   1.262 +
   1.263 +#define JS_CLASS_MEMBERS(FinalizeOpType)                                      \
   1.264 +    const char          *name;                                                \
   1.265 +    uint32_t            flags;                                                \
   1.266 +                                                                              \
   1.267 +    /* Mandatory function pointer members. */                                 \
   1.268 +    JSPropertyOp        addProperty;                                          \
   1.269 +    JSDeletePropertyOp  delProperty;                                          \
   1.270 +    JSPropertyOp        getProperty;                                          \
   1.271 +    JSStrictPropertyOp  setProperty;                                          \
   1.272 +    JSEnumerateOp       enumerate;                                            \
   1.273 +    JSResolveOp         resolve;                                              \
   1.274 +    JSConvertOp         convert;                                              \
   1.275 +                                                                              \
   1.276 +    /* Optional members (may be null). */                                     \
   1.277 +    FinalizeOpType      finalize;                                             \
   1.278 +    JSNative            call;                                                 \
   1.279 +    JSHasInstanceOp     hasInstance;                                          \
   1.280 +    JSNative            construct;                                            \
   1.281 +    JSTraceOp           trace
   1.282 +
   1.283 +// Callback for the creation of constructor and prototype objects.
   1.284 +typedef JSObject *(*ClassObjectCreationOp)(JSContext *cx, JSProtoKey key);
   1.285 +
   1.286 +// Callback for custom post-processing after class initialization via ClassSpec.
   1.287 +typedef bool (*FinishClassInitOp)(JSContext *cx, JS::HandleObject ctor,
   1.288 +                                  JS::HandleObject proto);
   1.289 +
   1.290 +struct ClassSpec
   1.291 +{
   1.292 +    ClassObjectCreationOp createConstructor;
   1.293 +    ClassObjectCreationOp createPrototype;
   1.294 +    const JSFunctionSpec *constructorFunctions;
   1.295 +    const JSFunctionSpec *prototypeFunctions;
   1.296 +    FinishClassInitOp finishInit;
   1.297 +    bool defined() const { return !!createConstructor; }
   1.298 +};
   1.299 +
   1.300 +struct ClassExtension
   1.301 +{
   1.302 +    JSObjectOp          outerObject;
   1.303 +    JSObjectOp          innerObject;
   1.304 +    JSIteratorOp        iteratorObject;
   1.305 +
   1.306 +    /*
   1.307 +     * isWrappedNative is true only if the class is an XPCWrappedNative.
   1.308 +     * WeakMaps use this to override the wrapper disposal optimization.
   1.309 +     */
   1.310 +    bool                isWrappedNative;
   1.311 +
   1.312 +    /*
   1.313 +     * If an object is used as a key in a weakmap, it may be desirable for the
   1.314 +     * garbage collector to keep that object around longer than it otherwise
   1.315 +     * would. A common case is when the key is a wrapper around an object in
   1.316 +     * another compartment, and we want to avoid collecting the wrapper (and
   1.317 +     * removing the weakmap entry) as long as the wrapped object is alive. In
   1.318 +     * that case, the wrapped object is returned by the wrapper's
   1.319 +     * weakmapKeyDelegateOp hook. As long as the wrapper is used as a weakmap
   1.320 +     * key, it will not be collected (and remain in the weakmap) until the
   1.321 +     * wrapped object is collected.
   1.322 +     */
   1.323 +    JSWeakmapKeyDelegateOp weakmapKeyDelegateOp;
   1.324 +};
   1.325 +
   1.326 +#define JS_NULL_CLASS_SPEC  {nullptr,nullptr,nullptr,nullptr,nullptr}
   1.327 +#define JS_NULL_CLASS_EXT   {nullptr,nullptr,nullptr,false,nullptr}
   1.328 +
   1.329 +struct ObjectOps
   1.330 +{
   1.331 +    LookupGenericOp     lookupGeneric;
   1.332 +    LookupPropOp        lookupProperty;
   1.333 +    LookupElementOp     lookupElement;
   1.334 +    DefineGenericOp     defineGeneric;
   1.335 +    DefinePropOp        defineProperty;
   1.336 +    DefineElementOp     defineElement;
   1.337 +    GenericIdOp         getGeneric;
   1.338 +    PropertyIdOp        getProperty;
   1.339 +    ElementIdOp         getElement;
   1.340 +    StrictGenericIdOp   setGeneric;
   1.341 +    StrictPropertyIdOp  setProperty;
   1.342 +    StrictElementIdOp   setElement;
   1.343 +    GenericAttributesOp getGenericAttributes;
   1.344 +    GenericAttributesOp setGenericAttributes;
   1.345 +    DeletePropertyOp    deleteProperty;
   1.346 +    DeleteElementOp     deleteElement;
   1.347 +    WatchOp             watch;
   1.348 +    UnwatchOp           unwatch;
   1.349 +    SliceOp             slice; // Optimized slice, can be null.
   1.350 +
   1.351 +    JSNewEnumerateOp    enumerate;
   1.352 +    ObjectOp            thisObject;
   1.353 +};
   1.354 +
   1.355 +#define JS_NULL_OBJECT_OPS                                                    \
   1.356 +    {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
   1.357 +     nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
   1.358 +     nullptr,nullptr}
   1.359 +
   1.360 +} // namespace js
   1.361 +
   1.362 +// Classes, objects, and properties.
   1.363 +
   1.364 +typedef void (*JSClassInternal)();
   1.365 +
   1.366 +struct JSClass {
   1.367 +    JS_CLASS_MEMBERS(JSFinalizeOp);
   1.368 +
   1.369 +    void                *reserved[31];
   1.370 +};
   1.371 +
   1.372 +#define JSCLASS_HAS_PRIVATE             (1<<0)  // objects have private slot
   1.373 +#define JSCLASS_NEW_ENUMERATE           (1<<1)  // has JSNewEnumerateOp hook
   1.374 +#define JSCLASS_NEW_RESOLVE             (1<<2)  // has JSNewResolveOp hook
   1.375 +#define JSCLASS_PRIVATE_IS_NSISUPPORTS  (1<<3)  // private is (nsISupports *)
   1.376 +#define JSCLASS_IS_DOMJSCLASS           (1<<4)  // objects are DOM
   1.377 +#define JSCLASS_IMPLEMENTS_BARRIERS     (1<<5)  // Correctly implements GC read
   1.378 +                                                // and write barriers
   1.379 +#define JSCLASS_EMULATES_UNDEFINED      (1<<6)  // objects of this class act
   1.380 +                                                // like the value undefined,
   1.381 +                                                // in some contexts
   1.382 +#define JSCLASS_USERBIT1                (1<<7)  // Reserved for embeddings.
   1.383 +
   1.384 +// To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or
   1.385 +// JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where
   1.386 +// n is a constant in [1, 255].  Reserved slots are indexed from 0 to n-1.
   1.387 +#define JSCLASS_RESERVED_SLOTS_SHIFT    8       // room for 8 flags below */
   1.388 +#define JSCLASS_RESERVED_SLOTS_WIDTH    8       // and 16 above this field */
   1.389 +#define JSCLASS_RESERVED_SLOTS_MASK     JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH)
   1.390 +#define JSCLASS_HAS_RESERVED_SLOTS(n)   (((n) & JSCLASS_RESERVED_SLOTS_MASK)  \
   1.391 +                                         << JSCLASS_RESERVED_SLOTS_SHIFT)
   1.392 +#define JSCLASS_RESERVED_SLOTS(clasp)   (((clasp)->flags                      \
   1.393 +                                          >> JSCLASS_RESERVED_SLOTS_SHIFT)    \
   1.394 +                                         & JSCLASS_RESERVED_SLOTS_MASK)
   1.395 +
   1.396 +#define JSCLASS_HIGH_FLAGS_SHIFT        (JSCLASS_RESERVED_SLOTS_SHIFT +       \
   1.397 +                                         JSCLASS_RESERVED_SLOTS_WIDTH)
   1.398 +
   1.399 +#define JSCLASS_IS_ANONYMOUS            (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
   1.400 +#define JSCLASS_IS_GLOBAL               (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1))
   1.401 +#define JSCLASS_INTERNAL_FLAG2          (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2))
   1.402 +#define JSCLASS_INTERNAL_FLAG3          (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
   1.403 +
   1.404 +#define JSCLASS_IS_PROXY                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
   1.405 +
   1.406 +// Bit 22 unused.
   1.407 +
   1.408 +// Reserved for embeddings.
   1.409 +#define JSCLASS_USERBIT2                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6))
   1.410 +#define JSCLASS_USERBIT3                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+7))
   1.411 +
   1.412 +#define JSCLASS_BACKGROUND_FINALIZE     (1<<(JSCLASS_HIGH_FLAGS_SHIFT+8))
   1.413 +
   1.414 +// Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
   1.415 +// below.
   1.416 +
   1.417 +// ECMA-262 requires that most constructors used internally create objects
   1.418 +// with "the original Foo.prototype value" as their [[Prototype]] (__proto__)
   1.419 +// member initial value.  The "original ... value" verbiage is there because
   1.420 +// in ECMA-262, global properties naming class objects are read/write and
   1.421 +// deleteable, for the most part.
   1.422 +//
   1.423 +// Implementing this efficiently requires that global objects have classes
   1.424 +// with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
   1.425 +// previously allowed, but is now an ES5 violation and thus unsupported.
   1.426 +//
   1.427 +#define JSCLASS_GLOBAL_SLOT_COUNT      (3 + JSProto_LIMIT * 3 + 31)
   1.428 +#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n)                                    \
   1.429 +    (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
   1.430 +#define JSCLASS_GLOBAL_FLAGS                                                  \
   1.431 +    JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0)
   1.432 +#define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp)                              \
   1.433 +  (((clasp)->flags & JSCLASS_IS_GLOBAL)                                       \
   1.434 +   && JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT)
   1.435 +
   1.436 +// Fast access to the original value of each standard class's prototype.
   1.437 +#define JSCLASS_CACHED_PROTO_SHIFT      (JSCLASS_HIGH_FLAGS_SHIFT + 10)
   1.438 +#define JSCLASS_CACHED_PROTO_WIDTH      6
   1.439 +#define JSCLASS_CACHED_PROTO_MASK       JS_BITMASK(JSCLASS_CACHED_PROTO_WIDTH)
   1.440 +#define JSCLASS_HAS_CACHED_PROTO(key)   (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT)
   1.441 +#define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey)                         \
   1.442 +                                         (((clasp)->flags                     \
   1.443 +                                           >> JSCLASS_CACHED_PROTO_SHIFT)     \
   1.444 +                                          & JSCLASS_CACHED_PROTO_MASK))
   1.445 +
   1.446 +// Initializer for unused members of statically initialized JSClass structs.
   1.447 +#define JSCLASS_NO_INTERNAL_MEMBERS     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
   1.448 +#define JSCLASS_NO_OPTIONAL_MEMBERS     0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS
   1.449 +
   1.450 +namespace js {
   1.451 +
   1.452 +struct Class
   1.453 +{
   1.454 +    JS_CLASS_MEMBERS(FinalizeOp);
   1.455 +    ClassSpec          spec;
   1.456 +    ClassExtension      ext;
   1.457 +    ObjectOps           ops;
   1.458 +
   1.459 +    /* Class is not native and its map is not a scope. */
   1.460 +    static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
   1.461 +
   1.462 +    bool isNative() const {
   1.463 +        return !(flags & NON_NATIVE);
   1.464 +    }
   1.465 +
   1.466 +    bool hasPrivate() const {
   1.467 +        return !!(flags & JSCLASS_HAS_PRIVATE);
   1.468 +    }
   1.469 +
   1.470 +    bool emulatesUndefined() const {
   1.471 +        return flags & JSCLASS_EMULATES_UNDEFINED;
   1.472 +    }
   1.473 +
   1.474 +    bool isJSFunction() const {
   1.475 +        return this == js::FunctionClassPtr;
   1.476 +    }
   1.477 +
   1.478 +    bool isCallable() const {
   1.479 +        return isJSFunction() || call;
   1.480 +    }
   1.481 +
   1.482 +    bool isProxy() const {
   1.483 +        return flags & JSCLASS_IS_PROXY;
   1.484 +    }
   1.485 +
   1.486 +    bool isDOMClass() const {
   1.487 +        return flags & JSCLASS_IS_DOMJSCLASS;
   1.488 +    }
   1.489 +
   1.490 +    static size_t offsetOfFlags() { return offsetof(Class, flags); }
   1.491 +};
   1.492 +
   1.493 +JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name));
   1.494 +JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags));
   1.495 +JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty));
   1.496 +JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty));
   1.497 +JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty));
   1.498 +JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty));
   1.499 +JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate));
   1.500 +JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve));
   1.501 +JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert));
   1.502 +JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
   1.503 +JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
   1.504 +JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
   1.505 +JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
   1.506 +JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace));
   1.507 +JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class));
   1.508 +
   1.509 +static MOZ_ALWAYS_INLINE const JSClass *
   1.510 +Jsvalify(const Class *c)
   1.511 +{
   1.512 +    return (const JSClass *)c;
   1.513 +}
   1.514 +
   1.515 +static MOZ_ALWAYS_INLINE const Class *
   1.516 +Valueify(const JSClass *c)
   1.517 +{
   1.518 +    return (const Class *)c;
   1.519 +}
   1.520 +
   1.521 +/*
   1.522 + * Enumeration describing possible values of the [[Class]] internal property
   1.523 + * value of objects.
   1.524 + */
   1.525 +enum ESClassValue {
   1.526 +    ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean,
   1.527 +    ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date
   1.528 +};
   1.529 +
   1.530 +/*
   1.531 + * Return whether the given object has the given [[Class]] internal property
   1.532 + * value. Beware, this query says nothing about the js::Class of the JSObject
   1.533 + * so the caller must not assume anything about obj's representation (e.g., obj
   1.534 + * may be a proxy).
   1.535 + */
   1.536 +inline bool
   1.537 +ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
   1.538 +
   1.539 +/* Just a helper that checks v.isObject before calling ObjectClassIs. */
   1.540 +inline bool
   1.541 +IsObjectWithClass(const JS::Value &v, ESClassValue classValue, JSContext *cx);
   1.542 +
   1.543 +}  /* namespace js */
   1.544 +
   1.545 +#endif  /* js_Class_h */

mercurial