js/public/Class.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* JSClass definition and its component types, plus related interfaces. */
     9 #ifndef js_Class_h
    10 #define js_Class_h
    12 #include "mozilla/NullPtr.h"
    14 #include "jstypes.h"
    16 #include "js/CallArgs.h"
    17 #include "js/Id.h"
    18 #include "js/TypeDecls.h"
    20 /*
    21  * A JSClass acts as a vtable for JS objects that allows JSAPI clients to
    22  * control various aspects of the behavior of an object like property lookup.
    23  * js::Class is an engine-private extension that allows more control over
    24  * object behavior and, e.g., allows custom slow layout.
    25  */
    27 class JSFreeOp;
    28 struct JSFunctionSpec;
    30 namespace js {
    32 class Class;
    33 class FreeOp;
    34 class PropertyName;
    35 class Shape;
    37 // This is equal to JSFunction::class_.  Use it in places where you don't want
    38 // to #include jsfun.h.
    39 extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr;
    41 } // namespace js
    43 // JSClass operation signatures.
    45 // Add or get a property named by id in obj.  Note the jsid id type -- id may
    46 // be a string (Unicode property identifier) or an int (element index).  The
    47 // *vp out parameter, on success, is the new property value after the action.
    48 typedef bool
    49 (* JSPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    50                  JS::MutableHandleValue vp);
    52 // Set a property named by id in obj, treating the assignment as strict
    53 // mode code if strict is true. Note the jsid id type -- id may be a string
    54 // (Unicode property identifier) or an int (element index). The *vp out
    55 // parameter, on success, is the new property value after the
    56 // set.
    57 typedef bool
    58 (* JSStrictPropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    59                        bool strict, JS::MutableHandleValue vp);
    61 // Delete a property named by id in obj.
    62 //
    63 // If an error occurred, return false as per normal JSAPI error practice.
    64 //
    65 // If no error occurred, but the deletion attempt wasn't allowed (perhaps
    66 // because the property was non-configurable), set *succeeded to false and
    67 // return true.  This will cause |delete obj[id]| to evaluate to false in
    68 // non-strict mode code, and to throw a TypeError in strict mode code.
    69 //
    70 // If no error occurred and the deletion wasn't disallowed (this is *not* the
    71 // same as saying that a deletion actually occurred -- deleting a non-existent
    72 // property, or an inherited property, is allowed -- it's just pointless),
    73 // set *succeeded to true and return true.
    74 typedef bool
    75 (* JSDeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
    76                        bool *succeeded);
    78 // This function type is used for callbacks that enumerate the properties of
    79 // a JSObject.  The behavior depends on the value of enum_op:
    80 //
    81 //  JSENUMERATE_INIT
    82 //    A new, opaque iterator state should be allocated and stored in *statep.
    83 //    (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored).
    84 //
    85 //    The number of properties that will be enumerated should be returned as
    86 //    an integer jsval in *idp, if idp is non-null, and provided the number of
    87 //    enumerable properties is known.  If idp is non-null and the number of
    88 //    enumerable properties can't be computed in advance, *idp should be set
    89 //    to JSVAL_ZERO.
    90 //
    91 //  JSENUMERATE_INIT_ALL
    92 //    Used identically to JSENUMERATE_INIT, but exposes all properties of the
    93 //    object regardless of enumerability.
    94 //
    95 //  JSENUMERATE_NEXT
    96 //    A previously allocated opaque iterator state is passed in via statep.
    97 //    Return the next jsid in the iteration using *idp.  The opaque iterator
    98 //    state pointed at by statep is destroyed and *statep is set to JSVAL_NULL
    99 //    if there are no properties left to enumerate.
   100 //
   101 //  JSENUMERATE_DESTROY
   102 //    Destroy the opaque iterator state previously allocated in *statep by a
   103 //    call to this function when enum_op was JSENUMERATE_INIT or
   104 //    JSENUMERATE_INIT_ALL.
   105 //
   106 // The return value is used to indicate success, with a value of false
   107 // indicating failure.
   108 typedef bool
   109 (* JSNewEnumerateOp)(JSContext *cx, JS::HandleObject obj, JSIterateOp enum_op,
   110                      JS::MutableHandleValue statep, JS::MutableHandleId idp);
   112 // The old-style JSClass.enumerate op should define all lazy properties not
   113 // yet reflected in obj.
   114 typedef bool
   115 (* JSEnumerateOp)(JSContext *cx, JS::HandleObject obj);
   117 // Resolve a lazy property named by id in obj by defining it directly in obj.
   118 // Lazy properties are those reflected from some peer native property space
   119 // (e.g., the DOM attributes for a given node reflected as obj) on demand.
   120 //
   121 // JS looks for a property in an object, and if not found, tries to resolve
   122 // the given id.  If resolve succeeds, the engine looks again in case resolve
   123 // defined obj[id].  If no such property exists directly in obj, the process
   124 // is repeated with obj's prototype, etc.
   125 //
   126 // NB: JSNewResolveOp provides a cheaper way to resolve lazy properties.
   127 typedef bool
   128 (* JSResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
   130 // Like JSResolveOp, except the *objp out parameter, on success, should be null
   131 // to indicate that id was not resolved; and non-null, referring to obj or one
   132 // of its prototypes, if id was resolved.  The hook may assume *objp is null on
   133 // entry.
   134 //
   135 // This hook instead of JSResolveOp is called via the JSClass.resolve member
   136 // if JSCLASS_NEW_RESOLVE is set in JSClass.flags.
   137 typedef bool
   138 (* JSNewResolveOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   139                    JS::MutableHandleObject objp);
   141 // Convert obj to the given type, returning true with the resulting value in
   142 // *vp on success, and returning false on error or exception.
   143 typedef bool
   144 (* JSConvertOp)(JSContext *cx, JS::HandleObject obj, JSType type,
   145                 JS::MutableHandleValue vp);
   147 // Finalize obj, which the garbage collector has determined to be unreachable
   148 // from other live objects or from GC roots.  Obviously, finalizers must never
   149 // store a reference to obj.
   150 typedef void
   151 (* JSFinalizeOp)(JSFreeOp *fop, JSObject *obj);
   153 // Finalizes external strings created by JS_NewExternalString.
   154 struct JSStringFinalizer {
   155     void (*finalize)(const JSStringFinalizer *fin, jschar *chars);
   156 };
   158 // Check whether v is an instance of obj.  Return false on error or exception,
   159 // true on success with true in *bp if v is an instance of obj, false in
   160 // *bp otherwise.
   161 typedef bool
   162 (* JSHasInstanceOp)(JSContext *cx, JS::HandleObject obj, JS::MutableHandleValue vp,
   163                     bool *bp);
   165 // Function type for trace operation of the class called to enumerate all
   166 // traceable things reachable from obj's private data structure. For each such
   167 // thing, a trace implementation must call one of the JS_Call*Tracer variants
   168 // on the thing.
   169 //
   170 // JSTraceOp implementation can assume that no other threads mutates object
   171 // state. It must not change state of the object or corresponding native
   172 // structures. The only exception for this rule is the case when the embedding
   173 // needs a tight integration with GC. In that case the embedding can check if
   174 // the traversal is a part of the marking phase through calling
   175 // JS_IsGCMarkingTracer and apply a special code like emptying caches or
   176 // marking its native structures.
   177 typedef void
   178 (* JSTraceOp)(JSTracer *trc, JSObject *obj);
   180 // A generic type for functions mapping an object to another object, or null
   181 // if an error or exception was thrown on cx.
   182 typedef JSObject *
   183 (* JSObjectOp)(JSContext *cx, JS::HandleObject obj);
   185 // Hook that creates an iterator object for a given object. Returns the
   186 // iterator object or null if an error or exception was thrown on cx.
   187 typedef JSObject *
   188 (* JSIteratorOp)(JSContext *cx, JS::HandleObject obj, bool keysonly);
   190 typedef JSObject *
   191 (* JSWeakmapKeyDelegateOp)(JSObject *obj);
   193 /* js::Class operation signatures. */
   195 namespace js {
   197 typedef bool
   198 (* LookupGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   199                     JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   200 typedef bool
   201 (* LookupPropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   202                  JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   203 typedef bool
   204 (* LookupElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index,
   205                     JS::MutableHandleObject objp, JS::MutableHandle<Shape*> propp);
   206 typedef bool
   207 (* DefineGenericOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleValue value,
   208                     JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   209 typedef bool
   210 (* DefinePropOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   211                  JS::HandleValue value, JSPropertyOp getter, JSStrictPropertyOp setter,
   212                  unsigned attrs);
   213 typedef bool
   214 (* DefineElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, JS::HandleValue value,
   215                     JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
   216 typedef bool
   217 (* GenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, JS::HandleId id,
   218                 JS::MutableHandleValue vp);
   219 typedef bool
   220 (* PropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver,
   221                  JS::Handle<PropertyName*> name, JS::MutableHandleValue vp);
   222 typedef bool
   223 (* ElementIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleObject receiver, uint32_t index,
   224                 JS::MutableHandleValue vp);
   225 typedef bool
   226 (* StrictGenericIdOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
   227                       JS::MutableHandleValue vp, bool strict);
   228 typedef bool
   229 (* StrictPropertyIdOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   230                        JS::MutableHandleValue vp, bool strict);
   231 typedef bool
   232 (* StrictElementIdOp)(JSContext *cx, JS::HandleObject obj, uint32_t index,
   233                       JS::MutableHandleValue vp, bool strict);
   234 typedef bool
   235 (* GenericAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned *attrsp);
   236 typedef bool
   237 (* PropertyAttributesOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   238                          unsigned *attrsp);
   239 typedef bool
   240 (* DeletePropertyOp)(JSContext *cx, JS::HandleObject obj, JS::Handle<PropertyName*> name,
   241                      bool *succeeded);
   242 typedef bool
   243 (* DeleteElementOp)(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
   245 typedef bool
   246 (* WatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::HandleObject callable);
   248 typedef bool
   249 (* UnwatchOp)(JSContext *cx, JS::HandleObject obj, JS::HandleId id);
   251 typedef bool
   252 (* SliceOp)(JSContext *cx, JS::HandleObject obj, uint32_t begin, uint32_t end,
   253             JS::HandleObject result); // result is actually preallocted.
   255 typedef JSObject *
   256 (* ObjectOp)(JSContext *cx, JS::HandleObject obj);
   257 typedef void
   258 (* FinalizeOp)(FreeOp *fop, JSObject *obj);
   260 #define JS_CLASS_MEMBERS(FinalizeOpType)                                      \
   261     const char          *name;                                                \
   262     uint32_t            flags;                                                \
   263                                                                               \
   264     /* Mandatory function pointer members. */                                 \
   265     JSPropertyOp        addProperty;                                          \
   266     JSDeletePropertyOp  delProperty;                                          \
   267     JSPropertyOp        getProperty;                                          \
   268     JSStrictPropertyOp  setProperty;                                          \
   269     JSEnumerateOp       enumerate;                                            \
   270     JSResolveOp         resolve;                                              \
   271     JSConvertOp         convert;                                              \
   272                                                                               \
   273     /* Optional members (may be null). */                                     \
   274     FinalizeOpType      finalize;                                             \
   275     JSNative            call;                                                 \
   276     JSHasInstanceOp     hasInstance;                                          \
   277     JSNative            construct;                                            \
   278     JSTraceOp           trace
   280 // Callback for the creation of constructor and prototype objects.
   281 typedef JSObject *(*ClassObjectCreationOp)(JSContext *cx, JSProtoKey key);
   283 // Callback for custom post-processing after class initialization via ClassSpec.
   284 typedef bool (*FinishClassInitOp)(JSContext *cx, JS::HandleObject ctor,
   285                                   JS::HandleObject proto);
   287 struct ClassSpec
   288 {
   289     ClassObjectCreationOp createConstructor;
   290     ClassObjectCreationOp createPrototype;
   291     const JSFunctionSpec *constructorFunctions;
   292     const JSFunctionSpec *prototypeFunctions;
   293     FinishClassInitOp finishInit;
   294     bool defined() const { return !!createConstructor; }
   295 };
   297 struct ClassExtension
   298 {
   299     JSObjectOp          outerObject;
   300     JSObjectOp          innerObject;
   301     JSIteratorOp        iteratorObject;
   303     /*
   304      * isWrappedNative is true only if the class is an XPCWrappedNative.
   305      * WeakMaps use this to override the wrapper disposal optimization.
   306      */
   307     bool                isWrappedNative;
   309     /*
   310      * If an object is used as a key in a weakmap, it may be desirable for the
   311      * garbage collector to keep that object around longer than it otherwise
   312      * would. A common case is when the key is a wrapper around an object in
   313      * another compartment, and we want to avoid collecting the wrapper (and
   314      * removing the weakmap entry) as long as the wrapped object is alive. In
   315      * that case, the wrapped object is returned by the wrapper's
   316      * weakmapKeyDelegateOp hook. As long as the wrapper is used as a weakmap
   317      * key, it will not be collected (and remain in the weakmap) until the
   318      * wrapped object is collected.
   319      */
   320     JSWeakmapKeyDelegateOp weakmapKeyDelegateOp;
   321 };
   323 #define JS_NULL_CLASS_SPEC  {nullptr,nullptr,nullptr,nullptr,nullptr}
   324 #define JS_NULL_CLASS_EXT   {nullptr,nullptr,nullptr,false,nullptr}
   326 struct ObjectOps
   327 {
   328     LookupGenericOp     lookupGeneric;
   329     LookupPropOp        lookupProperty;
   330     LookupElementOp     lookupElement;
   331     DefineGenericOp     defineGeneric;
   332     DefinePropOp        defineProperty;
   333     DefineElementOp     defineElement;
   334     GenericIdOp         getGeneric;
   335     PropertyIdOp        getProperty;
   336     ElementIdOp         getElement;
   337     StrictGenericIdOp   setGeneric;
   338     StrictPropertyIdOp  setProperty;
   339     StrictElementIdOp   setElement;
   340     GenericAttributesOp getGenericAttributes;
   341     GenericAttributesOp setGenericAttributes;
   342     DeletePropertyOp    deleteProperty;
   343     DeleteElementOp     deleteElement;
   344     WatchOp             watch;
   345     UnwatchOp           unwatch;
   346     SliceOp             slice; // Optimized slice, can be null.
   348     JSNewEnumerateOp    enumerate;
   349     ObjectOp            thisObject;
   350 };
   352 #define JS_NULL_OBJECT_OPS                                                    \
   353     {nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
   354      nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr, \
   355      nullptr,nullptr}
   357 } // namespace js
   359 // Classes, objects, and properties.
   361 typedef void (*JSClassInternal)();
   363 struct JSClass {
   364     JS_CLASS_MEMBERS(JSFinalizeOp);
   366     void                *reserved[31];
   367 };
   369 #define JSCLASS_HAS_PRIVATE             (1<<0)  // objects have private slot
   370 #define JSCLASS_NEW_ENUMERATE           (1<<1)  // has JSNewEnumerateOp hook
   371 #define JSCLASS_NEW_RESOLVE             (1<<2)  // has JSNewResolveOp hook
   372 #define JSCLASS_PRIVATE_IS_NSISUPPORTS  (1<<3)  // private is (nsISupports *)
   373 #define JSCLASS_IS_DOMJSCLASS           (1<<4)  // objects are DOM
   374 #define JSCLASS_IMPLEMENTS_BARRIERS     (1<<5)  // Correctly implements GC read
   375                                                 // and write barriers
   376 #define JSCLASS_EMULATES_UNDEFINED      (1<<6)  // objects of this class act
   377                                                 // like the value undefined,
   378                                                 // in some contexts
   379 #define JSCLASS_USERBIT1                (1<<7)  // Reserved for embeddings.
   381 // To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or
   382 // JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where
   383 // n is a constant in [1, 255].  Reserved slots are indexed from 0 to n-1.
   384 #define JSCLASS_RESERVED_SLOTS_SHIFT    8       // room for 8 flags below */
   385 #define JSCLASS_RESERVED_SLOTS_WIDTH    8       // and 16 above this field */
   386 #define JSCLASS_RESERVED_SLOTS_MASK     JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH)
   387 #define JSCLASS_HAS_RESERVED_SLOTS(n)   (((n) & JSCLASS_RESERVED_SLOTS_MASK)  \
   388                                          << JSCLASS_RESERVED_SLOTS_SHIFT)
   389 #define JSCLASS_RESERVED_SLOTS(clasp)   (((clasp)->flags                      \
   390                                           >> JSCLASS_RESERVED_SLOTS_SHIFT)    \
   391                                          & JSCLASS_RESERVED_SLOTS_MASK)
   393 #define JSCLASS_HIGH_FLAGS_SHIFT        (JSCLASS_RESERVED_SLOTS_SHIFT +       \
   394                                          JSCLASS_RESERVED_SLOTS_WIDTH)
   396 #define JSCLASS_IS_ANONYMOUS            (1<<(JSCLASS_HIGH_FLAGS_SHIFT+0))
   397 #define JSCLASS_IS_GLOBAL               (1<<(JSCLASS_HIGH_FLAGS_SHIFT+1))
   398 #define JSCLASS_INTERNAL_FLAG2          (1<<(JSCLASS_HIGH_FLAGS_SHIFT+2))
   399 #define JSCLASS_INTERNAL_FLAG3          (1<<(JSCLASS_HIGH_FLAGS_SHIFT+3))
   401 #define JSCLASS_IS_PROXY                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+4))
   403 // Bit 22 unused.
   405 // Reserved for embeddings.
   406 #define JSCLASS_USERBIT2                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+6))
   407 #define JSCLASS_USERBIT3                (1<<(JSCLASS_HIGH_FLAGS_SHIFT+7))
   409 #define JSCLASS_BACKGROUND_FINALIZE     (1<<(JSCLASS_HIGH_FLAGS_SHIFT+8))
   411 // Bits 26 through 31 are reserved for the CACHED_PROTO_KEY mechanism, see
   412 // below.
   414 // ECMA-262 requires that most constructors used internally create objects
   415 // with "the original Foo.prototype value" as their [[Prototype]] (__proto__)
   416 // member initial value.  The "original ... value" verbiage is there because
   417 // in ECMA-262, global properties naming class objects are read/write and
   418 // deleteable, for the most part.
   419 //
   420 // Implementing this efficiently requires that global objects have classes
   421 // with the following flags. Failure to use JSCLASS_GLOBAL_FLAGS was
   422 // previously allowed, but is now an ES5 violation and thus unsupported.
   423 //
   424 #define JSCLASS_GLOBAL_SLOT_COUNT      (3 + JSProto_LIMIT * 3 + 31)
   425 #define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n)                                    \
   426     (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
   427 #define JSCLASS_GLOBAL_FLAGS                                                  \
   428     JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0)
   429 #define JSCLASS_HAS_GLOBAL_FLAG_AND_SLOTS(clasp)                              \
   430   (((clasp)->flags & JSCLASS_IS_GLOBAL)                                       \
   431    && JSCLASS_RESERVED_SLOTS(clasp) >= JSCLASS_GLOBAL_SLOT_COUNT)
   433 // Fast access to the original value of each standard class's prototype.
   434 #define JSCLASS_CACHED_PROTO_SHIFT      (JSCLASS_HIGH_FLAGS_SHIFT + 10)
   435 #define JSCLASS_CACHED_PROTO_WIDTH      6
   436 #define JSCLASS_CACHED_PROTO_MASK       JS_BITMASK(JSCLASS_CACHED_PROTO_WIDTH)
   437 #define JSCLASS_HAS_CACHED_PROTO(key)   (uint32_t(key) << JSCLASS_CACHED_PROTO_SHIFT)
   438 #define JSCLASS_CACHED_PROTO_KEY(clasp) ((JSProtoKey)                         \
   439                                          (((clasp)->flags                     \
   440                                            >> JSCLASS_CACHED_PROTO_SHIFT)     \
   441                                           & JSCLASS_CACHED_PROTO_MASK))
   443 // Initializer for unused members of statically initialized JSClass structs.
   444 #define JSCLASS_NO_INTERNAL_MEMBERS     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
   445 #define JSCLASS_NO_OPTIONAL_MEMBERS     0,0,0,0,0,JSCLASS_NO_INTERNAL_MEMBERS
   447 namespace js {
   449 struct Class
   450 {
   451     JS_CLASS_MEMBERS(FinalizeOp);
   452     ClassSpec          spec;
   453     ClassExtension      ext;
   454     ObjectOps           ops;
   456     /* Class is not native and its map is not a scope. */
   457     static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
   459     bool isNative() const {
   460         return !(flags & NON_NATIVE);
   461     }
   463     bool hasPrivate() const {
   464         return !!(flags & JSCLASS_HAS_PRIVATE);
   465     }
   467     bool emulatesUndefined() const {
   468         return flags & JSCLASS_EMULATES_UNDEFINED;
   469     }
   471     bool isJSFunction() const {
   472         return this == js::FunctionClassPtr;
   473     }
   475     bool isCallable() const {
   476         return isJSFunction() || call;
   477     }
   479     bool isProxy() const {
   480         return flags & JSCLASS_IS_PROXY;
   481     }
   483     bool isDOMClass() const {
   484         return flags & JSCLASS_IS_DOMJSCLASS;
   485     }
   487     static size_t offsetOfFlags() { return offsetof(Class, flags); }
   488 };
   490 JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name));
   491 JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags));
   492 JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty));
   493 JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty));
   494 JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty));
   495 JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty));
   496 JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate));
   497 JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve));
   498 JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert));
   499 JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
   500 JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
   501 JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
   502 JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
   503 JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace));
   504 JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class));
   506 static MOZ_ALWAYS_INLINE const JSClass *
   507 Jsvalify(const Class *c)
   508 {
   509     return (const JSClass *)c;
   510 }
   512 static MOZ_ALWAYS_INLINE const Class *
   513 Valueify(const JSClass *c)
   514 {
   515     return (const Class *)c;
   516 }
   518 /*
   519  * Enumeration describing possible values of the [[Class]] internal property
   520  * value of objects.
   521  */
   522 enum ESClassValue {
   523     ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean,
   524     ESClass_RegExp, ESClass_ArrayBuffer, ESClass_Date
   525 };
   527 /*
   528  * Return whether the given object has the given [[Class]] internal property
   529  * value. Beware, this query says nothing about the js::Class of the JSObject
   530  * so the caller must not assume anything about obj's representation (e.g., obj
   531  * may be a proxy).
   532  */
   533 inline bool
   534 ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
   536 /* Just a helper that checks v.isObject before calling ObjectClassIs. */
   537 inline bool
   538 IsObjectWithClass(const JS::Value &v, ESClassValue classValue, JSContext *cx);
   540 }  /* namespace js */
   542 #endif  /* js_Class_h */

mercurial