Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef js_OldDebugAPI_h
8 #define js_OldDebugAPI_h
10 /*
11 * JS debugger API.
12 */
14 #include "mozilla/NullPtr.h"
16 #include "jsapi.h"
17 #include "jsbytecode.h"
19 #include "js/CallArgs.h"
20 #include "js/TypeDecls.h"
22 class JSAtom;
23 class JSFreeOp;
25 namespace js {
26 class InterpreterFrame;
27 class ScriptFrameIter;
28 }
30 // Raw JSScript* because this needs to be callable from a signal handler.
31 extern JS_PUBLIC_API(unsigned)
32 JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc);
34 extern JS_PUBLIC_API(const char *)
35 JS_GetScriptFilename(JSScript *script);
37 namespace JS {
39 class FrameDescription
40 {
41 public:
42 explicit FrameDescription(const js::ScriptFrameIter& iter);
44 unsigned lineno() {
45 if (!linenoComputed) {
46 lineno_ = JS_PCToLineNumber(nullptr, script_, pc_);
47 linenoComputed = true;
48 }
49 return lineno_;
50 }
52 const char *filename() const {
53 return JS_GetScriptFilename(script_);
54 }
56 JSFlatString *funDisplayName() const {
57 return funDisplayName_ ? JS_ASSERT_STRING_IS_FLAT(funDisplayName_) : nullptr;
58 }
60 // Both these locations should be traced during GC but otherwise not used;
61 // they are implementation details.
62 Heap<JSScript*> &markedLocation1() {
63 return script_;
64 }
65 Heap<JSString*> &markedLocation2() {
66 return funDisplayName_;
67 }
69 private:
70 Heap<JSScript*> script_;
71 Heap<JSString*> funDisplayName_;
72 jsbytecode *pc_;
73 unsigned lineno_;
74 bool linenoComputed;
75 };
77 struct StackDescription
78 {
79 unsigned nframes;
80 FrameDescription *frames;
81 };
83 extern JS_PUBLIC_API(StackDescription *)
84 DescribeStack(JSContext *cx, unsigned maxFrames);
86 extern JS_PUBLIC_API(void)
87 FreeStackDescription(JSContext *cx, StackDescription *desc);
89 extern JS_PUBLIC_API(char *)
90 FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps);
92 } // namespace JS
94 # ifdef JS_DEBUG
95 JS_FRIEND_API(void) js_DumpValue(const JS::Value &val);
96 JS_FRIEND_API(void) js_DumpId(jsid id);
97 JS_FRIEND_API(void) js_DumpInterpreterFrame(JSContext *cx, js::InterpreterFrame *start = nullptr);
98 # endif
100 JS_FRIEND_API(void)
101 js_DumpBacktrace(JSContext *cx);
103 typedef enum JSTrapStatus {
104 JSTRAP_ERROR,
105 JSTRAP_CONTINUE,
106 JSTRAP_RETURN,
107 JSTRAP_THROW,
108 JSTRAP_LIMIT
109 } JSTrapStatus;
111 typedef JSTrapStatus
112 (* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
113 JS::Value closure);
115 typedef JSTrapStatus
116 (* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
117 void *closure);
119 typedef JSTrapStatus
120 (* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
121 void *closure);
123 typedef JSTrapStatus
124 (* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
125 void *closure);
127 typedef bool
128 (* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, JS::Value old,
129 JS::Value *newp, void *closure);
131 /* called just after script creation */
132 typedef void
133 (* JSNewScriptHook)(JSContext *cx,
134 const char *filename, /* URL of script */
135 unsigned lineno, /* first line */
136 JSScript *script,
137 JSFunction *fun,
138 void *callerdata);
140 /* called just before script destruction */
141 typedef void
142 (* JSDestroyScriptHook)(JSFreeOp *fop,
143 JSScript *script,
144 void *callerdata);
146 typedef void
147 (* JSSourceHandler)(const char *filename, unsigned lineno, const jschar *str,
148 size_t length, void **listenerTSData, void *closure);
152 extern JS_PUBLIC_API(JSCompartment *)
153 JS_EnterCompartmentOfScript(JSContext *cx, JSScript *target);
155 extern JS_PUBLIC_API(JSString *)
156 JS_DecompileScript(JSContext *cx, JS::HandleScript script, const char *name, unsigned indent);
158 /*
159 * Currently, we only support runtime-wide debugging. In the future, we should
160 * be able to support compartment-wide debugging.
161 */
162 extern JS_PUBLIC_API(void)
163 JS_SetRuntimeDebugMode(JSRuntime *rt, bool debug);
165 /*
166 * Debug mode is a compartment-wide mode that enables a debugger to attach
167 * to and interact with running methodjit-ed frames. In particular, it causes
168 * every function to be compiled as if an eval was present (so eval-in-frame)
169 * can work, and it ensures that functions can be re-JITed for other debug
170 * features. In general, it is not safe to interact with frames that were live
171 * before debug mode was enabled. For this reason, it is also not safe to
172 * enable debug mode while frames are live.
173 */
175 /* Get current state of debugging mode. */
176 extern JS_PUBLIC_API(bool)
177 JS_GetDebugMode(JSContext *cx);
179 /*
180 * Turn on/off debugging mode for all compartments. This returns false if any code
181 * from any of the runtime's compartments is running or on the stack.
182 */
183 JS_FRIEND_API(bool)
184 JS_SetDebugModeForAllCompartments(JSContext *cx, bool debug);
186 /*
187 * Turn on/off debugging mode for a single compartment. This should only be
188 * used when no code from this compartment is running or on the stack in any
189 * thread.
190 */
191 JS_FRIEND_API(bool)
192 JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, bool debug);
194 /*
195 * Turn on/off debugging mode for a context's compartment.
196 */
197 JS_FRIEND_API(bool)
198 JS_SetDebugMode(JSContext *cx, bool debug);
200 /* Turn on single step mode. */
201 extern JS_PUBLIC_API(bool)
202 JS_SetSingleStepMode(JSContext *cx, JS::HandleScript script, bool singleStep);
204 /* The closure argument will be marked. */
205 extern JS_PUBLIC_API(bool)
206 JS_SetTrap(JSContext *cx, JS::HandleScript script, jsbytecode *pc,
207 JSTrapHandler handler, JS::HandleValue closure);
209 extern JS_PUBLIC_API(void)
210 JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
211 JSTrapHandler *handlerp, JS::Value *closurep);
213 extern JS_PUBLIC_API(void)
214 JS_ClearScriptTraps(JSRuntime *rt, JSScript *script);
216 extern JS_PUBLIC_API(void)
217 JS_ClearAllTrapsForCompartment(JSContext *cx);
219 extern JS_PUBLIC_API(bool)
220 JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure);
222 extern JS_PUBLIC_API(bool)
223 JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep);
225 /************************************************************************/
227 extern JS_PUBLIC_API(bool)
228 JS_SetWatchPoint(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
229 JSWatchPointHandler handler, JS::HandleObject closure);
231 extern JS_PUBLIC_API(bool)
232 JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsid id,
233 JSWatchPointHandler *handlerp, JSObject **closurep);
235 extern JS_PUBLIC_API(bool)
236 JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj);
238 /************************************************************************/
240 extern JS_PUBLIC_API(jsbytecode *)
241 JS_LineNumberToPC(JSContext *cx, JSScript *script, unsigned lineno);
243 extern JS_PUBLIC_API(jsbytecode *)
244 JS_EndPC(JSContext *cx, JSScript *script);
246 extern JS_PUBLIC_API(bool)
247 JS_GetLinePCs(JSContext *cx, JSScript *script,
248 unsigned startLine, unsigned maxLines,
249 unsigned* count, unsigned** lines, jsbytecode*** pcs);
251 extern JS_PUBLIC_API(unsigned)
252 JS_GetFunctionArgumentCount(JSContext *cx, JSFunction *fun);
254 extern JS_PUBLIC_API(bool)
255 JS_FunctionHasLocalNames(JSContext *cx, JSFunction *fun);
257 /*
258 * N.B. The mark is in the context temp pool and thus the caller must take care
259 * to call JS_ReleaseFunctionLocalNameArray in a LIFO manner (wrt to any other
260 * call that may use the temp pool.
261 */
262 extern JS_PUBLIC_API(uintptr_t *)
263 JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp);
265 extern JS_PUBLIC_API(JSAtom *)
266 JS_LocalNameToAtom(uintptr_t w);
268 extern JS_PUBLIC_API(JSString *)
269 JS_AtomKey(JSAtom *atom);
271 extern JS_PUBLIC_API(void)
272 JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark);
274 extern JS_PUBLIC_API(JSScript *)
275 JS_GetFunctionScript(JSContext *cx, JS::HandleFunction fun);
277 extern JS_PUBLIC_API(JSNative)
278 JS_GetFunctionNative(JSContext *cx, JSFunction *fun);
280 extern JS_PUBLIC_API(JSPrincipals *)
281 JS_GetScriptPrincipals(JSScript *script);
283 extern JS_PUBLIC_API(JSPrincipals *)
284 JS_GetScriptOriginPrincipals(JSScript *script);
286 JS_PUBLIC_API(JSFunction *)
287 JS_GetScriptFunction(JSContext *cx, JSScript *script);
289 extern JS_PUBLIC_API(JSObject *)
290 JS_GetParentOrScopeChain(JSContext *cx, JSObject *obj);
292 /************************************************************************/
294 /*
295 * This is almost JS_GetClass(obj)->name except that certain debug-only
296 * proxies are made transparent. In particular, this function turns the class
297 * of any scope (returned via JS_GetFrameScopeChain or JS_GetFrameCalleeObject)
298 * from "Proxy" to "Call", "Block", "With" etc.
299 */
300 extern JS_PUBLIC_API(const char *)
301 JS_GetDebugClassName(JSObject *obj);
303 /************************************************************************/
305 extern JS_PUBLIC_API(const jschar *)
306 JS_GetScriptSourceMap(JSContext *cx, JSScript *script);
308 extern JS_PUBLIC_API(unsigned)
309 JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script);
311 extern JS_PUBLIC_API(unsigned)
312 JS_GetScriptLineExtent(JSContext *cx, JSScript *script);
314 extern JS_PUBLIC_API(JSVersion)
315 JS_GetScriptVersion(JSContext *cx, JSScript *script);
317 extern JS_PUBLIC_API(bool)
318 JS_GetScriptIsSelfHosted(JSScript *script);
320 /************************************************************************/
322 /*
323 * Hook setters for script creation and destruction. These macros provide
324 * binary compatibility and newer, shorter synonyms.
325 */
326 #define JS_SetNewScriptHook JS_SetNewScriptHookProc
327 #define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc
329 extern JS_PUBLIC_API(void)
330 JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata);
332 extern JS_PUBLIC_API(void)
333 JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
334 void *callerdata);
336 /************************************************************************/
338 typedef struct JSPropertyDesc {
339 JS::Value id; /* primary id, atomized string, or int */
340 JS::Value value; /* property value */
341 uint8_t flags; /* flags, see below */
342 uint8_t spare; /* unused */
343 JS::Value alias; /* alias id if JSPD_ALIAS flag */
344 } JSPropertyDesc;
346 #define JSPD_ENUMERATE 0x01 /* visible to for/in loop */
347 #define JSPD_READONLY 0x02 /* assignment is error */
348 #define JSPD_PERMANENT 0x04 /* property cannot be deleted */
349 #define JSPD_ALIAS 0x08 /* property has an alias id */
350 #define JSPD_EXCEPTION 0x40 /* exception occurred fetching the property, */
351 /* value is exception */
352 #define JSPD_ERROR 0x80 /* native getter returned false without */
353 /* throwing an exception */
355 typedef struct JSPropertyDescArray {
356 uint32_t length; /* number of elements in array */
357 JSPropertyDesc *array; /* alloc'd by Get, freed by Put */
358 } JSPropertyDescArray;
360 typedef struct JSScopeProperty JSScopeProperty;
362 extern JS_PUBLIC_API(bool)
363 JS_GetPropertyDescArray(JSContext *cx, JS::HandleObject obj, JSPropertyDescArray *pda);
365 extern JS_PUBLIC_API(void)
366 JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda);
368 /************************************************************************/
370 /*
371 * JSAbstractFramePtr is the public version of AbstractFramePtr, a pointer to a
372 * StackFrame or baseline JIT frame.
373 */
374 class JS_PUBLIC_API(JSAbstractFramePtr)
375 {
376 uintptr_t ptr_;
377 jsbytecode *pc_;
379 protected:
380 JSAbstractFramePtr()
381 : ptr_(0), pc_(nullptr)
382 { }
384 public:
385 JSAbstractFramePtr(void *raw, jsbytecode *pc);
387 uintptr_t raw() const { return ptr_; }
388 jsbytecode *pc() const { return pc_; }
390 operator bool() const { return !!ptr_; }
392 JSObject *scopeChain(JSContext *cx);
393 JSObject *callObject(JSContext *cx);
395 JSFunction *maybeFun();
396 JSScript *script();
398 bool getThisValue(JSContext *cx, JS::MutableHandleValue thisv);
400 bool isDebuggerFrame();
402 bool evaluateInStackFrame(JSContext *cx,
403 const char *bytes, unsigned length,
404 const char *filename, unsigned lineno,
405 JS::MutableHandleValue rval);
407 bool evaluateUCInStackFrame(JSContext *cx,
408 const jschar *chars, unsigned length,
409 const char *filename, unsigned lineno,
410 JS::MutableHandleValue rval);
411 };
413 class JS_PUBLIC_API(JSNullFramePtr) : public JSAbstractFramePtr
414 {
415 public:
416 JSNullFramePtr()
417 : JSAbstractFramePtr()
418 {}
419 };
421 /*
422 * This class does not work when IonMonkey is active. It's only used by jsd,
423 * which can only be used when IonMonkey is disabled.
424 *
425 * To find the calling script and line number, use JS_DescribeSciptedCaller.
426 * To summarize the call stack, use JS::DescribeStack.
427 */
428 class JS_PUBLIC_API(JSBrokenFrameIterator)
429 {
430 void *data_;
432 public:
433 JSBrokenFrameIterator(JSContext *cx);
434 ~JSBrokenFrameIterator();
436 bool done() const;
437 JSBrokenFrameIterator& operator++();
439 JSAbstractFramePtr abstractFramePtr() const;
440 jsbytecode *pc() const;
442 bool isConstructing() const;
443 };
445 /*
446 * This hook captures high level script execution and function calls (JS or
447 * native). It is used by JS_SetExecuteHook to hook top level scripts and by
448 * JS_SetCallHook to hook function calls. It will get called twice per script
449 * or function call: just before execution begins and just after it finishes.
450 * In both cases the 'current' frame is that of the executing code.
451 *
452 * The 'before' param is true for the hook invocation before the execution
453 * and false for the invocation after the code has run.
454 *
455 * The 'ok' param is significant only on the post execution invocation to
456 * signify whether or not the code completed 'normally'.
457 *
458 * The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
459 * for the 'before'invocation, but is whatever value is returned from that
460 * invocation for the 'after' invocation. Thus, the hook implementor *could*
461 * allocate a structure in the 'before' invocation and return a pointer to that
462 * structure. The pointer would then be handed to the hook for the 'after'
463 * invocation. Alternately, the 'before' could just return the same value as
464 * in 'closure' to cause the 'after' invocation to be called with the same
465 * 'closure' value as the 'before'.
466 *
467 * Returning nullptr in the 'before' hook will cause the 'after' hook *not* to
468 * be called.
469 */
470 typedef void *
471 (* JSInterpreterHook)(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing,
472 bool before, bool *ok, void *closure);
474 typedef bool
475 (* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report,
476 void *closure);
478 typedef struct JSDebugHooks {
479 JSInterruptHook interruptHook;
480 void *interruptHookData;
481 JSNewScriptHook newScriptHook;
482 void *newScriptHookData;
483 JSDestroyScriptHook destroyScriptHook;
484 void *destroyScriptHookData;
485 JSDebuggerHandler debuggerHandler;
486 void *debuggerHandlerData;
487 JSSourceHandler sourceHandler;
488 void *sourceHandlerData;
489 JSInterpreterHook executeHook;
490 void *executeHookData;
491 JSInterpreterHook callHook;
492 void *callHookData;
493 JSThrowHook throwHook;
494 void *throwHookData;
495 JSDebugErrorHook debugErrorHook;
496 void *debugErrorHookData;
497 } JSDebugHooks;
499 /************************************************************************/
501 extern JS_PUBLIC_API(bool)
502 JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure);
504 extern JS_PUBLIC_API(bool)
505 JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
507 extern JS_PUBLIC_API(bool)
508 JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
510 extern JS_PUBLIC_API(bool)
511 JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
513 extern JS_PUBLIC_API(bool)
514 JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure);
516 extern JS_PUBLIC_API(bool)
517 JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
519 /************************************************************************/
521 extern JS_PUBLIC_API(const JSDebugHooks *)
522 JS_GetGlobalDebugHooks(JSRuntime *rt);
524 /**
525 * Add various profiling-related functions as properties of the given object.
526 */
527 extern JS_PUBLIC_API(bool)
528 JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
530 /* Defined in vm/Debugger.cpp. */
531 extern JS_PUBLIC_API(bool)
532 JS_DefineDebuggerObject(JSContext *cx, JS::HandleObject obj);
534 extern JS_PUBLIC_API(void)
535 JS_DumpPCCounts(JSContext *cx, JS::HandleScript script);
537 extern JS_PUBLIC_API(void)
538 JS_DumpCompartmentPCCounts(JSContext *cx);
540 namespace js {
541 extern JS_FRIEND_API(bool)
542 CanCallContextDebugHandler(JSContext *cx);
543 }
545 /* Call the context debug handler on the topmost scripted frame. */
546 extern JS_FRIEND_API(bool)
547 js_CallContextDebugHandler(JSContext *cx);
549 #endif /* js_OldDebugAPI_h */