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 18771 : ContextFriendFields(JSRuntime *rt)
196 18771 : : runtime(rt) { }
197 :
198 55520653 : static const ContextFriendFields *get(const JSContext *cx) {
199 55520653 : 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 18761 : RuntimeFriendFields()
214 : : interrupt(0),
215 18761 : nativeStackLimit(0) { }
216 :
217 55520653 : static const RuntimeFriendFields *get(const JSRuntime *rt) {
218 55520653 : return reinterpret_cast<const RuntimeFriendFields *>(rt);
219 : }
220 : };
221 :
222 : inline JSRuntime *
223 55520653 : GetRuntime(const JSContext *cx)
224 : {
225 55520653 : 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 : WeakMapTracer(JSRuntime *rt, WeakMapTraceCallback cb)
301 : : 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 : * Shadow declarations of JS internal structures, for access by inline access
312 : * functions below. Do not use these structures in any other way. When adding
313 : * new fields for access by inline methods, make sure to add static asserts to
314 : * the original header file to ensure that offsets are consistent.
315 : */
316 : namespace shadow {
317 :
318 : struct TypeObject {
319 : JSObject *proto;
320 : };
321 :
322 : struct BaseShape {
323 : js::Class *clasp;
324 : JSObject *parent;
325 : };
326 :
327 : struct Shape {
328 : BaseShape *base;
329 : jsid _1;
330 : uint32_t slotInfo;
331 :
332 : static const uint32_t FIXED_SLOTS_SHIFT = 27;
333 : };
334 :
335 : struct Object {
336 : Shape *shape;
337 : TypeObject *type;
338 : js::Value *slots;
339 : js::Value *_1;
340 :
341 1658690167 : size_t numFixedSlots() const { return shape->slotInfo >> Shape::FIXED_SLOTS_SHIFT; }
342 979400 : Value *fixedSlots() const {
343 979400 : return (Value *)(uintptr_t(this) + sizeof(shadow::Object));
344 : }
345 :
346 979436 : js::Value &slotRef(size_t slot) const {
347 979436 : size_t nfixed = numFixedSlots();
348 979436 : if (slot < nfixed)
349 979400 : return fixedSlots()[slot];
350 36 : return slots[slot - nfixed];
351 : }
352 : };
353 :
354 : struct Atom {
355 : size_t _;
356 : const jschar *chars;
357 : };
358 :
359 : } /* namespace shadow */
360 :
361 : extern JS_FRIEND_DATA(js::Class) AnyNameClass;
362 : extern JS_FRIEND_DATA(js::Class) AttributeNameClass;
363 : extern JS_FRIEND_DATA(js::Class) CallClass;
364 : extern JS_FRIEND_DATA(js::Class) DeclEnvClass;
365 : extern JS_FRIEND_DATA(js::Class) FunctionClass;
366 : extern JS_FRIEND_DATA(js::Class) FunctionProxyClass;
367 : extern JS_FRIEND_DATA(js::Class) NamespaceClass;
368 : extern JS_FRIEND_DATA(js::Class) OuterWindowProxyClass;
369 : extern JS_FRIEND_DATA(js::Class) ObjectProxyClass;
370 : extern JS_FRIEND_DATA(js::Class) QNameClass;
371 : extern JS_FRIEND_DATA(js::Class) XMLClass;
372 : extern JS_FRIEND_DATA(js::Class) ObjectClass;
373 :
374 : inline js::Class *
375 1148269737 : GetObjectClass(const JSObject *obj)
376 : {
377 1148269737 : return reinterpret_cast<const shadow::Object*>(obj)->shape->base->clasp;
378 : }
379 :
380 : inline JSClass *
381 : GetObjectJSClass(const JSObject *obj)
382 : {
383 : return js::Jsvalify(GetObjectClass(obj));
384 : }
385 :
386 : JS_FRIEND_API(bool)
387 : IsScopeObject(JSObject *obj);
388 :
389 : inline JSObject *
390 : GetObjectParent(JSObject *obj)
391 : {
392 : JS_ASSERT(!IsScopeObject(obj));
393 : return reinterpret_cast<shadow::Object*>(obj)->shape->base->parent;
394 : }
395 :
396 : JS_FRIEND_API(JSObject *)
397 : GetObjectParentMaybeScope(JSObject *obj);
398 :
399 : JS_FRIEND_API(JSObject *)
400 : GetGlobalForObjectCrossCompartment(JSObject *obj);
401 :
402 : JS_FRIEND_API(bool)
403 : IsOriginalScriptFunction(JSFunction *fun);
404 :
405 : JS_FRIEND_API(JSFunction *)
406 : DefineFunctionWithReserved(JSContext *cx, JSObject *obj, const char *name, JSNative call,
407 : unsigned nargs, unsigned attrs);
408 :
409 : JS_FRIEND_API(JSFunction *)
410 : NewFunctionWithReserved(JSContext *cx, JSNative call, unsigned nargs, unsigned flags,
411 : JSObject *parent, const char *name);
412 :
413 : JS_FRIEND_API(JSFunction *)
414 : NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
415 : JSObject *parent, jsid id);
416 :
417 : JS_FRIEND_API(JSObject *)
418 : InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
419 : JSClass *clasp, JSNative constructor, unsigned nargs,
420 : JSPropertySpec *ps, JSFunctionSpec *fs,
421 : JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
422 :
423 : JS_FRIEND_API(const Value &)
424 : GetFunctionNativeReserved(JSObject *fun, size_t which);
425 :
426 : JS_FRIEND_API(void)
427 : SetFunctionNativeReserved(JSObject *fun, size_t which, const Value &val);
428 :
429 : inline JSObject *
430 : GetObjectProto(JSObject *obj)
431 : {
432 : return reinterpret_cast<const shadow::Object*>(obj)->type->proto;
433 : }
434 :
435 : inline void *
436 : GetObjectPrivate(JSObject *obj)
437 : {
438 : const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj);
439 : void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
440 : return *addr;
441 : }
442 :
443 : /*
444 : * Get a slot that is both reserved for object's clasp *and* is fixed (fits
445 : * within the maximum capacity for the object's fixed slots).
446 : */
447 : inline const Value &
448 975938 : GetReservedSlot(const JSObject *obj, size_t slot)
449 : {
450 975938 : JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
451 975938 : return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
452 : }
453 :
454 : JS_FRIEND_API(void)
455 : SetReservedSlotWithBarrier(JSObject *obj, size_t slot, const Value &value);
456 :
457 : inline void
458 1749 : SetReservedSlot(JSObject *obj, size_t slot, const Value &value)
459 : {
460 1749 : JS_ASSERT(slot < JSCLASS_RESERVED_SLOTS(GetObjectClass(obj)));
461 1749 : shadow::Object *sobj = reinterpret_cast<shadow::Object *>(obj);
462 1749 : if (sobj->slotRef(slot).isMarkable())
463 0 : SetReservedSlotWithBarrier(obj, slot, value);
464 : else
465 1749 : sobj->slotRef(slot) = value;
466 1749 : }
467 :
468 : JS_FRIEND_API(uint32_t)
469 : GetObjectSlotSpan(JSObject *obj);
470 :
471 : inline const Value &
472 : GetObjectSlot(JSObject *obj, size_t slot)
473 : {
474 : JS_ASSERT(slot < GetObjectSlotSpan(obj));
475 : return reinterpret_cast<const shadow::Object *>(obj)->slotRef(slot);
476 : }
477 :
478 : inline Shape *
479 : GetObjectShape(JSObject *obj)
480 : {
481 : shadow::Shape *shape = reinterpret_cast<const shadow::Object*>(obj)->shape;
482 : return reinterpret_cast<Shape *>(shape);
483 : }
484 :
485 : inline const jschar *
486 : GetAtomChars(JSAtom *atom)
487 : {
488 : return reinterpret_cast<shadow::Atom *>(atom)->chars;
489 : }
490 :
491 : inline JSLinearString *
492 : AtomToLinearString(JSAtom *atom)
493 : {
494 : return reinterpret_cast<JSLinearString *>(atom);
495 : }
496 :
497 : static inline js::PropertyOp
498 : CastAsJSPropertyOp(JSObject *object)
499 : {
500 : return JS_DATA_TO_FUNC_PTR(js::PropertyOp, object);
501 : }
502 :
503 : static inline js::StrictPropertyOp
504 : CastAsJSStrictPropertyOp(JSObject *object)
505 : {
506 : return JS_DATA_TO_FUNC_PTR(js::StrictPropertyOp, object);
507 : }
508 :
509 : JS_FRIEND_API(bool)
510 : GetPropertyNames(JSContext *cx, JSObject *obj, unsigned flags, js::AutoIdVector *props);
511 :
512 : JS_FRIEND_API(bool)
513 : StringIsArrayIndex(JSLinearString *str, uint32_t *indexp);
514 :
515 : JS_FRIEND_API(void)
516 : SetPreserveWrapperCallback(JSRuntime *rt, PreserveWrapperCallback callback);
517 :
518 : JS_FRIEND_API(bool)
519 : IsObjectInContextCompartment(const JSObject *obj, const JSContext *cx);
520 :
521 : /*
522 : * NB: these flag bits are encoded into the bytecode stream in the immediate
523 : * operand of JSOP_ITER, so don't change them without advancing vm/Xdr.h's
524 : * XDR_BYTECODE_VERSION.
525 : */
526 : #define JSITER_ENUMERATE 0x1 /* for-in compatible hidden default iterator */
527 : #define JSITER_FOREACH 0x2 /* return [key, value] pair rather than key */
528 : #define JSITER_KEYVALUE 0x4 /* destructuring for-in wants [key, value] */
529 : #define JSITER_OWNONLY 0x8 /* iterate over obj's own properties only */
530 : #define JSITER_HIDDEN 0x10 /* also enumerate non-enumerable properties */
531 : #define JSITER_FOR_OF 0x20 /* harmony for-of loop */
532 :
533 : inline uintptr_t
534 55520653 : GetNativeStackLimit(const JSRuntime *rt)
535 : {
536 55520653 : return RuntimeFriendFields::get(rt)->nativeStackLimit;
537 : }
538 :
539 : #define JS_CHECK_RECURSION(cx, onerror) \
540 : JS_BEGIN_MACRO \
541 : int stackDummy_; \
542 : if (!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(js::GetRuntime(cx)), &stackDummy_)) { \
543 : js_ReportOverRecursed(cx); \
544 : onerror; \
545 : } \
546 : JS_END_MACRO
547 :
548 : JS_FRIEND_API(void)
549 : StartPCCountProfiling(JSContext *cx);
550 :
551 : JS_FRIEND_API(void)
552 : StopPCCountProfiling(JSContext *cx);
553 :
554 : JS_FRIEND_API(void)
555 : PurgePCCounts(JSContext *cx);
556 :
557 : JS_FRIEND_API(size_t)
558 : GetPCCountScriptCount(JSContext *cx);
559 :
560 : JS_FRIEND_API(JSString *)
561 : GetPCCountScriptSummary(JSContext *cx, size_t script);
562 :
563 : JS_FRIEND_API(JSString *)
564 : GetPCCountScriptContents(JSContext *cx, size_t script);
565 :
566 : #ifdef JS_THREADSAFE
567 : JS_FRIEND_API(void *)
568 : GetOwnerThread(const JSContext *cx);
569 :
570 : JS_FRIEND_API(unsigned)
571 : GetContextOutstandingRequests(const JSContext *cx);
572 :
573 : class JS_FRIEND_API(AutoSkipConservativeScan)
574 : {
575 : public:
576 : AutoSkipConservativeScan(JSContext *cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
577 : ~AutoSkipConservativeScan();
578 :
579 : private:
580 : JSContext *context;
581 : MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
582 : };
583 : #endif
584 :
585 : JS_FRIEND_API(JSCompartment *)
586 : GetContextCompartment(const JSContext *cx);
587 :
588 : JS_FRIEND_API(bool)
589 : HasUnrootedGlobal(const JSContext *cx);
590 :
591 : typedef void
592 : (* ActivityCallback)(void *arg, JSBool active);
593 :
594 : /*
595 : * Sets a callback that is run whenever the runtime goes idle - the
596 : * last active request ceases - and begins activity - when it was
597 : * idle and a request begins.
598 : */
599 : JS_FRIEND_API(void)
600 : SetActivityCallback(JSRuntime *rt, ActivityCallback cb, void *arg);
601 :
602 : extern JS_FRIEND_API(const JSStructuredCloneCallbacks *)
603 : GetContextStructuredCloneCallbacks(JSContext *cx);
604 :
605 : extern JS_FRIEND_API(JSVersion)
606 : VersionSetXML(JSVersion version, bool enable);
607 :
608 : extern JS_FRIEND_API(bool)
609 : CanCallContextDebugHandler(JSContext *cx);
610 :
611 : extern JS_FRIEND_API(JSTrapStatus)
612 : CallContextDebugHandler(JSContext *cx, JSScript *script, jsbytecode *bc, Value *rval);
613 :
614 : extern JS_FRIEND_API(bool)
615 : IsContextRunningJS(JSContext *cx);
616 :
617 : class SystemAllocPolicy;
618 : typedef Vector<JSCompartment*, 0, SystemAllocPolicy> CompartmentVector;
619 : extern JS_FRIEND_API(const CompartmentVector&)
620 : GetRuntimeCompartments(JSRuntime *rt);
621 :
622 : extern JS_FRIEND_API(size_t)
623 : SizeOfJSContext();
624 :
625 : #define GCREASONS(D) \
626 : /* Reasons internal to the JS engine */ \
627 : D(API) \
628 : D(MAYBEGC) \
629 : D(LAST_CONTEXT) \
630 : D(DESTROY_CONTEXT) \
631 : D(LAST_DITCH) \
632 : D(TOO_MUCH_MALLOC) \
633 : D(ALLOC_TRIGGER) \
634 : D(DEBUG_GC) \
635 : D(UNUSED2) /* was SHAPE */ \
636 : D(UNUSED3) /* was REFILL */ \
637 : \
638 : /* Reasons from Firefox */ \
639 : D(DOM_WINDOW_UTILS) \
640 : D(COMPONENT_UTILS) \
641 : D(MEM_PRESSURE) \
642 : D(CC_WAITING) \
643 : D(CC_FORCED) \
644 : D(LOAD_END) \
645 : D(POST_COMPARTMENT) \
646 : D(PAGE_HIDE) \
647 : D(NSJSCONTEXT_DESTROY) \
648 : D(SET_NEW_DOCUMENT) \
649 : D(SET_DOC_SHELL) \
650 : D(DOM_UTILS) \
651 : D(DOM_IPC) \
652 : D(DOM_WORKER) \
653 : D(INTER_SLICE_GC) \
654 : D(REFRESH_FRAME)
655 :
656 : namespace gcreason {
657 :
658 : /* GCReasons will end up looking like JSGC_MAYBEGC */
659 : enum Reason {
660 : #define MAKE_REASON(name) name,
661 : GCREASONS(MAKE_REASON)
662 : #undef MAKE_REASON
663 : NO_REASON,
664 : NUM_REASONS
665 : };
666 :
667 : } /* namespace gcreason */
668 :
669 : extern JS_FRIEND_API(void)
670 : PrepareCompartmentForGC(JSCompartment *comp);
671 :
672 : extern JS_FRIEND_API(void)
673 : PrepareForFullGC(JSRuntime *rt);
674 :
675 : /*
676 : * When triggering a GC using one of the functions below, it is first necessary
677 : * to select the compartments to be collected. To do this, you can call
678 : * PrepareCompartmentForGC on each compartment, or you can call PrepareForFullGC
679 : * to select all compartments. Failing to select any compartment is an error.
680 : */
681 :
682 : extern JS_FRIEND_API(void)
683 : GCForReason(JSContext *cx, gcreason::Reason reason);
684 :
685 : extern JS_FRIEND_API(void)
686 : ShrinkingGC(JSContext *cx, gcreason::Reason reason);
687 :
688 : extern JS_FRIEND_API(void)
689 : IncrementalGC(JSContext *cx, gcreason::Reason reason);
690 :
691 : extern JS_FRIEND_API(void)
692 : SetGCSliceTimeBudget(JSContext *cx, int64_t millis);
693 :
694 : enum GCProgress {
695 : /*
696 : * During non-incremental GC, the GC is bracketed by JSGC_CYCLE_BEGIN/END
697 : * callbacks. During an incremental GC, the sequence of callbacks is as
698 : * follows:
699 : * JSGC_CYCLE_BEGIN, JSGC_SLICE_END (first slice)
700 : * JSGC_SLICE_BEGIN, JSGC_SLICE_END (second slice)
701 : * ...
702 : * JSGC_SLICE_BEGIN, JSGC_CYCLE_END (last slice)
703 : */
704 :
705 : GC_CYCLE_BEGIN,
706 : GC_SLICE_BEGIN,
707 : GC_SLICE_END,
708 : GC_CYCLE_END
709 : };
710 :
711 : struct JS_FRIEND_API(GCDescription) {
712 : bool isCompartment;
713 :
714 0 : GCDescription(bool isCompartment)
715 0 : : isCompartment(isCompartment) {}
716 :
717 : jschar *formatMessage(JSRuntime *rt) const;
718 : jschar *formatJSON(JSRuntime *rt, uint64_t timestamp) const;
719 : };
720 :
721 : typedef void
722 : (* GCSliceCallback)(JSRuntime *rt, GCProgress progress, const GCDescription &desc);
723 :
724 : extern JS_FRIEND_API(GCSliceCallback)
725 : SetGCSliceCallback(JSRuntime *rt, GCSliceCallback callback);
726 :
727 : extern JS_FRIEND_API(bool)
728 : WantGCSlice(JSRuntime *rt);
729 :
730 : /*
731 : * Signals a good place to do an incremental slice, because the browser is
732 : * drawing a frame.
733 : */
734 : extern JS_FRIEND_API(void)
735 : NotifyDidPaint(JSContext *cx);
736 :
737 : extern JS_FRIEND_API(bool)
738 : IsIncrementalGCEnabled(JSRuntime *rt);
739 :
740 : extern JS_FRIEND_API(void)
741 : DisableIncrementalGC(JSRuntime *rt);
742 :
743 : extern JS_FRIEND_API(bool)
744 : IsIncrementalBarrierNeeded(JSRuntime *rt);
745 :
746 : extern JS_FRIEND_API(bool)
747 : IsIncrementalBarrierNeeded(JSContext *cx);
748 :
749 : extern JS_FRIEND_API(bool)
750 : IsIncrementalBarrierNeededOnObject(JSObject *obj);
751 :
752 : extern JS_FRIEND_API(void)
753 : IncrementalReferenceBarrier(void *ptr);
754 :
755 : extern JS_FRIEND_API(void)
756 : IncrementalValueBarrier(const Value &v);
757 :
758 : class ObjectPtr
759 : {
760 : JSObject *value;
761 :
762 : public:
763 : ObjectPtr() : value(NULL) {}
764 :
765 : ObjectPtr(JSObject *obj) : value(obj) {}
766 :
767 : /* Always call finalize before the destructor. */
768 : ~ObjectPtr() { JS_ASSERT(!value); }
769 :
770 : void finalize(JSRuntime *rt) {
771 : if (IsIncrementalBarrierNeeded(rt))
772 : IncrementalReferenceBarrier(value);
773 : value = NULL;
774 : }
775 :
776 : void init(JSObject *obj) { value = obj; }
777 :
778 : JSObject *get() const { return value; }
779 :
780 : void writeBarrierPre(JSRuntime *rt) {
781 : IncrementalReferenceBarrier(value);
782 : }
783 :
784 : ObjectPtr &operator=(JSObject *obj) {
785 : IncrementalReferenceBarrier(value);
786 : value = obj;
787 : return *this;
788 : }
789 :
790 : JSObject &operator*() const { return *value; }
791 : JSObject *operator->() const { return value; }
792 : operator JSObject *() const { return value; }
793 : };
794 :
795 : extern JS_FRIEND_API(JSObject *)
796 : GetTestingFunctions(JSContext *cx);
797 :
798 : /*
799 : * Helper to convert FreeOp to JSFreeOp when the definition of FreeOp is not
800 : * available and the compiler does not know that FreeOp inherits from
801 : * JSFreeOp.
802 : */
803 : inline JSFreeOp *
804 : CastToJSFreeOp(FreeOp *fop)
805 : {
806 : return reinterpret_cast<JSFreeOp *>(fop);
807 : }
808 :
809 : } /* namespace js */
810 :
811 : #endif
812 :
813 : /* Implemented in jsdate.cpp. */
814 :
815 : /*
816 : * Detect whether the internal date value is NaN. (Because failure is
817 : * out-of-band for js_DateGet*)
818 : */
819 : extern JS_FRIEND_API(JSBool)
820 : js_DateIsValid(JSContext *cx, JSObject* obj);
821 :
822 : extern JS_FRIEND_API(double)
823 : js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj);
824 :
825 : /* Implemented in jscntxt.cpp. */
826 :
827 : /*
828 : * Report an exception, which is currently realized as a printf-style format
829 : * string and its arguments.
830 : */
831 : typedef enum JSErrNum {
832 : #define MSG_DEF(name, number, count, exception, format) \
833 : name = number,
834 : #include "js.msg"
835 : #undef MSG_DEF
836 : JSErr_Limit
837 : } JSErrNum;
838 :
839 : extern JS_FRIEND_API(const JSErrorFormatString *)
840 : js_GetErrorMessage(void *userRef, const char *locale, const unsigned errorNumber);
841 :
842 : /* Implemented in jsclone.cpp. */
843 :
844 : extern JS_FRIEND_API(uint64_t)
845 : js_GetSCOffset(JSStructuredCloneWriter* writer);
846 :
847 : #endif /* jsfriendapi_h___ */
|