| 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|---|
| 2 | * vim: set ts=8 sw=4 et tw=78: |
|---|
| 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 Mozilla Communicator client code, released |
|---|
| 18 | * March 31, 1998. |
|---|
| 19 | * |
|---|
| 20 | * The Initial Developer of the Original Code is |
|---|
| 21 | * Netscape Communications Corporation. |
|---|
| 22 | * Portions created by the Initial Developer are Copyright (C) 1998 |
|---|
| 23 | * the Initial Developer. All Rights Reserved. |
|---|
| 24 | * |
|---|
| 25 | * Contributor(s): |
|---|
| 26 | * |
|---|
| 27 | * Alternatively, the contents of this file may be used under the terms of |
|---|
| 28 | * either of the GNU General Public License Version 2 or later (the "GPL"), |
|---|
| 29 | * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
|---|
| 30 | * in which case the provisions of the GPL or the LGPL are applicable instead |
|---|
| 31 | * of those above. If you wish to allow use of your version of this file only |
|---|
| 32 | * under the terms of either the GPL or the LGPL, and not to allow others to |
|---|
| 33 | * use your version of this file under the terms of the MPL, indicate your |
|---|
| 34 | * decision by deleting the provisions above and replace them with the notice |
|---|
| 35 | * and other provisions required by the GPL or the LGPL. If you do not delete |
|---|
| 36 | * the provisions above, a recipient may use your version of this file under |
|---|
| 37 | * the terms of any one of the MPL, the GPL or the LGPL. |
|---|
| 38 | * |
|---|
| 39 | * ***** END LICENSE BLOCK ***** */ |
|---|
| 40 | |
|---|
| 41 | #ifndef jsobj_h___ |
|---|
| 42 | #define jsobj_h___ |
|---|
| 43 | /* |
|---|
| 44 | * JS object definitions. |
|---|
| 45 | * |
|---|
| 46 | * A JS object consists of a possibly-shared object descriptor containing |
|---|
| 47 | * ordered property names, called the map; and a dense vector of property |
|---|
| 48 | * values, called slots. The map/slot pointer pair is GC'ed, while the map |
|---|
| 49 | * is reference counted and the slot vector is malloc'ed. |
|---|
| 50 | */ |
|---|
| 51 | #include "jshash.h" /* Added by JSIFY */ |
|---|
| 52 | #include "jsprvtd.h" |
|---|
| 53 | #include "jspubtd.h" |
|---|
| 54 | |
|---|
| 55 | JS_BEGIN_EXTERN_C |
|---|
| 56 | |
|---|
| 57 | /* For detailed comments on these function pointer types, see jsprvtd.h. */ |
|---|
| 58 | struct JSObjectOps { |
|---|
| 59 | /* |
|---|
| 60 | * Custom shared object map for non-native objects. For native objects |
|---|
| 61 | * this should be null indicating, that JSObject.map is an instance of |
|---|
| 62 | * JSScope. |
|---|
| 63 | */ |
|---|
| 64 | const JSObjectMap *objectMap; |
|---|
| 65 | |
|---|
| 66 | /* Mandatory non-null function pointer members. */ |
|---|
| 67 | JSLookupPropOp lookupProperty; |
|---|
| 68 | JSDefinePropOp defineProperty; |
|---|
| 69 | JSPropertyIdOp getProperty; |
|---|
| 70 | JSPropertyIdOp setProperty; |
|---|
| 71 | JSAttributesOp getAttributes; |
|---|
| 72 | JSAttributesOp setAttributes; |
|---|
| 73 | JSPropertyIdOp deleteProperty; |
|---|
| 74 | JSConvertOp defaultValue; |
|---|
| 75 | JSNewEnumerateOp enumerate; |
|---|
| 76 | JSCheckAccessIdOp checkAccess; |
|---|
| 77 | |
|---|
| 78 | /* Optionally non-null members start here. */ |
|---|
| 79 | JSObjectOp thisObject; |
|---|
| 80 | JSPropertyRefOp dropProperty; |
|---|
| 81 | JSNative call; |
|---|
| 82 | JSNative construct; |
|---|
| 83 | JSHasInstanceOp hasInstance; |
|---|
| 84 | JSTraceOp trace; |
|---|
| 85 | JSFinalizeOp clear; |
|---|
| 86 | JSGetRequiredSlotOp getRequiredSlot; |
|---|
| 87 | JSSetRequiredSlotOp setRequiredSlot; |
|---|
| 88 | }; |
|---|
| 89 | |
|---|
| 90 | struct JSObjectMap { |
|---|
| 91 | JSObjectOps *ops; /* high level object operation vtable */ |
|---|
| 92 | }; |
|---|
| 93 | |
|---|
| 94 | /* Shorthand macros for frequently-made calls. */ |
|---|
| 95 | #define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ |
|---|
| 96 | (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp) |
|---|
| 97 | #define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \ |
|---|
| 98 | (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp) |
|---|
| 99 | #define OBJ_GET_PROPERTY(cx,obj,id,vp) \ |
|---|
| 100 | (obj)->map->ops->getProperty(cx,obj,id,vp) |
|---|
| 101 | #define OBJ_SET_PROPERTY(cx,obj,id,vp) \ |
|---|
| 102 | (obj)->map->ops->setProperty(cx,obj,id,vp) |
|---|
| 103 | #define OBJ_GET_ATTRIBUTES(cx,obj,id,prop,attrsp) \ |
|---|
| 104 | (obj)->map->ops->getAttributes(cx,obj,id,prop,attrsp) |
|---|
| 105 | #define OBJ_SET_ATTRIBUTES(cx,obj,id,prop,attrsp) \ |
|---|
| 106 | (obj)->map->ops->setAttributes(cx,obj,id,prop,attrsp) |
|---|
| 107 | #define OBJ_DELETE_PROPERTY(cx,obj,id,rval) \ |
|---|
| 108 | (obj)->map->ops->deleteProperty(cx,obj,id,rval) |
|---|
| 109 | #define OBJ_DEFAULT_VALUE(cx,obj,hint,vp) \ |
|---|
| 110 | (obj)->map->ops->defaultValue(cx,obj,hint,vp) |
|---|
| 111 | #define OBJ_ENUMERATE(cx,obj,enum_op,statep,idp) \ |
|---|
| 112 | (obj)->map->ops->enumerate(cx,obj,enum_op,statep,idp) |
|---|
| 113 | #define OBJ_CHECK_ACCESS(cx,obj,id,mode,vp,attrsp) \ |
|---|
| 114 | (obj)->map->ops->checkAccess(cx,obj,id,mode,vp,attrsp) |
|---|
| 115 | |
|---|
| 116 | /* These four are time-optimized to avoid stub calls. */ |
|---|
| 117 | #define OBJ_THIS_OBJECT(cx,obj) \ |
|---|
| 118 | ((obj)->map->ops->thisObject \ |
|---|
| 119 | ? (obj)->map->ops->thisObject(cx,obj) \ |
|---|
| 120 | : (obj)) |
|---|
| 121 | #define OBJ_DROP_PROPERTY(cx,obj,prop) \ |
|---|
| 122 | ((obj)->map->ops->dropProperty \ |
|---|
| 123 | ? (obj)->map->ops->dropProperty(cx,obj,prop) \ |
|---|
| 124 | : (void)0) |
|---|
| 125 | #define OBJ_GET_REQUIRED_SLOT(cx,obj,slot) \ |
|---|
| 126 | ((obj)->map->ops->getRequiredSlot \ |
|---|
| 127 | ? (obj)->map->ops->getRequiredSlot(cx, obj, slot) \ |
|---|
| 128 | : JSVAL_VOID) |
|---|
| 129 | #define OBJ_SET_REQUIRED_SLOT(cx,obj,slot,v) \ |
|---|
| 130 | ((obj)->map->ops->setRequiredSlot \ |
|---|
| 131 | ? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v) \ |
|---|
| 132 | : JS_TRUE) |
|---|
| 133 | |
|---|
| 134 | #define OBJ_TO_INNER_OBJECT(cx,obj) \ |
|---|
| 135 | JS_BEGIN_MACRO \ |
|---|
| 136 | JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ |
|---|
| 137 | if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ |
|---|
| 138 | JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \ |
|---|
| 139 | if (xclasp_->innerObject) \ |
|---|
| 140 | obj = xclasp_->innerObject(cx, obj); \ |
|---|
| 141 | } \ |
|---|
| 142 | JS_END_MACRO |
|---|
| 143 | |
|---|
| 144 | #define OBJ_TO_OUTER_OBJECT(cx,obj) \ |
|---|
| 145 | JS_BEGIN_MACRO \ |
|---|
| 146 | JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ |
|---|
| 147 | if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ |
|---|
| 148 | JSExtendedClass *xclasp_ = (JSExtendedClass*)clasp_; \ |
|---|
| 149 | if (xclasp_->outerObject) \ |
|---|
| 150 | obj = xclasp_->outerObject(cx, obj); \ |
|---|
| 151 | } \ |
|---|
| 152 | JS_END_MACRO |
|---|
| 153 | |
|---|
| 154 | #define JS_INITIAL_NSLOTS 5 |
|---|
| 155 | |
|---|
| 156 | /* |
|---|
| 157 | * JSObject struct, with members sized to fit in 32 bytes on 32-bit targets, |
|---|
| 158 | * 64 bytes on 64-bit systems. The JSFunction struct is an extension of this |
|---|
| 159 | * struct allocated from a larger GC size-class. |
|---|
| 160 | * |
|---|
| 161 | * The classword member stores the JSClass pointer for this object, with the |
|---|
| 162 | * least two bits encoding whether this object is a "delegate" or a "system" |
|---|
| 163 | * object. |
|---|
| 164 | * |
|---|
| 165 | * An object is a delegate if it is on another object's prototype (linked by |
|---|
| 166 | * JSSLOT_PROTO) or scope (JSSLOT_PARENT) chain, and therefore the delegate |
|---|
| 167 | * might be asked implicitly to get or set a property on behalf of another |
|---|
| 168 | * object. Delegates may be accessed directly too, as may any object, but only |
|---|
| 169 | * those objects linked after the head of any prototype or scope chain are |
|---|
| 170 | * flagged as delegates. This definition helps to optimize shape-based property |
|---|
| 171 | * cache invalidation (see Purge{Scope,Proto}Chain in jsobj.cpp). |
|---|
| 172 | * |
|---|
| 173 | * The meaning of the system object bit is defined by the API client. It is |
|---|
| 174 | * set in JS_NewSystemObject and is queried by JS_IsSystemObject (jsdbgapi.h), |
|---|
| 175 | * but it has no intrinsic meaning to SpiderMonkey. Further, JSFILENAME_SYSTEM |
|---|
| 176 | * and JS_FlagScriptFilenamePrefix (also exported via jsdbgapi.h) are intended |
|---|
| 177 | * to be complementary to this bit, but it is up to the API client to implement |
|---|
| 178 | * any such association. |
|---|
| 179 | * |
|---|
| 180 | * Both these classword tag bits are initially zero; they may be set or queried |
|---|
| 181 | * using the STOBJ_(IS|SET)_(DELEGATE|SYSTEM) macros. |
|---|
| 182 | * |
|---|
| 183 | * The dslots member is null or a pointer into a dynamically allocated vector |
|---|
| 184 | * of jsvals for reserved and dynamic slots. If dslots is not null, dslots[-1] |
|---|
| 185 | * records the number of available slots. |
|---|
| 186 | */ |
|---|
| 187 | struct JSObject { |
|---|
| 188 | JSObjectMap *map; /* propery map, see jsscope.h */ |
|---|
| 189 | jsuword classword; /* classword, see above */ |
|---|
| 190 | jsval fslots[JS_INITIAL_NSLOTS]; /* small number of fixed slots */ |
|---|
| 191 | jsval *dslots; /* dynamically allocated slots */ |
|---|
| 192 | }; |
|---|
| 193 | |
|---|
| 194 | #define JSSLOT_PROTO 0 |
|---|
| 195 | #define JSSLOT_PARENT 1 |
|---|
| 196 | #define JSSLOT_PRIVATE 2 |
|---|
| 197 | #define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \ |
|---|
| 198 | ? JSSLOT_PRIVATE + 1 \ |
|---|
| 199 | : JSSLOT_PARENT + 1) |
|---|
| 200 | |
|---|
| 201 | #define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \ |
|---|
| 202 | + JSCLASS_RESERVED_SLOTS(clasp)) |
|---|
| 203 | |
|---|
| 204 | /* |
|---|
| 205 | * Maximum net gross capacity of the obj->dslots vector, excluding the additional |
|---|
| 206 | * hidden slot used to store the length of the vector. |
|---|
| 207 | */ |
|---|
| 208 | #define MAX_DSLOTS_LENGTH (JS_MAX(~(uint32)0, ~(size_t)0) / sizeof(jsval)) |
|---|
| 209 | |
|---|
| 210 | /* |
|---|
| 211 | * STOBJ prefix means Single Threaded Object. Use the following fast macros to |
|---|
| 212 | * directly manipulate slots in obj when only one thread can access obj, or |
|---|
| 213 | * when accessing read-only slots within JS_INITIAL_NSLOTS. |
|---|
| 214 | */ |
|---|
| 215 | |
|---|
| 216 | #define STOBJ_NSLOTS(obj) \ |
|---|
| 217 | ((obj)->dslots ? (uint32)(obj)->dslots[-1] : (uint32)JS_INITIAL_NSLOTS) |
|---|
| 218 | |
|---|
| 219 | #define STOBJ_GET_SLOT(obj,slot) \ |
|---|
| 220 | ((slot) < JS_INITIAL_NSLOTS \ |
|---|
| 221 | ? (obj)->fslots[(slot)] \ |
|---|
| 222 | : (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]), \ |
|---|
| 223 | (obj)->dslots[(slot) - JS_INITIAL_NSLOTS])) |
|---|
| 224 | |
|---|
| 225 | #define STOBJ_SET_SLOT(obj,slot,value) \ |
|---|
| 226 | ((slot) < JS_INITIAL_NSLOTS \ |
|---|
| 227 | ? (obj)->fslots[(slot)] = (value) \ |
|---|
| 228 | : (JS_ASSERT((slot) < (uint32)(obj)->dslots[-1]), \ |
|---|
| 229 | (obj)->dslots[(slot) - JS_INITIAL_NSLOTS] = (value))) |
|---|
| 230 | |
|---|
| 231 | #define STOBJ_GET_PROTO(obj) \ |
|---|
| 232 | JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PROTO]) |
|---|
| 233 | #define STOBJ_SET_PROTO(obj,proto) \ |
|---|
| 234 | (void)(STOBJ_NULLSAFE_SET_DELEGATE(proto), \ |
|---|
| 235 | (obj)->fslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto)) |
|---|
| 236 | #define STOBJ_CLEAR_PROTO(obj) \ |
|---|
| 237 | ((obj)->fslots[JSSLOT_PROTO] = JSVAL_NULL) |
|---|
| 238 | |
|---|
| 239 | #define STOBJ_GET_PARENT(obj) \ |
|---|
| 240 | JSVAL_TO_OBJECT((obj)->fslots[JSSLOT_PARENT]) |
|---|
| 241 | #define STOBJ_SET_PARENT(obj,parent) \ |
|---|
| 242 | (void)(STOBJ_NULLSAFE_SET_DELEGATE(parent), \ |
|---|
| 243 | (obj)->fslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent)) |
|---|
| 244 | #define STOBJ_CLEAR_PARENT(obj) \ |
|---|
| 245 | ((obj)->fslots[JSSLOT_PARENT] = JSVAL_NULL) |
|---|
| 246 | |
|---|
| 247 | /* |
|---|
| 248 | * We use JSObject.classword to store both JSClass* and the delegate and system |
|---|
| 249 | * flags in the two least significant bits. We do *not* synchronize updates of |
|---|
| 250 | * obj->classword -- API clients must take care. |
|---|
| 251 | */ |
|---|
| 252 | #define JSSLOT_CLASS_MASK_BITS 3 |
|---|
| 253 | |
|---|
| 254 | static JS_ALWAYS_INLINE JSClass* |
|---|
| 255 | STOBJ_GET_CLASS(const JSObject* obj) |
|---|
| 256 | { |
|---|
| 257 | return (JSClass *) (obj->classword & ~JSSLOT_CLASS_MASK_BITS); |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | #define STOBJ_IS_DELEGATE(obj) (((obj)->classword & 1) != 0) |
|---|
| 261 | #define STOBJ_SET_DELEGATE(obj) ((obj)->classword |= 1) |
|---|
| 262 | #define STOBJ_NULLSAFE_SET_DELEGATE(obj) \ |
|---|
| 263 | (!(obj) || STOBJ_SET_DELEGATE((JSObject*)obj)) |
|---|
| 264 | #define STOBJ_IS_SYSTEM(obj) (((obj)->classword & 2) != 0) |
|---|
| 265 | #define STOBJ_SET_SYSTEM(obj) ((obj)->classword |= 2) |
|---|
| 266 | |
|---|
| 267 | #define STOBJ_GET_PRIVATE(obj) \ |
|---|
| 268 | (JS_ASSERT(JSVAL_IS_INT(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))), \ |
|---|
| 269 | JSVAL_TO_PRIVATE(STOBJ_GET_SLOT(obj, JSSLOT_PRIVATE))) |
|---|
| 270 | |
|---|
| 271 | #define OBJ_CHECK_SLOT(obj,slot) \ |
|---|
| 272 | JS_ASSERT_IF(OBJ_IS_NATIVE(obj), slot < OBJ_SCOPE(obj)->freeslot) |
|---|
| 273 | |
|---|
| 274 | #define LOCKED_OBJ_GET_SLOT(obj,slot) \ |
|---|
| 275 | (OBJ_CHECK_SLOT(obj, slot), STOBJ_GET_SLOT(obj, slot)) |
|---|
| 276 | #define LOCKED_OBJ_SET_SLOT(obj,slot,value) \ |
|---|
| 277 | (OBJ_CHECK_SLOT(obj, slot), STOBJ_SET_SLOT(obj, slot, value)) |
|---|
| 278 | |
|---|
| 279 | /* |
|---|
| 280 | * NB: Don't call LOCKED_OBJ_SET_SLOT or STOBJ_SET_SLOT for a write to a slot |
|---|
| 281 | * that may contain a function reference already, or where the new value is a |
|---|
| 282 | * function ref, and the object's scope may be branded with a property cache |
|---|
| 283 | * structural type capability that distinguishes versions of the object with |
|---|
| 284 | * and without the function property. Instead use LOCKED_OBJ_WRITE_BARRIER or |
|---|
| 285 | * a fast inline equivalent (JSOP_SETNAME/JSOP_SETPROP cases in jsinterp.c). |
|---|
| 286 | */ |
|---|
| 287 | #define LOCKED_OBJ_WRITE_BARRIER(cx,obj,slot,newval) \ |
|---|
| 288 | JS_BEGIN_MACRO \ |
|---|
| 289 | JSScope *scope_ = OBJ_SCOPE(obj); \ |
|---|
| 290 | JS_ASSERT(scope_->object == (obj)); \ |
|---|
| 291 | GC_WRITE_BARRIER(cx, scope_, LOCKED_OBJ_GET_SLOT(obj, slot), newval); \ |
|---|
| 292 | LOCKED_OBJ_SET_SLOT(obj, slot, newval); \ |
|---|
| 293 | JS_END_MACRO |
|---|
| 294 | |
|---|
| 295 | #define LOCKED_OBJ_GET_PROTO(obj) \ |
|---|
| 296 | (OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_GET_PROTO(obj)) |
|---|
| 297 | #define LOCKED_OBJ_SET_PROTO(obj,proto) \ |
|---|
| 298 | (OBJ_CHECK_SLOT(obj, JSSLOT_PROTO), STOBJ_SET_PROTO(obj, proto)) |
|---|
| 299 | |
|---|
| 300 | #define LOCKED_OBJ_GET_PARENT(obj) \ |
|---|
| 301 | (OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_GET_PARENT(obj)) |
|---|
| 302 | #define LOCKED_OBJ_SET_PARENT(obj,parent) \ |
|---|
| 303 | (OBJ_CHECK_SLOT(obj, JSSLOT_PARENT), STOBJ_SET_PARENT(obj, parent)) |
|---|
| 304 | |
|---|
| 305 | #define LOCKED_OBJ_GET_CLASS(obj) \ |
|---|
| 306 | STOBJ_GET_CLASS(obj) |
|---|
| 307 | |
|---|
| 308 | #define LOCKED_OBJ_GET_PRIVATE(obj) \ |
|---|
| 309 | (OBJ_CHECK_SLOT(obj, JSSLOT_PRIVATE), STOBJ_GET_PRIVATE(obj)) |
|---|
| 310 | |
|---|
| 311 | #ifdef JS_THREADSAFE |
|---|
| 312 | |
|---|
| 313 | /* Thread-safe functions and wrapper macros for accessing slots in obj. */ |
|---|
| 314 | #define OBJ_GET_SLOT(cx,obj,slot) \ |
|---|
| 315 | (OBJ_CHECK_SLOT(obj, slot), \ |
|---|
| 316 | (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->title.ownercx == cx) \ |
|---|
| 317 | ? LOCKED_OBJ_GET_SLOT(obj, slot) \ |
|---|
| 318 | : js_GetSlotThreadSafe(cx, obj, slot)) |
|---|
| 319 | |
|---|
| 320 | #define OBJ_SET_SLOT(cx,obj,slot,value) \ |
|---|
| 321 | JS_BEGIN_MACRO \ |
|---|
| 322 | OBJ_CHECK_SLOT(obj, slot); \ |
|---|
| 323 | if (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->title.ownercx == cx) \ |
|---|
| 324 | LOCKED_OBJ_WRITE_BARRIER(cx, obj, slot, value); \ |
|---|
| 325 | else \ |
|---|
| 326 | js_SetSlotThreadSafe(cx, obj, slot, value); \ |
|---|
| 327 | JS_END_MACRO |
|---|
| 328 | |
|---|
| 329 | /* |
|---|
| 330 | * If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a native |
|---|
| 331 | * object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx), |
|---|
| 332 | * to avoid needlessly switching from lock-free to lock-full scope when doing |
|---|
| 333 | * GC on a different context from the last one to own the scope. The caller |
|---|
| 334 | * in this case is probably a JSClass.mark function, e.g., fun_mark, or maybe |
|---|
| 335 | * a finalizer. |
|---|
| 336 | * |
|---|
| 337 | * The GC runs only when all threads except the one on which the GC is active |
|---|
| 338 | * are suspended at GC-safe points, so calling STOBJ_GET_SLOT from the GC's |
|---|
| 339 | * thread is safe when rt->gcRunning is set. See jsgc.c for details. |
|---|
| 340 | */ |
|---|
| 341 | #define THREAD_IS_RUNNING_GC(rt, thread) \ |
|---|
| 342 | ((rt)->gcRunning && (rt)->gcThread == (thread)) |
|---|
| 343 | |
|---|
| 344 | #define CX_THREAD_IS_RUNNING_GC(cx) \ |
|---|
| 345 | THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread) |
|---|
| 346 | |
|---|
| 347 | #else /* !JS_THREADSAFE */ |
|---|
| 348 | |
|---|
| 349 | #define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) |
|---|
| 350 | #define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_WRITE_BARRIER(cx,obj,slot, \ |
|---|
| 351 | value) |
|---|
| 352 | |
|---|
| 353 | #endif /* !JS_THREADSAFE */ |
|---|
| 354 | |
|---|
| 355 | /* Thread-safe delegate, proto, parent, and class access macros. */ |
|---|
| 356 | #define OBJ_IS_DELEGATE(cx,obj) STOBJ_IS_DELEGATE(obj) |
|---|
| 357 | #define OBJ_SET_DELEGATE(cx,obj) STOBJ_SET_DELEGATE(obj) |
|---|
| 358 | |
|---|
| 359 | #define OBJ_GET_PROTO(cx,obj) STOBJ_GET_PROTO(obj) |
|---|
| 360 | #define OBJ_SET_PROTO(cx,obj,proto) STOBJ_SET_PROTO(obj, proto) |
|---|
| 361 | #define OBJ_CLEAR_PROTO(cx,obj) STOBJ_CLEAR_PROTO(obj) |
|---|
| 362 | |
|---|
| 363 | #define OBJ_GET_PARENT(cx,obj) STOBJ_GET_PARENT(obj) |
|---|
| 364 | #define OBJ_SET_PARENT(cx,obj,parent) STOBJ_SET_PARENT(obj, parent) |
|---|
| 365 | #define OBJ_CLEAR_PARENT(cx,obj) STOBJ_CLEAR_PARENT(obj) |
|---|
| 366 | |
|---|
| 367 | /* |
|---|
| 368 | * Class is invariant and comes from the fixed clasp member. Thus no locking |
|---|
| 369 | * is necessary to read it. Same for the private slot. |
|---|
| 370 | */ |
|---|
| 371 | #define OBJ_GET_CLASS(cx,obj) STOBJ_GET_CLASS(obj) |
|---|
| 372 | #define OBJ_GET_PRIVATE(cx,obj) STOBJ_GET_PRIVATE(obj) |
|---|
| 373 | |
|---|
| 374 | /* |
|---|
| 375 | * Test whether the object is native. FIXME bug 492938: consider how it would |
|---|
| 376 | * affect the performance to do just the !ops->objectMap check. |
|---|
| 377 | */ |
|---|
| 378 | #define OPS_IS_NATIVE(ops) \ |
|---|
| 379 | JS_LIKELY((ops) == &js_ObjectOps || !(ops)->objectMap) |
|---|
| 380 | |
|---|
| 381 | #define OBJ_IS_NATIVE(obj) OPS_IS_NATIVE((obj)->map->ops) |
|---|
| 382 | |
|---|
| 383 | extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; |
|---|
| 384 | extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; |
|---|
| 385 | extern JSClass js_ObjectClass; |
|---|
| 386 | extern JSClass js_WithClass; |
|---|
| 387 | extern JSClass js_BlockClass; |
|---|
| 388 | |
|---|
| 389 | /* |
|---|
| 390 | * Block scope object macros. The slots reserved by js_BlockClass are: |
|---|
| 391 | * |
|---|
| 392 | * JSSLOT_PRIVATE JSStackFrame * active frame pointer or null |
|---|
| 393 | * JSSLOT_BLOCK_DEPTH int depth of block slots in frame |
|---|
| 394 | * |
|---|
| 395 | * After JSSLOT_BLOCK_DEPTH come one or more slots for the block locals. |
|---|
| 396 | * |
|---|
| 397 | * A With object is like a Block object, in that both have one reserved slot |
|---|
| 398 | * telling the stack depth of the relevant slots (the slot whose value is the |
|---|
| 399 | * object named in the with statement, the slots containing the block's local |
|---|
| 400 | * variables); and both have a private slot referring to the JSStackFrame in |
|---|
| 401 | * whose activation they were created (or null if the with or block object |
|---|
| 402 | * outlives the frame). |
|---|
| 403 | */ |
|---|
| 404 | #define JSSLOT_BLOCK_DEPTH (JSSLOT_PRIVATE + 1) |
|---|
| 405 | |
|---|
| 406 | #define OBJ_IS_CLONED_BLOCK(obj) \ |
|---|
| 407 | (OBJ_SCOPE(obj)->object != (obj)) |
|---|
| 408 | #define OBJ_BLOCK_COUNT(cx,obj) \ |
|---|
| 409 | (OBJ_SCOPE(obj)->entryCount) |
|---|
| 410 | #define OBJ_BLOCK_DEPTH(cx,obj) \ |
|---|
| 411 | JSVAL_TO_INT(STOBJ_GET_SLOT(obj, JSSLOT_BLOCK_DEPTH)) |
|---|
| 412 | #define OBJ_SET_BLOCK_DEPTH(cx,obj,depth) \ |
|---|
| 413 | STOBJ_SET_SLOT(obj, JSSLOT_BLOCK_DEPTH, INT_TO_JSVAL(depth)) |
|---|
| 414 | |
|---|
| 415 | /* |
|---|
| 416 | * To make sure this slot is well-defined, always call js_NewWithObject to |
|---|
| 417 | * create a With object, don't call js_NewObject directly. When creating a |
|---|
| 418 | * With object that does not correspond to a stack slot, pass -1 for depth. |
|---|
| 419 | * |
|---|
| 420 | * When popping the stack across this object's "with" statement, client code |
|---|
| 421 | * must call JS_SetPrivate(cx, withobj, NULL). |
|---|
| 422 | */ |
|---|
| 423 | extern JS_REQUIRES_STACK JSObject * |
|---|
| 424 | js_NewWithObject(JSContext *cx, JSObject *proto, JSObject *parent, jsint depth); |
|---|
| 425 | |
|---|
| 426 | /* |
|---|
| 427 | * Create a new block scope object not linked to any proto or parent object. |
|---|
| 428 | * Blocks are created by the compiler to reify let blocks and comprehensions. |
|---|
| 429 | * Only when dynamic scope is captured do they need to be cloned and spliced |
|---|
| 430 | * into an active scope chain. |
|---|
| 431 | */ |
|---|
| 432 | extern JSObject * |
|---|
| 433 | js_NewBlockObject(JSContext *cx); |
|---|
| 434 | |
|---|
| 435 | extern JSObject * |
|---|
| 436 | js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent, |
|---|
| 437 | JSStackFrame *fp); |
|---|
| 438 | |
|---|
| 439 | extern JS_REQUIRES_STACK JSBool |
|---|
| 440 | js_PutBlockObject(JSContext *cx, JSBool normalUnwind); |
|---|
| 441 | |
|---|
| 442 | JSBool |
|---|
| 443 | js_XDRBlockObject(JSXDRState *xdr, JSObject **objp); |
|---|
| 444 | |
|---|
| 445 | struct JSSharpObjectMap { |
|---|
| 446 | jsrefcount depth; |
|---|
| 447 | jsatomid sharpgen; |
|---|
| 448 | JSHashTable *table; |
|---|
| 449 | }; |
|---|
| 450 | |
|---|
| 451 | #define SHARP_BIT ((jsatomid) 1) |
|---|
| 452 | #define BUSY_BIT ((jsatomid) 2) |
|---|
| 453 | #define SHARP_ID_SHIFT 2 |
|---|
| 454 | #define IS_SHARP(he) (JS_PTR_TO_UINT32((he)->value) & SHARP_BIT) |
|---|
| 455 | #define MAKE_SHARP(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|SHARP_BIT)) |
|---|
| 456 | #define IS_BUSY(he) (JS_PTR_TO_UINT32((he)->value) & BUSY_BIT) |
|---|
| 457 | #define MAKE_BUSY(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)|BUSY_BIT)) |
|---|
| 458 | #define CLEAR_BUSY(he) ((he)->value = JS_UINT32_TO_PTR(JS_PTR_TO_UINT32((he)->value)&~BUSY_BIT)) |
|---|
| 459 | |
|---|
| 460 | extern JSHashEntry * |
|---|
| 461 | js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, |
|---|
| 462 | jschar **sp); |
|---|
| 463 | |
|---|
| 464 | extern void |
|---|
| 465 | js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); |
|---|
| 466 | |
|---|
| 467 | /* |
|---|
| 468 | * Mark objects stored in map if GC happens between js_EnterSharpObject |
|---|
| 469 | * and js_LeaveSharpObject. GC calls this when map->depth > 0. |
|---|
| 470 | */ |
|---|
| 471 | extern void |
|---|
| 472 | js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map); |
|---|
| 473 | |
|---|
| 474 | extern JSBool |
|---|
| 475 | js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, uintN argc, |
|---|
| 476 | jsval *vp); |
|---|
| 477 | |
|---|
| 478 | extern JSBool |
|---|
| 479 | js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id, |
|---|
| 480 | jsval *vp); |
|---|
| 481 | |
|---|
| 482 | extern JSBool |
|---|
| 483 | js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, jsval *vp); |
|---|
| 484 | |
|---|
| 485 | #if JS_HAS_GETTER_SETTER |
|---|
| 486 | JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, jsval *vp); |
|---|
| 487 | JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, jsval *vp); |
|---|
| 488 | #endif |
|---|
| 489 | |
|---|
| 490 | extern JSObject * |
|---|
| 491 | js_InitEval(JSContext *cx, JSObject *obj); |
|---|
| 492 | |
|---|
| 493 | extern JSObject * |
|---|
| 494 | js_InitObjectClass(JSContext *cx, JSObject *obj); |
|---|
| 495 | |
|---|
| 496 | extern JSObject * |
|---|
| 497 | js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, |
|---|
| 498 | JSClass *clasp, JSNative constructor, uintN nargs, |
|---|
| 499 | JSPropertySpec *ps, JSFunctionSpec *fs, |
|---|
| 500 | JSPropertySpec *static_ps, JSFunctionSpec *static_fs); |
|---|
| 501 | |
|---|
| 502 | /* |
|---|
| 503 | * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp. |
|---|
| 504 | */ |
|---|
| 505 | extern const char js_watch_str[]; |
|---|
| 506 | extern const char js_unwatch_str[]; |
|---|
| 507 | extern const char js_hasOwnProperty_str[]; |
|---|
| 508 | extern const char js_isPrototypeOf_str[]; |
|---|
| 509 | extern const char js_propertyIsEnumerable_str[]; |
|---|
| 510 | extern const char js_defineGetter_str[]; |
|---|
| 511 | extern const char js_defineSetter_str[]; |
|---|
| 512 | extern const char js_lookupGetter_str[]; |
|---|
| 513 | extern const char js_lookupSetter_str[]; |
|---|
| 514 | |
|---|
| 515 | extern JSBool |
|---|
| 516 | js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp); |
|---|
| 517 | |
|---|
| 518 | extern JSObject * |
|---|
| 519 | js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent, |
|---|
| 520 | uintN objectSize); |
|---|
| 521 | |
|---|
| 522 | /* |
|---|
| 523 | * See jsapi.h, JS_NewObjectWithGivenProto. |
|---|
| 524 | * |
|---|
| 525 | * objectSize is either the explicit size for the allocated object or 0 |
|---|
| 526 | * indicating to use the default size based on object's class. |
|---|
| 527 | */ |
|---|
| 528 | extern JSObject * |
|---|
| 529 | js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto, |
|---|
| 530 | JSObject *parent, uintN objectSize); |
|---|
| 531 | |
|---|
| 532 | /* |
|---|
| 533 | * Allocate a new native object and initialize all fslots with JSVAL_VOID |
|---|
| 534 | * starting with the specified slot. The parent slot is set to the value of |
|---|
| 535 | * proto's parent slot. |
|---|
| 536 | * |
|---|
| 537 | * Note that this is the correct global object for native class instances, but |
|---|
| 538 | * not for user-defined functions called as constructors. Functions used as |
|---|
| 539 | * constructors must create instances parented by the parent of the function |
|---|
| 540 | * object, not by the parent of its .prototype object value. |
|---|
| 541 | */ |
|---|
| 542 | extern JSObject* |
|---|
| 543 | js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot); |
|---|
| 544 | |
|---|
| 545 | /* |
|---|
| 546 | * Fast access to immutable standard objects (constructors and prototypes). |
|---|
| 547 | */ |
|---|
| 548 | extern JSBool |
|---|
| 549 | js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, |
|---|
| 550 | JSObject **objp); |
|---|
| 551 | |
|---|
| 552 | extern JSBool |
|---|
| 553 | js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj); |
|---|
| 554 | |
|---|
| 555 | extern JSBool |
|---|
| 556 | js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp); |
|---|
| 557 | |
|---|
| 558 | extern JSObject * |
|---|
| 559 | js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, |
|---|
| 560 | JSObject *parent, uintN argc, jsval *argv); |
|---|
| 561 | |
|---|
| 562 | extern void |
|---|
| 563 | js_FinalizeObject(JSContext *cx, JSObject *obj); |
|---|
| 564 | |
|---|
| 565 | extern JSBool |
|---|
| 566 | js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp); |
|---|
| 567 | |
|---|
| 568 | extern void |
|---|
| 569 | js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot); |
|---|
| 570 | |
|---|
| 571 | /* JSVAL_INT_MAX as a string */ |
|---|
| 572 | #define JSVAL_INT_MAX_STRING "1073741823" |
|---|
| 573 | |
|---|
| 574 | /* |
|---|
| 575 | * Convert string indexes that convert to int jsvals as ints to save memory. |
|---|
| 576 | * Care must be taken to use this macro every time a property name is used, or |
|---|
| 577 | * else double-sets, incorrect property cache misses, or other mistakes could |
|---|
| 578 | * occur. |
|---|
| 579 | */ |
|---|
| 580 | #define CHECK_FOR_STRING_INDEX(id) \ |
|---|
| 581 | JS_BEGIN_MACRO \ |
|---|
| 582 | if (JSID_IS_ATOM(id)) { \ |
|---|
| 583 | JSAtom *atom_ = JSID_TO_ATOM(id); \ |
|---|
| 584 | JSString *str_ = ATOM_TO_STRING(atom_); \ |
|---|
| 585 | const jschar *s_ = JSFLATSTR_CHARS(str_); \ |
|---|
| 586 | JSBool negative_ = (*s_ == '-'); \ |
|---|
| 587 | if (negative_) s_++; \ |
|---|
| 588 | if (JS7_ISDEC(*s_)) { \ |
|---|
| 589 | size_t n_ = JSFLATSTR_LENGTH(str_) - negative_; \ |
|---|
| 590 | if (n_ <= sizeof(JSVAL_INT_MAX_STRING) - 1) \ |
|---|
| 591 | id = js_CheckForStringIndex(id, s_, s_ + n_, negative_); \ |
|---|
| 592 | } \ |
|---|
| 593 | } \ |
|---|
| 594 | JS_END_MACRO |
|---|
| 595 | |
|---|
| 596 | extern jsid |
|---|
| 597 | js_CheckForStringIndex(jsid id, const jschar *cp, const jschar *end, |
|---|
| 598 | JSBool negative); |
|---|
| 599 | |
|---|
| 600 | /* |
|---|
| 601 | * js_PurgeScopeChain does nothing if obj is not itself a prototype or parent |
|---|
| 602 | * scope, else it reshapes the scope and prototype chains it links. It calls |
|---|
| 603 | * js_PurgeScopeChainHelper, which asserts that obj is flagged as a delegate |
|---|
| 604 | * (i.e., obj has ever been on a prototype or parent chain). |
|---|
| 605 | */ |
|---|
| 606 | extern void |
|---|
| 607 | js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id); |
|---|
| 608 | |
|---|
| 609 | #ifdef __cplusplus /* Aargh, libgjs, bug 492720. */ |
|---|
| 610 | static JS_INLINE void |
|---|
| 611 | js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id) |
|---|
| 612 | { |
|---|
| 613 | if (OBJ_IS_DELEGATE(cx, obj)) |
|---|
| 614 | js_PurgeScopeChainHelper(cx, obj, id); |
|---|
| 615 | } |
|---|
| 616 | #endif |
|---|
| 617 | |
|---|
| 618 | /* |
|---|
| 619 | * Find or create a property named by id in obj's scope, with the given getter |
|---|
| 620 | * and setter, slot, attributes, and other members. |
|---|
| 621 | */ |
|---|
| 622 | extern JSScopeProperty * |
|---|
| 623 | js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, |
|---|
| 624 | JSPropertyOp getter, JSPropertyOp setter, uint32 slot, |
|---|
| 625 | uintN attrs, uintN flags, intN shortid); |
|---|
| 626 | |
|---|
| 627 | /* |
|---|
| 628 | * Change sprop to have the given attrs, getter, and setter in scope, morphing |
|---|
| 629 | * it into a potentially new JSScopeProperty. Return a pointer to the changed |
|---|
| 630 | * or identical property. |
|---|
| 631 | */ |
|---|
| 632 | extern JSScopeProperty * |
|---|
| 633 | js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, |
|---|
| 634 | JSScopeProperty *sprop, uintN attrs, uintN mask, |
|---|
| 635 | JSPropertyOp getter, JSPropertyOp setter); |
|---|
| 636 | |
|---|
| 637 | /* |
|---|
| 638 | * On error, return false. On success, if propp is non-null, return true with |
|---|
| 639 | * obj locked and with a held property in *propp; if propp is null, return true |
|---|
| 640 | * but release obj's lock first. Therefore all callers who pass non-null propp |
|---|
| 641 | * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to |
|---|
| 642 | * drop the held property, and to release the lock on obj. |
|---|
| 643 | */ |
|---|
| 644 | extern JSBool |
|---|
| 645 | js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, |
|---|
| 646 | JSPropertyOp getter, JSPropertyOp setter, uintN attrs, |
|---|
| 647 | JSProperty **propp); |
|---|
| 648 | |
|---|
| 649 | #ifdef __cplusplus /* FIXME: bug 442399 removes this LiveConnect requirement. */ |
|---|
| 650 | |
|---|
| 651 | /* |
|---|
| 652 | * Flags for the defineHow parameter of js_DefineNativeProperty. |
|---|
| 653 | */ |
|---|
| 654 | const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */ |
|---|
| 655 | const uintN JSDNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */ |
|---|
| 656 | |
|---|
| 657 | extern JSBool |
|---|
| 658 | js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, |
|---|
| 659 | JSPropertyOp getter, JSPropertyOp setter, uintN attrs, |
|---|
| 660 | uintN flags, intN shortid, JSProperty **propp, |
|---|
| 661 | uintN defineHow = 0); |
|---|
| 662 | #endif |
|---|
| 663 | |
|---|
| 664 | /* |
|---|
| 665 | * Unlike js_DefineProperty, propp must be non-null. On success, and if id was |
|---|
| 666 | * found, return true with *objp non-null and locked, and with a held property |
|---|
| 667 | * stored in *propp. If successful but id was not found, return true with both |
|---|
| 668 | * *objp and *propp null. Therefore all callers who receive a non-null *propp |
|---|
| 669 | * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp). |
|---|
| 670 | */ |
|---|
| 671 | extern JS_FRIEND_API(JSBool) |
|---|
| 672 | js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, |
|---|
| 673 | JSProperty **propp); |
|---|
| 674 | |
|---|
| 675 | /* |
|---|
| 676 | * Specialized subroutine that allows caller to preset JSRESOLVE_* flags and |
|---|
| 677 | * returns the index along the prototype chain in which *propp was found, or |
|---|
| 678 | * the last index if not found, or -1 on error. |
|---|
| 679 | */ |
|---|
| 680 | extern int |
|---|
| 681 | js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags, |
|---|
| 682 | JSObject **objp, JSProperty **propp); |
|---|
| 683 | |
|---|
| 684 | /* |
|---|
| 685 | * If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success. |
|---|
| 686 | */ |
|---|
| 687 | extern JSPropCacheEntry * |
|---|
| 688 | js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult, |
|---|
| 689 | JSObject **objp, JSObject **pobjp, JSProperty **propp); |
|---|
| 690 | |
|---|
| 691 | /* |
|---|
| 692 | * Return the index along the scope chain in which id was found, or the last |
|---|
| 693 | * index if not found, or -1 on error. |
|---|
| 694 | */ |
|---|
| 695 | extern JS_FRIEND_API(JSBool) |
|---|
| 696 | js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, |
|---|
| 697 | JSProperty **propp); |
|---|
| 698 | |
|---|
| 699 | extern JS_REQUIRES_STACK JSObject * |
|---|
| 700 | js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id); |
|---|
| 701 | |
|---|
| 702 | extern JSObject * |
|---|
| 703 | js_FindVariableScope(JSContext *cx, JSFunction **funp); |
|---|
| 704 | |
|---|
| 705 | /* |
|---|
| 706 | * NB: js_NativeGet and js_NativeSet are called with the scope containing sprop |
|---|
| 707 | * (pobj's scope for Get, obj's for Set) locked, and on successful return, that |
|---|
| 708 | * scope is again locked. But on failure, both functions return false with the |
|---|
| 709 | * scope containing sprop unlocked. |
|---|
| 710 | */ |
|---|
| 711 | extern JSBool |
|---|
| 712 | js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj, |
|---|
| 713 | JSScopeProperty *sprop, jsval *vp); |
|---|
| 714 | |
|---|
| 715 | extern JSBool |
|---|
| 716 | js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp); |
|---|
| 717 | |
|---|
| 718 | extern JSBool |
|---|
| 719 | js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult, |
|---|
| 720 | jsval *vp); |
|---|
| 721 | |
|---|
| 722 | extern JSBool |
|---|
| 723 | js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); |
|---|
| 724 | |
|---|
| 725 | extern JSBool |
|---|
| 726 | js_GetMethod(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult, |
|---|
| 727 | jsval *vp); |
|---|
| 728 | |
|---|
| 729 | /* |
|---|
| 730 | * Check whether it is OK to assign an undeclared property of the global |
|---|
| 731 | * object at the current script PC. |
|---|
| 732 | */ |
|---|
| 733 | extern JS_FRIEND_API(JSBool) |
|---|
| 734 | js_CheckUndeclaredVarAssignment(JSContext *cx); |
|---|
| 735 | |
|---|
| 736 | extern JSBool |
|---|
| 737 | js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult, |
|---|
| 738 | jsval *vp); |
|---|
| 739 | |
|---|
| 740 | extern JSBool |
|---|
| 741 | js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); |
|---|
| 742 | |
|---|
| 743 | extern JSBool |
|---|
| 744 | js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, |
|---|
| 745 | uintN *attrsp); |
|---|
| 746 | |
|---|
| 747 | extern JSBool |
|---|
| 748 | js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, |
|---|
| 749 | uintN *attrsp); |
|---|
| 750 | |
|---|
| 751 | extern JSBool |
|---|
| 752 | js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval); |
|---|
| 753 | |
|---|
| 754 | extern JSBool |
|---|
| 755 | js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp); |
|---|
| 756 | |
|---|
| 757 | extern JSBool |
|---|
| 758 | js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, |
|---|
| 759 | jsval *statep, jsid *idp); |
|---|
| 760 | |
|---|
| 761 | extern void |
|---|
| 762 | js_TraceNativeEnumerators(JSTracer *trc); |
|---|
| 763 | |
|---|
| 764 | extern JSBool |
|---|
| 765 | js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, |
|---|
| 766 | jsval *vp, uintN *attrsp); |
|---|
| 767 | |
|---|
| 768 | extern JSBool |
|---|
| 769 | js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); |
|---|
| 770 | |
|---|
| 771 | extern JSBool |
|---|
| 772 | js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, |
|---|
| 773 | jsval *rval); |
|---|
| 774 | |
|---|
| 775 | extern JSBool |
|---|
| 776 | js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); |
|---|
| 777 | |
|---|
| 778 | extern JSBool |
|---|
| 779 | js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj, |
|---|
| 780 | JSBool checkForCycles); |
|---|
| 781 | |
|---|
| 782 | extern JSBool |
|---|
| 783 | js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); |
|---|
| 784 | |
|---|
| 785 | extern JSBool |
|---|
| 786 | js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id, |
|---|
| 787 | JSObject **protop); |
|---|
| 788 | |
|---|
| 789 | extern JSBool |
|---|
| 790 | js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, |
|---|
| 791 | uintN attrs); |
|---|
| 792 | |
|---|
| 793 | /* |
|---|
| 794 | * Wrap boolean, number or string as Boolean, Number or String object. |
|---|
| 795 | * *vp must not be an object, null or undefined. |
|---|
| 796 | */ |
|---|
| 797 | extern JSBool |
|---|
| 798 | js_PrimitiveToObject(JSContext *cx, jsval *vp); |
|---|
| 799 | |
|---|
| 800 | extern JSBool |
|---|
| 801 | js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); |
|---|
| 802 | |
|---|
| 803 | extern JSObject * |
|---|
| 804 | js_ValueToNonNullObject(JSContext *cx, jsval v); |
|---|
| 805 | |
|---|
| 806 | extern JSBool |
|---|
| 807 | js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval); |
|---|
| 808 | |
|---|
| 809 | extern JSBool |
|---|
| 810 | js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, |
|---|
| 811 | uintN argc, jsval *argv, jsval *rval); |
|---|
| 812 | |
|---|
| 813 | extern JSBool |
|---|
| 814 | js_XDRObject(JSXDRState *xdr, JSObject **objp); |
|---|
| 815 | |
|---|
| 816 | extern void |
|---|
| 817 | js_TraceObject(JSTracer *trc, JSObject *obj); |
|---|
| 818 | |
|---|
| 819 | extern void |
|---|
| 820 | js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize); |
|---|
| 821 | |
|---|
| 822 | extern void |
|---|
| 823 | js_Clear(JSContext *cx, JSObject *obj); |
|---|
| 824 | |
|---|
| 825 | extern jsval |
|---|
| 826 | js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot); |
|---|
| 827 | |
|---|
| 828 | extern JSBool |
|---|
| 829 | js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); |
|---|
| 830 | |
|---|
| 831 | /* |
|---|
| 832 | * Precondition: obj must be locked. |
|---|
| 833 | */ |
|---|
| 834 | extern JSBool |
|---|
| 835 | js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots, |
|---|
| 836 | JSBool exactAllocation); |
|---|
| 837 | |
|---|
| 838 | extern JSObject * |
|---|
| 839 | js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller); |
|---|
| 840 | |
|---|
| 841 | extern JSBool |
|---|
| 842 | js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj, |
|---|
| 843 | JSPrincipals *principals, JSAtom *caller); |
|---|
| 844 | |
|---|
| 845 | /* Infallible -- returns its argument if there is no wrapped object. */ |
|---|
| 846 | extern JSObject * |
|---|
| 847 | js_GetWrappedObject(JSContext *cx, JSObject *obj); |
|---|
| 848 | |
|---|
| 849 | /* NB: Infallible. */ |
|---|
| 850 | extern const char * |
|---|
| 851 | js_ComputeFilename(JSContext *cx, JSStackFrame *caller, |
|---|
| 852 | JSPrincipals *principals, uintN *linenop); |
|---|
| 853 | |
|---|
| 854 | /* Infallible, therefore cx is last parameter instead of first. */ |
|---|
| 855 | extern JSBool |
|---|
| 856 | js_IsCallable(JSObject *obj, JSContext *cx); |
|---|
| 857 | |
|---|
| 858 | void |
|---|
| 859 | js_ReportGetterOnlyAssignment(JSContext *cx); |
|---|
| 860 | |
|---|
| 861 | extern JS_FRIEND_API(JSBool) |
|---|
| 862 | js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp); |
|---|
| 863 | |
|---|
| 864 | #ifdef DEBUG |
|---|
| 865 | JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n); |
|---|
| 866 | JS_FRIEND_API(void) js_DumpString(JSString *str); |
|---|
| 867 | JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom); |
|---|
| 868 | JS_FRIEND_API(void) js_DumpValue(jsval val); |
|---|
| 869 | JS_FRIEND_API(void) js_DumpId(jsid id); |
|---|
| 870 | JS_FRIEND_API(void) js_DumpObject(JSObject *obj); |
|---|
| 871 | #endif |
|---|
| 872 | |
|---|
| 873 | JS_END_EXTERN_C |
|---|
| 874 | |
|---|
| 875 | #endif /* jsobj_h___ */ |
|---|