source: pkg/kev/main/xulrunner/trunk/js/src/jsobj.h @ 6224

Revision 6224, 35.3 KB checked in by alanbach-guest, 4 years ago (diff)

[svn-inject] Applying Debian modifications to trunk

Line 
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
55JS_BEGIN_EXTERN_C
56
57/* For detailed comments on these function pointer types, see jsprvtd.h. */
58struct 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
90struct 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 */
187struct 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
254static JS_ALWAYS_INLINE JSClass*
255STOBJ_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
383extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps;
384extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps;
385extern JSClass  js_ObjectClass;
386extern JSClass  js_WithClass;
387extern 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 */
423extern JS_REQUIRES_STACK JSObject *
424js_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 */
432extern JSObject *
433js_NewBlockObject(JSContext *cx);
434
435extern JSObject *
436js_CloneBlockObject(JSContext *cx, JSObject *proto, JSObject *parent,
437                    JSStackFrame *fp);
438
439extern JS_REQUIRES_STACK JSBool
440js_PutBlockObject(JSContext *cx, JSBool normalUnwind);
441
442JSBool
443js_XDRBlockObject(JSXDRState *xdr, JSObject **objp);
444
445struct 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
460extern JSHashEntry *
461js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
462                    jschar **sp);
463
464extern void
465js_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 */
471extern void
472js_TraceSharpMap(JSTracer *trc, JSSharpObjectMap *map);
473
474extern JSBool
475js_HasOwnPropertyHelper(JSContext *cx, JSLookupPropOp lookup, uintN argc,
476                        jsval *vp);
477
478extern JSBool
479js_HasOwnProperty(JSContext *cx, JSLookupPropOp lookup, JSObject *obj, jsid id,
480                  jsval *vp);
481
482extern JSBool
483js_PropertyIsEnumerable(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
484
485#if JS_HAS_GETTER_SETTER
486JS_FRIEND_API(JSBool) js_obj_defineGetter(JSContext *cx, uintN argc, jsval *vp);
487JS_FRIEND_API(JSBool) js_obj_defineSetter(JSContext *cx, uintN argc, jsval *vp);
488#endif
489
490extern JSObject *
491js_InitEval(JSContext *cx, JSObject *obj);
492
493extern JSObject *
494js_InitObjectClass(JSContext *cx, JSObject *obj);
495
496extern JSObject *
497js_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 */
505extern const char js_watch_str[];
506extern const char js_unwatch_str[];
507extern const char js_hasOwnProperty_str[];
508extern const char js_isPrototypeOf_str[];
509extern const char js_propertyIsEnumerable_str[];
510extern const char js_defineGetter_str[];
511extern const char js_defineSetter_str[];
512extern const char js_lookupGetter_str[];
513extern const char js_lookupSetter_str[];
514
515extern JSBool
516js_GetClassId(JSContext *cx, JSClass *clasp, jsid *idp);
517
518extern JSObject *
519js_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 */
528extern JSObject *
529js_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 */
542extern JSObject*
543js_NewNativeObject(JSContext *cx, JSClass *clasp, JSObject *proto, uint32 slot);
544
545/*
546 * Fast access to immutable standard objects (constructors and prototypes).
547 */
548extern JSBool
549js_GetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key,
550                  JSObject **objp);
551
552extern JSBool
553js_SetClassObject(JSContext *cx, JSObject *obj, JSProtoKey key, JSObject *cobj);
554
555extern JSBool
556js_FindClassObject(JSContext *cx, JSObject *start, jsid id, jsval *vp);
557
558extern JSObject *
559js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
560                   JSObject *parent, uintN argc, jsval *argv);
561
562extern void
563js_FinalizeObject(JSContext *cx, JSObject *obj);
564
565extern JSBool
566js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
567
568extern void
569js_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
596extern jsid
597js_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 */
606extern void
607js_PurgeScopeChainHelper(JSContext *cx, JSObject *obj, jsid id);
608
609#ifdef __cplusplus /* Aargh, libgjs, bug 492720. */
610static JS_INLINE void
611js_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 */
622extern JSScopeProperty *
623js_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 */
632extern JSScopeProperty *
633js_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 */
644extern JSBool
645js_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 */
654const uintN JSDNP_CACHE_RESULT = 1; /* an interpreter call from JSOP_INITPROP */
655const uintN JSDNP_DONT_PURGE   = 2; /* suppress js_PurgeScopeChain */
656
657extern JSBool
658js_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 */
671extern JS_FRIEND_API(JSBool)
672js_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 */
680extern int
681js_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 */
687extern JSPropCacheEntry *
688js_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 */
695extern JS_FRIEND_API(JSBool)
696js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp,
697                JSProperty **propp);
698
699extern JS_REQUIRES_STACK JSObject *
700js_FindIdentifierBase(JSContext *cx, JSObject *scopeChain, jsid id);
701
702extern JSObject *
703js_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 */
711extern JSBool
712js_NativeGet(JSContext *cx, JSObject *obj, JSObject *pobj,
713             JSScopeProperty *sprop, jsval *vp);
714
715extern JSBool
716js_NativeSet(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, jsval *vp);
717
718extern JSBool
719js_GetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult,
720                     jsval *vp);
721
722extern JSBool
723js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
724
725extern JSBool
726js_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 */
733extern JS_FRIEND_API(JSBool)
734js_CheckUndeclaredVarAssignment(JSContext *cx);
735
736extern JSBool
737js_SetPropertyHelper(JSContext *cx, JSObject *obj, jsid id, JSBool cacheResult,
738                     jsval *vp);
739
740extern JSBool
741js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
742
743extern JSBool
744js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
745                 uintN *attrsp);
746
747extern JSBool
748js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
749                 uintN *attrsp);
750
751extern JSBool
752js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval);
753
754extern JSBool
755js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
756
757extern JSBool
758js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
759             jsval *statep, jsid *idp);
760
761extern void
762js_TraceNativeEnumerators(JSTracer *trc);
763
764extern JSBool
765js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
766               jsval *vp, uintN *attrsp);
767
768extern JSBool
769js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
770
771extern JSBool
772js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
773             jsval *rval);
774
775extern JSBool
776js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
777
778extern JSBool
779js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
780                    JSBool checkForCycles);
781
782extern JSBool
783js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp);
784
785extern JSBool
786js_GetClassPrototype(JSContext *cx, JSObject *scope, jsid id,
787                     JSObject **protop);
788
789extern JSBool
790js_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 */
797extern JSBool
798js_PrimitiveToObject(JSContext *cx, jsval *vp);
799
800extern JSBool
801js_ValueToObject(JSContext *cx, jsval v, JSObject **objp);
802
803extern JSObject *
804js_ValueToNonNullObject(JSContext *cx, jsval v);
805
806extern JSBool
807js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval);
808
809extern JSBool
810js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom,
811             uintN argc, jsval *argv, jsval *rval);
812
813extern JSBool
814js_XDRObject(JSXDRState *xdr, JSObject **objp);
815
816extern void
817js_TraceObject(JSTracer *trc, JSObject *obj);
818
819extern void
820js_PrintObjectSlotName(JSTracer *trc, char *buf, size_t bufsize);
821
822extern void
823js_Clear(JSContext *cx, JSObject *obj);
824
825extern jsval
826js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot);
827
828extern JSBool
829js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v);
830
831/*
832 * Precondition: obj must be locked.
833 */
834extern JSBool
835js_ReallocSlots(JSContext *cx, JSObject *obj, uint32 nslots,
836                JSBool exactAllocation);
837
838extern JSObject *
839js_CheckScopeChainValidity(JSContext *cx, JSObject *scopeobj, const char *caller);
840
841extern JSBool
842js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
843                         JSPrincipals *principals, JSAtom *caller);
844
845/* Infallible -- returns its argument if there is no wrapped object. */
846extern JSObject *
847js_GetWrappedObject(JSContext *cx, JSObject *obj);
848
849/* NB: Infallible. */
850extern const char *
851js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
852                   JSPrincipals *principals, uintN *linenop);
853
854/* Infallible, therefore cx is last parameter instead of first. */
855extern JSBool
856js_IsCallable(JSObject *obj, JSContext *cx);
857
858void
859js_ReportGetterOnlyAssignment(JSContext *cx);
860
861extern JS_FRIEND_API(JSBool)
862js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
863
864#ifdef DEBUG
865JS_FRIEND_API(void) js_DumpChars(const jschar *s, size_t n);
866JS_FRIEND_API(void) js_DumpString(JSString *str);
867JS_FRIEND_API(void) js_DumpAtom(JSAtom *atom);
868JS_FRIEND_API(void) js_DumpValue(jsval val);
869JS_FRIEND_API(void) js_DumpId(jsid id);
870JS_FRIEND_API(void) js_DumpObject(JSObject *obj);
871#endif
872
873JS_END_EXTERN_C
874
875#endif /* jsobj_h___ */
Note: See TracBrowser for help on using the repository browser.