1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : *
17 : * The Original Code is SpiderMonkey code.
18 : *
19 : * The Initial Developer of the Original Code is
20 : * Mozilla Corporation.
21 : * Portions created by the Initial Developer are Copyright (C) 2010
22 : * the Initial Developer. All Rights Reserved.
23 : *
24 : * Contributor(s):
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef jsfriendapi_h___
41 : #define jsfriendapi_h___
42 :
43 : #include "jsclass.h"
44 : #include "jspubtd.h"
45 : #include "jsprvtd.h"
46 :
47 : #include "mozilla/GuardObjects.h"
48 :
49 : JS_BEGIN_EXTERN_C
50 :
51 : extern JS_FRIEND_API(void)
52 : JS_SetGrayGCRootsTracer(JSRuntime *rt, JSTraceDataOp traceOp, void *data);
53 :
54 : extern JS_FRIEND_API(JSString *)
55 : JS_GetAnonymousString(JSRuntime *rt);
56 :
57 : extern JS_FRIEND_API(JSObject *)
58 : JS_FindCompilationScope(JSContext *cx, JSObject *obj);
59 :
60 : extern JS_FRIEND_API(JSFunction *)
61 : JS_GetObjectFunction(JSObject *obj);
62 :
63 : extern JS_FRIEND_API(JSObject *)
64 : JS_GetGlobalForFrame(JSStackFrame *fp);
65 :
66 : extern JS_FRIEND_API(JSBool)
67 : JS_SplicePrototype(JSContext *cx, JSObject *obj, JSObject *proto);
68 :
69 : extern JS_FRIEND_API(JSObject *)
70 : JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
71 :
72 : extern JS_FRIEND_API(uint32_t)
73 : JS_ObjectCountDynamicSlots(JSObject *obj);
74 :
75 : extern JS_FRIEND_API(void)
76 : JS_ShrinkGCBuffers(JSRuntime *rt);
77 :
78 : extern JS_FRIEND_API(size_t)
79 : JS_GetE4XObjectsCreated(JSContext *cx);
80 :
81 : extern JS_FRIEND_API(size_t)
82 : JS_SetProtoCalled(JSContext *cx);
83 :
84 : extern JS_FRIEND_API(size_t)
85 : JS_GetCustomIteratorCount(JSContext *cx);
86 :
87 : extern JS_FRIEND_API(JSBool)
88 : JS_NondeterministicGetWeakMapKeys(JSContext *cx, JSObject *obj, JSObject **ret);
89 :
90 : /*
91 : * Used by the cycle collector to trace through the shape and all
92 : * shapes it reaches, marking all non-shape children found in the
93 : * process. Uses bounded stack space.
94 : */
95 : extern JS_FRIEND_API(void)
96 : JS_TraceShapeCycleCollectorChildren(JSTracer *trc, void *shape);
97 :
98 : enum {
99 : JS_TELEMETRY_GC_REASON,
100 : JS_TELEMETRY_GC_IS_COMPARTMENTAL,
101 : JS_TELEMETRY_GC_MS,
102 : JS_TELEMETRY_GC_MARK_MS,
103 : JS_TELEMETRY_GC_SWEEP_MS,
104 : JS_TELEMETRY_GC_SLICE_MS,
105 : JS_TELEMETRY_GC_MMU_50,
106 : JS_TELEMETRY_GC_RESET,
107 : JS_TELEMETRY_GC_INCREMENTAL_DISABLED,
108 : JS_TELEMETRY_GC_NON_INCREMENTAL
109 : };
110 :
111 : typedef void
112 : (* JSAccumulateTelemetryDataCallback)(int id, uint32_t sample);
113 :
114 : extern JS_FRIEND_API(void)
115 : JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback);
116 :
117 : extern JS_FRIEND_API(JSPrincipals *)
118 : JS_GetCompartmentPrincipals(JSCompartment *compartment);
119 :
120 : /* Safe to call with input obj == NULL. Returns non-NULL iff obj != NULL. */
121 : extern JS_FRIEND_API(JSObject *)
122 : JS_ObjectToInnerObject(JSContext *cx, JSObject *obj);
123 :
124 : /* Requires obj != NULL. */
125 : extern JS_FRIEND_API(JSObject *)
126 : JS_ObjectToOuterObject(JSContext *cx, JSObject *obj);
127 :
128 : extern JS_FRIEND_API(JSObject *)
129 : JS_CloneObject(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent);
130 :
131 : extern JS_FRIEND_API(JSBool)
132 : js_GetterOnlyPropertyStub(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp);
133 :
134 : JS_FRIEND_API(void)
135 : js_ReportOverRecursed(JSContext *maybecx);
136 :
137 : #ifdef DEBUG
138 :
139 : /*
140 : * Routines to print out values during debugging. These are FRIEND_API to help
141 : * the debugger find them and to support temporarily hacking js_Dump* calls
142 : * into other code.
143 : */
144 :
145 : extern JS_FRIEND_API(void)
146 : js_DumpString(JSString *str);
147 :
148 : extern JS_FRIEND_API(void)
149 : js_DumpAtom(JSAtom *atom);
150 :
151 : extern JS_FRIEND_API(void)
152 : js_DumpObject(JSObject *obj);
153 :
154 : extern JS_FRIEND_API(void)
155 : js_DumpChars(const jschar *s, size_t n);
156 : #endif
157 :
158 : #ifdef __cplusplus
159 :
160 : extern JS_FRIEND_API(bool)
161 : JS_CopyPropertiesFrom(JSContext *cx, JSObject *target, JSObject *obj);
162 :
163 : extern JS_FRIEND_API(JSBool)
164 : JS_WrapPropertyDescriptor(JSContext *cx, js::PropertyDescriptor *desc);
165 :
166 : extern JS_FRIEND_API(JSBool)
167 : JS_EnumerateState(JSContext *cx, JSObject *obj, JSIterateOp enum_op, js::Value *statep, jsid *idp);
168 :
169 : struct JSFunctionSpecWithHelp {
170 : const char *name;
171 : JSNative call;
172 : uint16_t nargs;
173 : uint16_t flags;
174 : const char *usage;
175 : const char *help;
176 : };
177 :
178 : #define JS_FN_HELP(name,call,nargs,flags,usage,help) \
179 : {name, call, nargs, (flags) | JSPROP_ENUMERATE | JSFUN_STUB_GSOPS, usage, help}
180 :
181 : extern JS_FRIEND_API(bool)
182 : JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *obj, const JSFunctionSpecWithHelp *fs);
183 :
184 : #endif
185 :
186 : JS_END_EXTERN_C
187 :
188 : #ifdef __cplusplus
189 :
190 : namespace js {
191 :
192 : struct ContextFriendFields {
193 : JSRuntime *const runtime;
194 :
195 : ContextFriendFields(JSRuntime *rt)
196 : : runtime(rt) { }
197 :
198 266589607 : static const ContextFriendFields *get(const JSContext *cx) {
199 266589607 : return reinterpret_cast<const ContextFriendFields *>(cx);
200 : }
201 : };
202 :
203 : struct RuntimeFriendFields {
204 : /*
205 : * If non-zero, we were been asked to call the operation callback as soon
206 : * as possible.
207 : */
208 : volatile int32_t interrupt;
209 :
210 : /* Limit pointer for checking native stack consumption. */
211 : uintptr_t nativeStackLimit;
212 :
213 : RuntimeFriendFields()
214 : : interrupt(0),
215 : nativeStackLimit(0) { }
216 :
217 267279485 : static const RuntimeFriendFields *get(const JSRuntime *rt) {
218 267279485 : return reinterpret_cast<const RuntimeFriendFields *>(rt);
219 : }
220 : };
221 :
222 : inline JSRuntime *
223 266589607 : GetRuntime(const JSContext *cx)
224 : {
225 266589607 : return ContextFriendFields::get(cx)->runtime;
226 : }
227 :
228 : typedef bool
229 : (* PreserveWrapperCallback)(JSContext *cx, JSObject *obj);
230 :
231 : #ifdef DEBUG
232 : /*
233 : * DEBUG-only method to dump the complete object graph of heap-allocated things.
234 : * fp is the file for the dump output.
235 : */
236 : extern JS_FRIEND_API(void)
237 : DumpHeapComplete(JSRuntime *rt, FILE *fp);
238 :
239 : #endif
240 :
241 : class JS_FRIEND_API(AutoPreserveCompartment) {
242 : private:
243 : JSContext *cx;
244 : JSCompartment *oldCompartment;
245 : public:
246 : AutoPreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM);
247 : ~AutoPreserveCompartment();
248 : JS_DECL_USE_GUARD_OBJECT_NOTIFIER
249 : };
250 :
251 : class JS_FRIEND_API(AutoSwitchCompartment) {
252 : private:
253 : JSContext *cx;
254 : JSCompartment *oldCompartment;
255 : public:
256 : AutoSwitchCompartment(JSContext *cx, JSCompartment *newCompartment
257 : JS_GUARD_OBJECT_NOTIFIER_PARAM);
258 : AutoSwitchCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM);
259 : ~AutoSwitchCompartment();
260 : JS_DECL_USE_GUARD_OBJECT_NOTIFIER
261 : };
262 :
263 : #ifdef OLD_GETTER_SETTER_METHODS
264 : JS_FRIEND_API(JSBool) obj_defineGetter(JSContext *cx, unsigned argc, js::Value *vp);
265 : JS_FRIEND_API(JSBool) obj_defineSetter(JSContext *cx, unsigned argc, js::Value *vp);
266 : #endif
267 :
268 : extern JS_FRIEND_API(bool)
269 : IsSystemCompartment(const JSCompartment *compartment);
270 :
271 : extern JS_FRIEND_API(bool)
272 : IsAtomsCompartment(const JSCompartment *c);
273 :
274 : /*
275 : * Check whether it is OK to assign an undeclared property with name
276 : * propname of the global object in the current script on cx. Reports
277 : * an error if one needs to be reported (in particular in all cases
278 : * when it returns false).
279 : */
280 : extern JS_FRIEND_API(bool)
281 : CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname);
282 :
283 : struct WeakMapTracer;
284 :
285 : /*
286 : * Weak map tracer callback, called once for every binding of every
287 : * weak map that was live at the time of the last garbage collection.
288 : *
289 : * m will be NULL if the weak map is not contained in a JS Object.
290 : */
291 : typedef void
292 : (* WeakMapTraceCallback)(WeakMapTracer *trc, JSObject *m,
293 : void *k, JSGCTraceKind kkind,
294 : void *v, JSGCTraceKind vkind);
295 :
296 : struct WeakMapTracer {
297 : JSRuntime *runtime;
298 : WeakMapTraceCallback callback;
299 :
300 1910 : WeakMapTracer(JSRuntime *rt, WeakMapTraceCallback cb)
301 1910 : : runtime(rt), callback(cb) {}
302 : };
303 :
304 : extern JS_FRIEND_API(void)
305 : TraceWeakMaps(WeakMapTracer *trc);
306 :
307 : extern JS_FRIEND_API(bool)
308 : GCThingIsMarkedGray(void *thing);
309 :
310 :
311 : /*
312 : * Shadow declarations of JS internal structures, for access by inline access
313 : * functions below. Do not use these structures in any other way. When adding
314 : * new fields for access by inline methods, make sure to add static asserts to
315 : * the original header file to ensure that offsets are consistent.
316 : */
317 : namespace shadow {
318 :
319 : struct TypeObject {
320 : JSObject *proto;
321 : };
322 :
323 : struct BaseShape {
324 : js::Class *clasp;
325 : JSObject *parent;
326 : };
327 :
328 : struct Shape {
329 : BaseShape *base;
330 : jsid _1;
331 : uint32_t slotInfo;
332 :
333 : static const uint32_t FIXED_SLOTS_SHIFT = 27;
334 : };
335 :
336 : struct Object {
337 : Shape *shape;
338 : TypeObject *type;
339 : js::Value *slots;
340 : js::Value *_1;
341 :
342 858317079 : size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; }
343 59958578 : Value *fixedSlots() const {
344 59958578 : return (Value *)(uintptr_t(this) + sizeof(shadow::Object));
345 : }
346 :
347 34476621 : js::Value &slotRef(size_t slot) const {
348 34476621 : size_t nfixed = numFixedSlots();
349 34476621 : if (slot < nfixed)
350 33716323 : return fixedSlots()[slot];
351 760298 : return slots[slot - nfixed];
352 : }
353 : };
354 :
355 : struct Atom {
356 : size_t _;
357 : const jschar *chars;
358 : };
359 :
360 : } /* namespace shadow */
361 :
362 : extern JS_FRIEND_DATA(js::Class) AnyNameClass;
363 : extern JS_FRIEND_DATA(js::Class) AttributeNameClass;
364 : extern JS_FRIEND_DATA(js::Class) CallClass;
365 : extern JS_FRIEND_DATA(js::Class) DeclEnvClass;
366 : extern JS_FRIEND_DATA(js::Class) FunctionClass;
367 : extern JS_FRIEND_DATA(js::Class) FunctionProxyClass;
368 : extern JS_FRIEND_DATA(js::Class) NamespaceClass;
369 : extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass;
370 : extern JS_FRIEND_DATA(js::Class) ObjectProxyClass;
371 : extern JS_FRIEND_DATA(js::Class) QNameClass;
372 : extern JS_FRIEND_DATA(js::Class) XMLClass;
373 : extern JS_FRIEND_DATA(js::Class) ObjectClass;
374 :
375 : inline js::Class *
376 368128412 : GetObjectClass(const JSObject *obj)
377 : {
378 368128412 : return reinterpret_cast<const shadow::Object*>(obj)->shape->base->clasp;
379 : }
380 :
381 : inline JSClass *
382 150463 : GetObjectJSClass(const JSObject *obj)
383 : {
384 150463 : return js::Jsvalify(GetObjectClass(obj));
385 : }
386 :
387 : JS_FRIEND_API(bool)
388 : IsScopeObject(JSObject *obj);
389 :
390 : inline JSObject *
391 13043148 : GetObjectParent(JSObject *obj)
392 : {
393 13043148 : JS_ASSERT(!IsScopeObject(obj));
394 13043148 : return reinterpret_cast<shadow::Object*>(obj)->shape->base->parent;
395 : }
396 :
397 : JS_FRIEND_API(JSObject *)
398 : GetObjectParentMaybeScope(JSObject *obj);
399 :
400 : JS_FRIEND_API(JSObject *)
401 : GetGlobalForObjectCrossCompartment(JSObject *obj);
402 :
403 : JS_FRIEND_API(bool)
404 : IsOriginalScriptFunction(JSFunction *fun);
405 :
406 : JS_FRIEND_API(JSFunction *)
407 : DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
408 : unsigned nargs, unsigned attrs);
409 :
410 : JS_FRIEND_API(JSFunction *)
411 : NewFunctionWithReserved(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
412 : JSObject *parent, const char *name);
413 :
414 : JS_FRIEND_API(JSFunction *)
415 : NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
416 : JSObject *parent, jsid id);
417 :
418 : JS_FRIEND_API(JSObject *)
419 : InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
420 : JSClass *clasp, JSNative constructor, unsigned nargs,
421 : JSPropertySpec *ps, JSFunctionSpec *fs,
422 : JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
423 :
424 : JS_FRIEND_API(const Value &)
425 : GetFunctionNativeReserved(JSObject *fun, size_t which);
426 :
427 : JS_FRIEND_API(void)
428 : SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val);
429 :
430 : inline JSObject *
431 409424 : GetObjectProto(JSObject *obj)
432 : {
433 409424 : return reinterpret_cast<const shadow::Object*>(obj)->type->proto;
434 : }
435 :
436 : inline void *
437 26242255 : GetObjectPrivate(JSObject *obj)
438 : {
439 26242255 : const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj);
440 26242255 : void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
441 26242255 : return *addr;
442 : }
443 :
444 : /*
445 : * Get a slot that is both reserved for object's clasp *and* is fixed (fits
446 : * within the maximum capacity for the object's fixed slots).
447 : */
448 : inline const Value &
449 33676338 : GetReservedSlot(const JSObject *obj, size_t slot)
450 : {
451 33676338 : JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
452 33676338 : return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
453 : }
454 :
455 : JS_FRIEND_API(void)
456 : SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const Value &value);
457 :
458 : inline void
459 14127 : SetReservedSlot(JSObject *obj, size_t slot, const Value &value)
460 : {
461 14127 : JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
462 14127 : shadow::Object *sobj = reinterpret_cast<shadow::Object *>(obj);
463 14127 : if (sobj->slotRef(slot).isMarkable())
464 0 : SetReservedSlotWithBarrier(obj, slot, value);
465 : else
466 14127 : sobj->slotRef(slot) = value;
467 14127 : }
468 :
469 : JS_FRIEND_API(uint32_t)
470 : GetObjectSlotSpan(JSObject *obj);
471 :
472 : inline const Value &
473 772029 : GetObjectSlot(JSObject *obj, size_t slot)
474 : {
475 772029 : JS_ASSERT(slot < GetObjectSlotSpan(obj));
476 772029 : return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
477 : }
478 :
479 : inline Shape *
480 17006 : GetObjectShape(JSObject *obj)
481 : {
482 17006 : shadow::Shape *shape = reinterpret_cast<const shadow::Object*>(obj)->shape;
483 17006 : return reinterpret_cast<Shape *>(shape);
484 : }
485 :
486 : inline const jschar *
487 3712 : GetAtomChars(JSAtom *atom)
488 : {
489 3712 : return reinterpret_cast<shadow::Atom *>(atom)->chars;
490 : }
491 :
492 : inline JSLinearString *
493 0 : AtomToLinearString(JSAtom *atom)
494 : {
495 0 : return reinterpret_cast<JSLinearString *>(atom);
496 : }
497 :
498 : static inline js::PropertyOp
499 0 : CastAsJSPropertyOp(JSObject *object)
500 : {
501 0 : return JS_DATA_TO_FUNC_PTR(js::PropertyOp, object);
502 : }
503 :
504 : static inline js::StrictPropertyOp
505 0 : CastAsJSStrictPropertyOp(JSObject *object)
506 : {
507 0 : return JS_DATA_TO_FUNC_PTR(js::StrictPropertyOp, object);
508 : }
509 :
510 : JS_FRIEND_API(bool)
511 : GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector *props);
512 :
513 : JS_FRIEND_API(bool)
514 : StringIsArrayIndex(JSLinearString *str, uint32_t *indexp);
515 :
516 : JS_FRIEND_API(void)
517 : SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback);
518 :
519 : JS_FRIEND_API(bool)
520 : IsObjectInContextCompartment(const JSObject *obj, const JSContext *cx);
521 :
522 : /*
523 : * NB: these flag bits are encoded into the bytecode stream in the immediate
524 : * operand of JSOP_ITER, so don't change them without advancing jsxdrapi.h's
525 : * JSXDR_BYTECODE_VERSION.
526 : */
527 : #define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */
528 : #define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */
529 : #define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */
530 : #define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
531 : #define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
532 : #define JSITER_FOR_OF 0x20 /* harmony for-of loop */
533 :
534 : inline uintptr_t
535 267279485 : GetNativeStackLimit(const JSRuntime *rt)
536 : {
537 267279485 : return RuntimeFriendFields::get(rt)->nativeStackLimit;
538 : }
539 :
540 : #define JS_CHECK_RECURSION(cx, onerror) \
541 : JS_BEGIN_MACRO \
542 : int stackDummy_; \
543 : if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \
544 : js_ReportOverRecursed(cx); \
545 : onerror; \
546 : } \
547 : JS_END_MACRO
548 :
549 : JS_FRIEND_API(void)
550 : StartPCCountProfiling(JSContext *cx);
551 :
552 : JS_FRIEND_API(void)
553 : StopPCCountProfiling(JSContext *cx);
554 :
555 : JS_FRIEND_API(void)
556 : PurgePCCounts(JSContext *cx);
557 :
558 : JS_FRIEND_API(size_t)
559 : GetPCCountScriptCount(JSContext *cx);
560 :
561 : JS_FRIEND_API(JSString *)
562 : GetPCCountScriptSummary(JSContext *cx, size_t script);
563 :
564 : JS_FRIEND_API(JSString *)
565 : GetPCCountScriptContents(JSContext *cx, size_t script);
566 :
567 : #ifdef JS_THREADSAFE
568 : JS_FRIEND_API(void *)
569 : GetOwnerThread(const JSContext *cx);
570 :
571 : JS_FRIEND_API(unsigned)
572 : GetContextOutstandingRequests(const JSContext *cx);
573 :
574 : class JS_FRIEND_API(AutoSkipConservativeScan)
575 : {
576 : public:
577 : AutoSkipConservativeScan(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
578 : ~AutoSkipConservativeScan();
579 :
580 : private:
581 : JSContext *context;
582 : MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
583 : };
584 : #endif
585 :
586 : JS_FRIEND_API(JSCompartment *)
587 : GetContextCompartment(const JSContext *cx);
588 :
589 : JS_FRIEND_API(bool)
590 : HasUnrootedGlobal(const JSContext *cx);
591 :
592 : typedef void
593 : (* ActivityCallback)(void *arg, JSBool active);
594 :
595 : /*
596 : * Sets a callback that is run whenever the runtime goes idle - the
597 : * last active request ceases - and begins activity - when it was
598 : * idle and a request begins.
599 : */
600 : JS_FRIEND_API(void)
601 : SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg);
602 :
603 : extern JS_FRIEND_API(const JSStructuredCloneCallbacks *)
604 : GetContextStructuredCloneCallbacks(JSContext *cx);
605 :
606 : extern JS_FRIEND_API(JSVersion)
607 : VersionSetXML(JSVersion version, bool enable);
608 :
609 : extern JS_FRIEND_API(bool)
610 : CanCallContextDebugHandler(JSContext *cx);
611 :
612 : extern JS_FRIEND_API(JSTrapStatus)
613 : CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval);
614 :
615 : extern JS_FRIEND_API(bool)
616 : IsContextRunningJS(JSContext *cx);
617 :
618 : class SystemAllocPolicy;
619 : typedef Vector<JSCompartment*, 0, SystemAllocPolicy> CompartmentVector;
620 : extern JS_FRIEND_API(const CompartmentVector&)
621 : GetRuntimeCompartments(JSRuntime *rt);
622 :
623 : extern JS_FRIEND_API(size_t)
624 : SizeOfJSContext();
625 :
626 : #define GCREASONS(D) \
627 : /* Reasons internal to the JS engine */ \
628 : D(API) \
629 : D(MAYBEGC) \
630 : D(LAST_CONTEXT) \
631 : D(DESTROY_CONTEXT) \
632 : D(LAST_DITCH) \
633 : D(TOO_MUCH_MALLOC) \
634 : D(ALLOC_TRIGGER) \
635 : D(DEBUG_GC) \
636 : D(UNUSED2) /* was SHAPE */ \
637 : D(UNUSED3) /* was REFILL */ \
638 : \
639 : /* Reasons from Firefox */ \
640 : D(DOM_WINDOW_UTILS) \
641 : D(COMPONENT_UTILS) \
642 : D(MEM_PRESSURE) \
643 : D(CC_WAITING) \
644 : D(CC_FORCED) \
645 : D(LOAD_END) \
646 : D(POST_COMPARTMENT) \
647 : D(PAGE_HIDE) \
648 : D(NSJSCONTEXT_DESTROY) \
649 : D(SET_NEW_DOCUMENT) \
650 : D(SET_DOC_SHELL) \
651 : D(DOM_UTILS) \
652 : D(DOM_IPC) \
653 : D(DOM_WORKER) \
654 : D(INTER_SLICE_GC) \
655 : D(REFRESH_FRAME)
656 :
657 : namespace gcreason {
658 :
659 : /* GCReasons will end up looking like JSGC_MAYBEGC */
660 : enum Reason {
661 : #define MAKE_REASON(name) name,
662 : GCREASONS(MAKE_REASON)
663 : #undef MAKE_REASON
664 : NO_REASON,
665 : NUM_REASONS
666 : };
667 :
668 : } /* namespace gcreason */
669 :
670 : extern JS_FRIEND_API(void)
671 : GCForReason(JSContext *cx, gcreason::Reason reason);
672 :
673 : extern JS_FRIEND_API(void)
674 : CompartmentGCForReason(JSContext *cx, JSCompartment *comp, gcreason::Reason reason);
675 :
676 : extern JS_FRIEND_API(void)
677 : ShrinkingGC(JSContext *cx, gcreason::Reason reason);
678 :
679 : extern JS_FRIEND_API(void)
680 : IncrementalGC(JSContext *cx, gcreason::Reason reason);
681 :
682 : extern JS_FRIEND_API(void)
683 : SetGCSliceTimeBudget(JSContext *cx, int64_t millis);
684 :
685 : enum GCProgress {
686 : /*
687 : * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
688 : * callbacks. During an incremental GC, the sequence of callbacks is as
689 : * follows:
690 : * JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice)
691 : * JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice)
692 : * ...
693 : * JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice)
694 : */
695 :
696 : GC_CYCLE_BEGIN,
697 : GC_SLICE_BEGIN,
698 : GC_SLICE_END,
699 : GC_CYCLE_END
700 : };
701 :
702 : struct GCDescription {
703 : const char *logMessage;
704 : bool isCompartment;
705 :
706 : GCDescription(const char *msg, bool isCompartment)
707 : : logMessage(msg), isCompartment(isCompartment) {}
708 : };
709 :
710 : typedef void
711 : (* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
712 :
713 : extern JS_FRIEND_API(GCSliceCallback)
714 : SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
715 :
716 : extern JS_FRIEND_API(bool)
717 : WantGCSlice(JSRuntime *rt);
718 :
719 : /*
720 : * Signals a good place to do an incremental slice, because the browser is
721 : * drawing a frame.
722 : */
723 : extern JS_FRIEND_API(void)
724 : NotifyDidPaint(JSContext *cx);
725 :
726 : extern JS_FRIEND_API(bool)
727 : IsIncrementalGCEnabled(JSRuntime *rt);
728 :
729 : extern JS_FRIEND_API(void)
730 : DisableIncrementalGC(JSRuntime *rt);
731 :
732 : extern JS_FRIEND_API(bool)
733 : IsIncrementalBarrierNeeded(JSRuntime *rt);
734 :
735 : extern JS_FRIEND_API(bool)
736 : IsIncrementalBarrierNeeded(JSContext *cx);
737 :
738 : extern JS_FRIEND_API(bool)
739 : IsIncrementalBarrierNeededOnObject(JSObject *obj);
740 :
741 : extern JS_FRIEND_API(void)
742 : IncrementalReferenceBarrier(void *ptr);
743 :
744 : extern JS_FRIEND_API(void)
745 : IncrementalValueBarrier(const Value &v);
746 :
747 : class ObjectPtr
748 : {
749 : JSObject *value;
750 :
751 : public:
752 : ObjectPtr() : value(NULL) {}
753 :
754 217872 : ObjectPtr(JSObject *obj) : value(obj) {}
755 :
756 : /* Always call finalize before the destructor. */
757 217723 : ~ObjectPtr() { JS_ASSERT(!value); }
758 :
759 233170 : void finalize(JSRuntime *rt) {
760 233170 : if (IsIncrementalBarrierNeeded(rt))
761 0 : IncrementalReferenceBarrier(value);
762 233170 : value = NULL;
763 233170 : }
764 202228 : void finalize(JSContext *cx) { finalize(JS_GetRuntime(cx)); }
765 :
766 : void init(JSObject *obj) { value = obj; }
767 :
768 0 : JSObject *get() const { return value; }
769 :
770 0 : void writeBarrierPre(JSRuntime *rt) {
771 0 : IncrementalReferenceBarrier(value);
772 0 : }
773 :
774 217998 : ObjectPtr &operator=(JSObject *obj) {
775 217998 : IncrementalReferenceBarrier(value);
776 217998 : value = obj;
777 217998 : return *this;
778 : }
779 :
780 : JSObject &operator*() const { return *value; }
781 : JSObject *operator->() const { return value; }
782 13935396 : operator JSObject *() const { return value; }
783 : };
784 :
785 : extern JS_FRIEND_API(JSObject *)
786 : GetTestingFunctions(JSContext *cx);
787 :
788 : } /* namespace js */
789 :
790 : #endif
791 :
792 : /* Implemented in jsdate.cpp. */
793 :
794 : /*
795 : * Detect whether the internal date value is NaN. (Because failure is
796 : * out-of-band for js_DateGet*)
797 : */
798 : extern JS_FRIEND_API(JSBool)
799 : js_DateIsValid(JSContext *cx, JSObject* obj);
800 :
801 : extern JS_FRIEND_API(double)
802 : js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj);
803 :
804 : /* Implemented in jscntxt.cpp. */
805 :
806 : /*
807 : * Report an exception, which is currently realized as a printf-style format
808 : * string and its arguments.
809 : */
810 : typedef enum JSErrNum {
811 : #define MSG_DEF(name, number, count, exception, format) \
812 : name = number,
813 : #include "js.msg"
814 : #undef MSG_DEF
815 : JSErr_Limit
816 : } JSErrNum;
817 :
818 : extern JS_FRIEND_API(const JSErrorFormatString *)
819 : js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber);
820 :
821 : /* Implemented in jsclone.cpp. */
822 :
823 : extern JS_FRIEND_API(uint64_t)
824 : js_GetSCOffset(JSStructuredCloneWriter* writer);
825 :
826 : #endif /* jsfriendapi_h___ */
|