LCOV - app.info - js/src/jsclass.h

LCOV - code coverage report
| Current view: | directory - js/src - jsclass.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 54 | 30 | 55.6 %
| Date: | 2012-04-21 | Functions: | 18 | 13 | 72.2 %

           1                 : /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=4 sw=4 et tw=79 ft=cpp:
           3                 :  *
           4                 :  * ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is SpiderMonkey JavaScript engine.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * Mozilla Corporation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2009
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *
          26                 :  * Alternatively, the contents of this file may be used under the terms of
          27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          30                 :  * of those above. If you wish to allow use of your version of this file only
          31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          32                 :  * use your version of this file under the terms of the MPL, indicate your
          33                 :  * decision by deleting the provisions above and replace them with the notice
          34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          35                 :  * the provisions above, a recipient may use your version of this file under
          36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          37                 :  *
          38                 :  * ***** END LICENSE BLOCK ***** */
          39                 :
          40                 : #ifndef jsclass_h__
          41                 : #define jsclass_h__
          42                 : /*
          43                 :  * A JSClass acts as a vtable for JS objects that allows JSAPI clients to
          44                 :  * control various aspects of the behavior of an object like property lookup.
          45                 :  * js::Class is an engine-private extension that allows more control over
          46                 :  * object behavior and, e.g., allows custom slow layout.
          47                 :  */
          48                 : #include "jsapi.h"
          49                 : #include "jsprvtd.h"
          50                 :
          51                 : #ifdef __cplusplus
          52                 :
          53                 : namespace js {
          54                 :
          55                 : class PropertyName;
          56                 : class SpecialId;
          57                 :
          58                 : static JS_ALWAYS_INLINE jsid
          59                 : SPECIALID_TO_JSID(const SpecialId &sid);
          60                 :
          61                 : /*
          62                 :  * We partition the ways to refer to a property into three: by an index
          63                 :  * (uint32_t); by a string whose characters do not represent an index
          64                 :  * (PropertyName, see vm/String.h); and by various special values.
          65                 :  *
          66                 :  * Special values are encoded using SpecialId, which is layout-compatible but
          67                 :  * non-interconvertible with jsid.  A SpecialId may be: an object (used by E4X
          68                 :  * and perhaps eventually by Harmony-proposed private names); JSID_VOID, which
          69                 :  * does not occur in JS scripts but may be used to indicate the absence of a
          70                 :  * valid identifier; or JS_DEFAULT_XML_NAMESPACE_ID, if E4X is enabled.
          71                 :  */
          72                 :
          73                 : class SpecialId {
          74                 :     uintptr_t bits;
          75                 :
          76                 :     /* Needs access to raw bits. */
          77                 :     friend JS_ALWAYS_INLINE jsid SPECIALID_TO_JSID(const SpecialId &sid);
          78                 :
          79                 :     static const uintptr_t TYPE_VOID = JSID_TYPE_VOID;
          80                 :     static const uintptr_t TYPE_OBJECT = JSID_TYPE_OBJECT;
          81                 :     static const uintptr_t TYPE_DEFAULT_XML_NAMESPACE = JSID_TYPE_DEFAULT_XML_NAMESPACE;
          82                 :     static const uintptr_t TYPE_MASK = JSID_TYPE_MASK;
          83                 :
          84            8100 :     SpecialId(uintptr_t bits) : bits(bits) { }
          85                 :
          86                 :   public:
          87         4756214 :     SpecialId() : bits(TYPE_VOID) { }
          88                 :
          89                 :     /* Object-valued */
          90                 :
          91               0 :     SpecialId(JSObject &obj)
          92               0 :       : bits(uintptr_t(&obj) | TYPE_OBJECT)
          93                 :     {
          94               0 :         JS_ASSERT(&obj != NULL);
          95               0 :         JS_ASSERT((uintptr_t(&obj) & TYPE_MASK) == 0);
          96               0 :     }
          97                 :
          98            8100 :     bool isObject() const {
          99            8100 :         return (bits & TYPE_MASK) == TYPE_OBJECT && bits != TYPE_OBJECT;
         100                 :     }
         101                 :
         102               0 :     JSObject *toObject() const {
         103               0 :         JS_ASSERT(isObject());
         104               0 :         return reinterpret_cast<JSObject *>(bits & ~TYPE_MASK);
         105                 :     }
         106                 :
         107                 :     /* Empty */
         108                 :
         109               0 :     static SpecialId empty() {
         110               0 :         SpecialId sid(TYPE_OBJECT);
         111               0 :         JS_ASSERT(sid.isEmpty());
         112                 :         return sid;
         113                 :     }
         114                 :
         115            8100 :     bool isEmpty() const {
         116            8100 :         return bits == TYPE_OBJECT;
         117                 :     }
         118                 :
         119                 :     /* Void */
         120                 :
         121               0 :     static SpecialId voidId() {
         122               0 :         SpecialId sid(TYPE_VOID);
         123               0 :         JS_ASSERT(sid.isVoid());
         124                 :         return sid;
         125                 :     }
         126                 :
         127            8100 :     bool isVoid() const {
         128            8100 :         return bits == TYPE_VOID;
         129                 :     }
         130                 :
         131                 :     /* Default XML namespace */
         132                 :
         133            8100 :     static SpecialId defaultXMLNamespace() {
         134            8100 :         SpecialId sid(TYPE_DEFAULT_XML_NAMESPACE);
         135            8100 :         JS_ASSERT(sid.isDefaultXMLNamespace());
         136                 :         return sid;
         137                 :     }
         138                 :
         139           16200 :     bool isDefaultXMLNamespace() const {
         140           16200 :         return bits == TYPE_DEFAULT_XML_NAMESPACE;
         141                 :     }
         142                 : };
         143                 :
         144                 : static JS_ALWAYS_INLINE jsid
         145            8100 : SPECIALID_TO_JSID(const SpecialId &sid)
         146                 : {
         147                 :     jsid id;
         148            8100 :     JSID_BITS(id) = sid.bits;
         149            8100 :     JS_ASSERT_IF(sid.isObject(), JSID_IS_OBJECT(id) && JSID_TO_OBJECT(id) == sid.toObject());
         150            8100 :     JS_ASSERT_IF(sid.isVoid(), JSID_IS_VOID(id));
         151            8100 :     JS_ASSERT_IF(sid.isEmpty(), JSID_IS_EMPTY(id));
         152            8100 :     JS_ASSERT_IF(sid.isDefaultXMLNamespace(), JSID_IS_DEFAULT_XML_NAMESPACE(id));
         153                 :     return id;
         154                 : }
         155                 :
         156                 : static JS_ALWAYS_INLINE bool
         157               9 : JSID_IS_SPECIAL(jsid id)
         158                 : {
         159              27 :     return JSID_IS_OBJECT(id) || JSID_IS_EMPTY(id) || JSID_IS_VOID(id) ||
         160              27 :            JSID_IS_DEFAULT_XML_NAMESPACE(id);
         161                 : }
         162                 :
         163                 : static JS_ALWAYS_INLINE SpecialId
         164               0 : JSID_TO_SPECIALID(jsid id)
         165                 : {
         166               0 :     JS_ASSERT(JSID_IS_SPECIAL(id));
         167               0 :     if (JSID_IS_OBJECT(id))
         168               0 :         return SpecialId(*JSID_TO_OBJECT(id));
         169               0 :     if (JSID_IS_EMPTY(id))
         170               0 :         return SpecialId::empty();
         171               0 :     if (JSID_IS_VOID(id))
         172               0 :         return SpecialId::voidId();
         173               0 :     JS_ASSERT(JSID_IS_DEFAULT_XML_NAMESPACE(id));
         174               0 :     return SpecialId::defaultXMLNamespace();
         175                 : }
         176                 :
         177                 : /* js::Class operation signatures. */
         178                 :
         179                 : typedef JSBool
         180                 : (* LookupGenericOp)(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
         181                 :                     JSProperty **propp);
         182                 : typedef JSBool
         183                 : (* LookupPropOp)(JSContext *cx, JSObject *obj, PropertyName *name, JSObject **objp,
         184                 :                  JSProperty **propp);
         185                 : typedef JSBool
         186                 : (* LookupElementOp)(JSContext *cx, JSObject *obj, uint32_t index, JSObject **objp,
         187                 :                     JSProperty **propp);
         188                 : typedef JSBool
         189                 : (* LookupSpecialOp)(JSContext *cx, JSObject *obj, SpecialId sid, JSObject **objp,
         190                 :                     JSProperty **propp);
         191                 : typedef JSBool
         192                 : (* DefineGenericOp)(JSContext *cx, JSObject *obj, jsid id, const Value *value,
         193                 :                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
         194                 : typedef JSBool
         195                 : (* DefinePropOp)(JSContext *cx, JSObject *obj, PropertyName *name, const Value *value,
         196                 :                  PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
         197                 : typedef JSBool
         198                 : (* DefineElementOp)(JSContext *cx, JSObject *obj, uint32_t index, const Value *value,
         199                 :                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
         200                 : typedef JSBool
         201                 : (* DefineSpecialOp)(JSContext *cx, JSObject *obj, SpecialId sid, const Value *value,
         202                 :                     PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
         203                 : typedef JSBool
         204                 : (* GenericIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp);
         205                 : typedef JSBool
         206                 : (* PropertyIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name, Value *vp);
         207                 : typedef JSBool
         208                 : (* ElementIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp);
         209                 : typedef JSBool
         210                 : (* ElementIfPresentOp)(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp, bool* present);
         211                 : typedef JSBool
         212                 : (* SpecialIdOp)(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp);
         213                 : typedef JSBool
         214                 : (* StrictGenericIdOp)(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict);
         215                 : typedef JSBool
         216                 : (* StrictPropertyIdOp)(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict);
         217                 : typedef JSBool
         218                 : (* StrictElementIdOp)(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict);
         219                 : typedef JSBool
         220                 : (* StrictSpecialIdOp)(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool strict);
         221                 : typedef JSBool
         222                 : (* GenericAttributesOp)(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
         223                 : typedef JSBool
         224                 : (* PropertyAttributesOp)(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp);
         225                 : typedef JSBool
         226                 : (* ElementAttributesOp)(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
         227                 : typedef JSBool
         228                 : (* SpecialAttributesOp)(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp);
         229                 : typedef JSBool
         230                 : (* DeletePropertyOp)(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict);
         231                 : typedef JSBool
         232                 : (* DeleteElementOp)(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict);
         233                 : typedef JSBool
         234                 : (* DeleteSpecialOp)(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool strict);
         235                 : typedef JSType
         236                 : (* TypeOfOp)(JSContext *cx, JSObject *obj);
         237                 :
         238                 : /*
         239                 :  * Prepare to make |obj| non-extensible; in particular, fully resolve its properties.
         240                 :  * On error, return false.
         241                 :  * If |obj| is now ready to become non-extensible, set |*fixed| to true and return true.
         242                 :  * If |obj| refuses to become non-extensible, set |*fixed| to false and return true; the
         243                 :  * caller will throw an appropriate error.
         244                 :  */
         245                 : typedef JSBool
         246                 : (* FixOp)(JSContext *cx, JSObject *obj, bool *fixed, AutoIdVector *props);
         247                 :
         248                 : typedef JSObject *
         249                 : (* ObjectOp)(JSContext *cx, JSObject *obj);
         250                 : typedef void
         251                 : (* FinalizeOp)(JSContext *cx, JSObject *obj);
         252                 :
         253                 : #define JS_CLASS_MEMBERS                                                      \
         254                 :     const char          *name;                                                \
         255                 :     uint32_t            flags;                                                \
         256                 :                                                                               \
         257                 :     /* Mandatory non-null function pointer members. */                        \
         258                 :     JSPropertyOp        addProperty;                                          \
         259                 :     JSPropertyOp        delProperty;                                          \
         260                 :     JSPropertyOp        getProperty;                                          \
         261                 :     JSStrictPropertyOp  setProperty;                                          \
         262                 :     JSEnumerateOp       enumerate;                                            \
         263                 :     JSResolveOp         resolve;                                              \
         264                 :     JSConvertOp         convert;                                              \
         265                 :     JSFinalizeOp        finalize;                                             \
         266                 :                                                                               \
         267                 :     /* Optionally non-null members start here. */                             \
         268                 :     JSCheckAccessOp     checkAccess;                                          \
         269                 :     JSNative            call;                                                 \
         270                 :     JSNative            construct;                                            \
         271                 :     JSHasInstanceOp     hasInstance;                                          \
         272                 :     JSTraceOp           trace
         273                 :
         274                 : /*
         275                 :  * The helper struct to measure the size of JS_CLASS_MEMBERS to know how much
         276                 :  * we have to padd js::Class to match the size of JSClass;
         277                 :  */
         278                 : struct ClassSizeMeasurement
         279                 : {
         280                 :     JS_CLASS_MEMBERS;
         281                 : };
         282                 :
         283                 : struct ClassExtension
         284                 : {
         285                 :     JSEqualityOp        equality;
         286                 :     JSObjectOp          outerObject;
         287                 :     JSObjectOp          innerObject;
         288                 :     JSIteratorOp        iteratorObject;
         289                 :     void               *unused;
         290                 :
         291                 :     /*
         292                 :      * isWrappedNative is true only if the class is an XPCWrappedNative.
         293                 :      * WeakMaps use this to override the wrapper disposal optimization.
         294                 :      */
         295                 :     bool                isWrappedNative;
         296                 : };
         297                 :
         298                 : #define JS_NULL_CLASS_EXT   {NULL,NULL,NULL,NULL,NULL,false}
         299                 :
         300                 : struct ObjectOps
         301                 : {
         302                 :     LookupGenericOp     lookupGeneric;
         303                 :     LookupPropOp        lookupProperty;
         304                 :     LookupElementOp     lookupElement;
         305                 :     LookupSpecialOp     lookupSpecial;
         306                 :     DefineGenericOp     defineGeneric;
         307                 :     DefinePropOp        defineProperty;
         308                 :     DefineElementOp     defineElement;
         309                 :     DefineSpecialOp     defineSpecial;
         310                 :     GenericIdOp         getGeneric;
         311                 :     PropertyIdOp        getProperty;
         312                 :     ElementIdOp         getElement;
         313                 :     ElementIfPresentOp  getElementIfPresent; /* can be null */
         314                 :     SpecialIdOp         getSpecial;
         315                 :     StrictGenericIdOp   setGeneric;
         316                 :     StrictPropertyIdOp  setProperty;
         317                 :     StrictElementIdOp   setElement;
         318                 :     StrictSpecialIdOp   setSpecial;
         319                 :     GenericAttributesOp getGenericAttributes;
         320                 :     PropertyAttributesOp getPropertyAttributes;
         321                 :     ElementAttributesOp getElementAttributes;
         322                 :     SpecialAttributesOp getSpecialAttributes;
         323                 :     GenericAttributesOp setGenericAttributes;
         324                 :     PropertyAttributesOp setPropertyAttributes;
         325                 :     ElementAttributesOp setElementAttributes;
         326                 :     SpecialAttributesOp setSpecialAttributes;
         327                 :     DeletePropertyOp    deleteProperty;
         328                 :     DeleteElementOp     deleteElement;
         329                 :     DeleteSpecialOp     deleteSpecial;
         330                 :
         331                 :     JSNewEnumerateOp    enumerate;
         332                 :     TypeOfOp            typeOf;
         333                 :     FixOp               fix;
         334                 :     ObjectOp            thisObject;
         335                 :     FinalizeOp          clear;
         336                 : };
         337                 :
         338                 : #define JS_NULL_OBJECT_OPS                                                    \
         339                 :     {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,   \
         340                 :      NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,        \
         341                 :      NULL,NULL,NULL,NULL,NULL,NULL}
         342                 :
         343                 : struct Class
         344                 : {
         345                 :     JS_CLASS_MEMBERS;
         346                 :     ClassExtension      ext;
         347                 :     ObjectOps           ops;
         348                 :     uint8_t             pad[sizeof(JSClass) - sizeof(ClassSizeMeasurement) -
         349                 :                             sizeof(ClassExtension) - sizeof(ObjectOps)];
         350                 :
         351                 :     /* Class is not native and its map is not a scope. */
         352                 :     static const uint32_t NON_NATIVE = JSCLASS_INTERNAL_FLAG2;
         353                 :
         354       746702302 :     bool isNative() const {
         355       746702302 :         return !(flags & NON_NATIVE);
         356                 :     }
         357                 :
         358        71830943 :     bool hasPrivate() const {
         359        71830943 :         return !!(flags & JSCLASS_HAS_PRIVATE);
         360                 :     }
         361                 : };
         362                 :
         363                 : JS_STATIC_ASSERT(offsetof(JSClass, name) == offsetof(Class, name));
         364                 : JS_STATIC_ASSERT(offsetof(JSClass, flags) == offsetof(Class, flags));
         365                 : JS_STATIC_ASSERT(offsetof(JSClass, addProperty) == offsetof(Class, addProperty));
         366                 : JS_STATIC_ASSERT(offsetof(JSClass, delProperty) == offsetof(Class, delProperty));
         367                 : JS_STATIC_ASSERT(offsetof(JSClass, getProperty) == offsetof(Class, getProperty));
         368                 : JS_STATIC_ASSERT(offsetof(JSClass, setProperty) == offsetof(Class, setProperty));
         369                 : JS_STATIC_ASSERT(offsetof(JSClass, enumerate) == offsetof(Class, enumerate));
         370                 : JS_STATIC_ASSERT(offsetof(JSClass, resolve) == offsetof(Class, resolve));
         371                 : JS_STATIC_ASSERT(offsetof(JSClass, convert) == offsetof(Class, convert));
         372                 : JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
         373                 : JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess));
         374                 : JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
         375                 : JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
         376                 : JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
         377                 : JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace));
         378                 : JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class));
         379                 :
         380                 : static JS_ALWAYS_INLINE JSClass *
         381         4523161 : Jsvalify(Class *c)
         382                 : {
         383         4523161 :     return (JSClass *)c;
         384                 : }
         385                 : static JS_ALWAYS_INLINE const JSClass *
         386                 : Jsvalify(const Class *c)
         387                 : {
         388                 :     return (const JSClass *)c;
         389                 : }
         390                 :
         391                 : static JS_ALWAYS_INLINE Class *
         392         3429278 : Valueify(JSClass *c)
         393                 : {
         394         3429278 :     return (Class *)c;
         395                 : }
         396                 : static JS_ALWAYS_INLINE const Class *
         397                 : Valueify(const JSClass *c)
         398                 : {
         399                 :     return (const Class *)c;
         400                 : }
         401                 :
         402                 : /*
         403                 :  * Enumeration describing possible values of the [[Class]] internal property
         404                 :  * value of objects.
         405                 :  */
         406                 : enum ESClassValue {
         407                 :     ESClass_Array, ESClass_Number, ESClass_String, ESClass_Boolean, ESClass_RegExp
         408                 : };
         409                 :
         410                 : /*
         411                 :  * Return whether the given object has the given [[Class]] internal property
         412                 :  * value. Beware, this query says nothing about the js::Class of the JSObject
         413                 :  * so the caller must not assume anything about obj's representation (e.g., obj
         414                 :  * may be a proxy).
         415                 :  */
         416                 : inline bool
         417                 : ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx);
         418                 :
         419                 : /* Just a helper that checks v.isObject before calling ObjectClassIs. */
         420                 : inline bool
         421                 : IsObjectWithClass(const Value &v, ESClassValue classValue, JSContext *cx);
         422                 :
         423                 : }  /* namespace js */
         424                 :
         425                 : #endif  /* __cplusplus */
         426                 :
         427                 : #endif  /* jsclass_h__ */

Generated by: LCOV version 1.7