/[jscoverage]/trunk/js/jsobj.h
ViewVC logotype

Contents of /trunk/js/jsobj.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 460 - (show annotations)
Sat Sep 26 23:15:22 2009 UTC (10 years, 1 month ago) by siliconforks
File MIME type: text/plain
File size: 35955 byte(s)
Upgrade to SpiderMonkey from Firefox 3.5.3.

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 extern JSObject *
486 js_InitEval(JSContext *cx, JSObject *obj);
487
488 extern JSObject *
489 js_InitObjectClass(JSContext *cx, JSObject *obj);
490
491 extern JSObject *
492 js_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
493 JSClass *clasp, JSNative constructor, uintN nargs,
494 JSPropertySpec *ps, JSFunctionSpec *fs,
495 JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
496
497 /*
498 * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
499 */
500 extern const char js_watch_str[];
501 extern const char js_unwatch_str[];
502 extern const char js_hasOwnProperty_str[];
503 extern const char js_isPrototypeOf_str[];
504 extern const char js_propertyIsEnumerable_str[];
505 extern const char js_defineGetter_str[];
506 extern const char js_defineSetter_str[];
507 extern const char js_lookupGetter_str[];
508 extern const char js_lookupSetter_str[];
509
510 extern JSBool
511 js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp);
512
513 extern JSObject *
514 js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent,
515 uintN objectSize);
516
517 /*
518 * See jsapi.h, JS_NewObjectWithGivenProto.
519 *
520 * objectSize is either the explicit size for the allocated object or 0
521 * indicating to use the default size based on object's class.
522 */
523 extern JSObject *
524 js_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
525 JSObject *parent, uintN objectSize);
526
527 /*
528 * Allocate a new native object and initialize all fslots with JSVAL_VOID
529 * starting with the specified slot. The parent slot is set to the value of
530 * proto's parent slot.
531 *
532 * Note that this is the correct global object for native class instances, but
533 * not for user-defined functions called as constructors. Functions used as
534 * constructors must create instances parented by the parent of the function
535 * object, not by the parent of its .prototype object value.
536 */
537 extern JSObject*
538 js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot);
539
540 /*
541 * Fast access to immutable standard objects (constructors and prototypes).
542 */
543 extern JSBool
544 js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
545 JSObject **objp);
546
547 extern JSBool
548 js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj);
549
550 extern JSBool
551 js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp);
552
553 extern JSObject *
554 js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
555 JSObject *parent, uintN argc, jsval *argv);
556
557 extern void
558 js_FinalizeObject(JSContext *cx, JSObject *obj);
559
560 extern JSBool
561 js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
562
563 extern void
564 js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot);
565
566 /* JSVAL_INT_MAX as a string */
567 #define JSVAL_INT_MAX_STRING "1073741823"
568
569 /*
570 * Convert string indexes that convert to int jsvals as ints to save memory.
571 * Care must be taken to use this macro every time a property name is used, or
572 * else double-sets, incorrect property cache misses, or other mistakes could
573 * occur.
574 */
575 #define CHECK_FOR_STRING_INDEX(id) \
576 JS_BEGIN_MACRO \
577 if (JSID_IS_ATOM(id)) { \
578 JSAtom *atom_ = JSID_TO_ATOM(id); \
579 JSString *str_ = ATOM_TO_STRING(atom_); \
580 const jschar *s_ = JSFLATSTR_CHARS(str_); \
581 JSBool negative_ = (*s_ == '-'); \
582 if (negative_) s_++; \
583 if (JS7_ISDEC(*s_)) { \
584 size_t n_ = JSFLATSTR_LENGTH(str_) - negative_; \
585 if (n_ <= sizeof(JSVAL_INT_MAX_STRING) - 1) \
586 id = js_CheckForStringIndex(id, s_, s_ + n_, negative_); \
587 } \
588 } \
589 JS_END_MACRO
590
591 extern jsid
592 js_CheckForStringIndex(jsid id, const jschar *cp, const jschar *end,
593 JSBool negative);
594
595 /*
596 * js_PurgeScopeChain does nothing if obj is not itself a prototype or parent
597 * scope, else it reshapes the scope and prototype chains it links. It calls
598 * js_PurgeScopeChainHelper, which asserts that obj is flagged as a delegate
599 * (i.e., obj has ever been on a prototype or parent chain).
600 */
601 extern void
602 js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id);
603
604 #ifdef __cplusplus /* Aargh, libgjs, bug 492720. */
605 static JS_INLINE void
606 js_PurgeScopeChain(JSContext *cx, JSObject *obj, jsid id)
607 {
608 if (OBJ_IS_DELEGATE(cx, obj))
609 js_PurgeScopeChainHelper(cx, obj, id);
610 }
611 #endif
612
613 /*
614 * Find or create a property named by id in obj's scope, with the given getter
615 * and setter, slot, attributes, and other members.
616 */
617 extern JSScopeProperty *
618 js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id,
619 JSPropertyOp getter, JSPropertyOp setter, uint32 slot,
620 uintN attrs, uintN flags, intN shortid);
621
622 /*
623 * Change sprop to have the given attrs, getter, and setter in scope, morphing
624 * it into a potentially new JSScopeProperty. Return a pointer to the changed
625 * or identical property.
626 */
627 extern JSScopeProperty *
628 js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj,
629 JSScopeProperty *sprop, uintN attrs, uintN mask,
630 JSPropertyOp getter, JSPropertyOp setter);
631
632 /*
633 * On error, return false. On success, if propp is non-null, return true with
634 * obj locked and with a held property in *propp; if propp is null, return true
635 * but release obj's lock first. Therefore all callers who pass non-null propp
636 * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to
637 * drop the held property, and to release the lock on obj.
638 */
639 extern JSBool
640 js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
641 JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
642 JSProperty **propp);
643
644 #ifdef __cplusplus /* FIXME: bug 442399 removes this LiveConnect requirement. */
645
646 /*
647 * Flags for the defineHow parameter of js_DefineNativeProperty.
648 */
649 const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */
650 const uintN JSDNP_DONT_PURGE = 2; /* suppress js_PurgeScopeChain */
651
652 extern JSBool
653 js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
654 JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
655 uintN flags, intN shortid, JSProperty **propp,
656 uintN defineHow = 0);
657 #endif
658
659 /*
660 * Unlike js_DefineProperty, propp must be non-null. On success, and if id was
661 * found, return true with *objp non-null and locked, and with a held property
662 * stored in *propp. If successful but id was not found, return true with both
663 * *objp and *propp null. Therefore all callers who receive a non-null *propp
664 * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp).
665 */
666 extern JS_FRIEND_API(JSBool)
667 js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
668 JSProperty **propp);
669
670 /*
671 * Specialized subroutine that allows caller to preset JSRESOLVE_* flags and
672 * returns the index along the prototype chain in which *propp was found, or
673 * the last index if not found, or -1 on error.
674 */
675 extern int
676 js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
677 JSObject **objp, JSProperty **propp);
678
679 /*
680 * If cacheResult is false, return JS_NO_PROP_CACHE_FILL on success.
681 */
682 extern JSPropCacheEntry *
683 js_FindPropertyHelper(JSContext *cx, jsid id, JSBool cacheResult,
684 JSObject **objp, JSObject **pobjp, JSProperty **propp);
685
686 /*
687 * Return the index along the scope chain in which id was found, or the last
688 * index if not found, or -1 on error.
689 */
690 extern JS_FRIEND_API(JSBool)
691 js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
692 JSProperty **propp);
693
694 extern JS_REQUIRES_STACK JSObject *
695 js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id);
696
697 extern JSObject *
698 js_FindVariableScope(JSContext *cx, JSFunction **funp);
699
700 /*
701 * NB: js_NativeGet and js_NativeSet are called with the scope containing sprop
702 * (pobj's scope for Get, obj's for Set) locked, and on successful return, that
703 * scope is again locked. But on failure, both functions return false with the
704 * scope containing sprop unlocked.
705 */
706 extern JSBool
707 js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
708 JSScopeProperty *sprop, jsval *vp);
709
710 extern JSBool
711 js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp);
712
713 extern JSBool
714 js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult,
715 jsval *vp);
716
717 extern JSBool
718 js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
719
720 extern JSBool
721 js_GetMethod(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult,
722 jsval *vp);
723
724 /*
725 * Check whether it is OK to assign an undeclared property of the global
726 * object at the current script PC.
727 */
728 extern JS_FRIEND_API(JSBool)
729 js_CheckUndeclaredVarAssignment(JSContext *cx);
730
731 extern JSBool
732 js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult,
733 jsval *vp);
734
735 extern JSBool
736 js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
737
738 extern JSBool
739 js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
740 uintN *attrsp);
741
742 extern JSBool
743 js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
744 uintN *attrsp);
745
746 extern JSBool
747 js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval);
748
749 extern JSBool
750 js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
751
752 extern JSBool
753 js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
754 jsval *statep, jsid *idp);
755
756 extern void
757 js_TraceNativeEnumerators(JSTracer *trc);
758
759 extern JSBool
760 js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
761 jsval *vp, uintN *attrsp);
762
763 extern JSBool
764 js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
765
766 extern JSBool
767 js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
768 jsval *rval);
769
770 extern JSBool
771 js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
772
773 extern JSBool
774 js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
775 JSBool checkForCycles);
776
777 extern JSBool
778 js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
779
780 extern JSBool
781 js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id,
782 JSObject **protop);
783
784 extern JSBool
785 js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto,
786 uintN attrs);
787
788 /*
789 * Wrap boolean, number or string as Boolean, Number or String object.
790 * *vp must not be an object, null or undefined.
791 */
792 extern JSBool
793 js_PrimitiveToObject(JSContext *cx, jsval *vp);
794
795 extern JSBool
796 js_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
797
798 extern JSObject *
799 js_ValueToNonNullObject(JSContext *cx, jsval v);
800
801 extern JSBool
802 js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval);
803
804 extern JSBool
805 js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
806 uintN argc, jsval *argv, jsval *rval);
807
808 extern JSBool
809 js_XDRObject(JSXDRState *xdr, JSObject **objp);
810
811 extern void
812 js_TraceObject(JSTracer *trc, JSObject *obj);
813
814 extern void
815 js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
816
817 extern void
818 js_Clear(JSContext *cx, JSObject *obj);
819
820 extern jsval
821 js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot);
822
823 extern JSBool
824 js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v);
825
826 /*
827 * Precondition: obj must be locked.
828 */
829 extern JSBool
830 js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
831 JSBool exactAllocation);
832
833 extern JSObject *
834 js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);
835
836 extern JSBool
837 js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
838 JSPrincipals *principals, JSAtom *caller);
839
840 /* Infallible -- returns its argument if there is no wrapped object. */
841 extern JSObject *
842 js_GetWrappedObject(JSContext *cx, JSObject *obj);
843
844 /* NB: Infallible. */
845 extern const char *
846 js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
847 JSPrincipals *principals, uintN *linenop);
848
849 /* Infallible, therefore cx is last parameter instead of first. */
850 extern JSBool
851 js_IsCallable(JSObject *obj, JSContext *cx);
852
853 void
854 js_ReportGetterOnlyAssignment(JSContext *cx);
855
856 extern JS_FRIEND_API(JSBool)
857 js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
858
859 #ifdef DEBUG
860 JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
861 JS_FRIEND_API(void) js_DumpString(JSString *str);
862 JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
863 JS_FRIEND_API(void) js_DumpValue(jsval val);
864 JS_FRIEND_API(void) js_DumpId(jsid id);
865 JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
866 #endif
867
868 JS_END_EXTERN_C
869
870 #endif /* jsobj_h___ */

  ViewVC Help
Powered by ViewVC 1.1.24