mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1083210 - Part 1: Add a Debugger.prototype.onNewPromise hook. r=shu
This commit is contained in:
parent
323ef5978b
commit
019d6491e6
@ -263,6 +263,23 @@ class BuilderOrigin : public Builder {
|
||||
// malloc'd blocks.
|
||||
void SetDebuggerMallocSizeOf(JSRuntime *runtime, mozilla::MallocSizeOf mallocSizeOf);
|
||||
|
||||
|
||||
// Handlers for observing Promises
|
||||
// -------------------------------
|
||||
//
|
||||
// The Debugger wants to observe behavior of promises, which are implemented by
|
||||
// Gecko with webidl and which SpiderMonkey knows nothing about. On the other
|
||||
// hand, Gecko knows nothing about which (if any) debuggers are observing a
|
||||
// promise's global. The compromise is that Gecko is responsible for calling
|
||||
// these handlers at the appropriate times, and SpiderMonkey will handle
|
||||
// notifying any Debugger instances that are observing the given promise's
|
||||
// global.
|
||||
|
||||
// Notify any Debugger instances observing this promise's global that a new
|
||||
// promise was allocated.
|
||||
JS_PUBLIC_API(void)
|
||||
onNewPromise(JSContext *cx, HandleObject promise);
|
||||
|
||||
} // namespace dbg
|
||||
} // namespace JS
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "asmjs/AsmJSLink.h"
|
||||
#include "asmjs/AsmJSValidate.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "js/StructuredClone.h"
|
||||
#include "js/UbiNode.h"
|
||||
@ -956,6 +957,34 @@ OOMAfterAllocations(JSContext *cx, unsigned argc, jsval *vp)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const JSClass FakePromiseClass = {
|
||||
"Promise", JSCLASS_IS_ANONYMOUS,
|
||||
JS_PropertyStub, /* addProperty */
|
||||
JS_DeletePropertyStub, /* delProperty */
|
||||
JS_PropertyStub, /* getProperty */
|
||||
JS_StrictPropertyStub, /* setProperty */
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub
|
||||
};
|
||||
|
||||
static bool
|
||||
MakeFakePromise(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject scope(cx, cx->global());
|
||||
if (!scope)
|
||||
return false;
|
||||
|
||||
RootedObject obj(cx, JS_NewObjectWithGivenProto(cx, &FakePromiseClass, JS::NullPtr(), scope));
|
||||
if (!obj)
|
||||
return false;
|
||||
|
||||
JS::dbg::onNewPromise(cx, obj);
|
||||
args.rval().setObject(*obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
static unsigned finalizeCount = 0;
|
||||
|
||||
static void
|
||||
@ -2235,6 +2264,12 @@ static const JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
" (return NULL)."),
|
||||
#endif
|
||||
|
||||
JS_FN_HELP("makeFakePromise", MakeFakePromise, 0, 0,
|
||||
"makeFakePromise()",
|
||||
" Create an object whose [[Class]] name is 'Promise' and call\n"
|
||||
" JS::dbg::onNewPromise on it before returning it. It doesn't actually have\n"
|
||||
" any of the other behavior associated with promises."),
|
||||
|
||||
JS_FN_HELP("makeFinalizeObserver", MakeFinalizeObserver, 0, 0,
|
||||
"makeFinalizeObserver()",
|
||||
" Get a special object whose finalization increases the counter returned\n"
|
||||
|
@ -81,12 +81,20 @@ compartment.
|
||||
|
||||
<code>onNewScript(<i>script</i>, <i>global</i>)</code>
|
||||
: New code, represented by the [`Debugger.Script`][script] instance
|
||||
<i>script</i>, has been loaded in the scope of the debuggee global
|
||||
object <i>global</i>. <i>global</i> is a [`Debugger.Object`][object]
|
||||
instance whose referent is the global object.
|
||||
<i>script</i>, has been loaded in the scope of the debuggees.
|
||||
|
||||
This method's return value is ignored.
|
||||
|
||||
<code>onNewPromise(<i>promise</i>)</code>
|
||||
: A new Promise object, referenced by the [`Debugger.Object`][object] instance
|
||||
*promise*, has been allocated in the scope of the debuggees.
|
||||
|
||||
This handler method should return a [resumption value][rv] specifying how
|
||||
the debuggee's execution should proceed. However, note that a <code>{ return:
|
||||
<i>value</i> }</code> resumption value is treated like `undefined` ("continue
|
||||
normally"); <i>value</i> is ignored. (Allowing the handler to substitute
|
||||
its own value for the new global object doesn't seem useful.)
|
||||
|
||||
<code>onDebuggerStatement(<i>frame</i>)</code>
|
||||
: Debuggee code has executed a <i>debugger</i> statement in <i>frame</i>.
|
||||
This method should return a [resumption value][rv] specifying how the
|
||||
|
17
js/src/jit-test/tests/debug/Debugger-onNewPromise-01.js
Normal file
17
js/src/jit-test/tests/debug/Debugger-onNewPromise-01.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Test that the onNewPromise hook gets called when promises are allocated in
|
||||
// the scope of debuggee globals.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger();
|
||||
var gw = dbg.addDebuggee(g);
|
||||
|
||||
|
||||
let promisesFound = [];
|
||||
dbg.onNewPromise = p => { promisesFound.push(p); };
|
||||
|
||||
let p1 = g.makeFakePromise()
|
||||
dbg.enabled = false;
|
||||
let p2 = g.makeFakePromise();
|
||||
|
||||
assertEq(promisesFound.indexOf(gw.makeDebuggeeValue(p1)) != -1, true);
|
||||
assertEq(promisesFound.indexOf(gw.makeDebuggeeValue(p2)) == -1, true);
|
24
js/src/jit-test/tests/debug/Debugger-onNewPromise-02.js
Normal file
24
js/src/jit-test/tests/debug/Debugger-onNewPromise-02.js
Normal file
@ -0,0 +1,24 @@
|
||||
// onNewPromise handlers fire, until they are removed.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
var log;
|
||||
|
||||
log = '';
|
||||
g.makeFakePromise();
|
||||
assertEq(log, '');
|
||||
|
||||
dbg.onNewPromise = function (promise) {
|
||||
log += 'n';
|
||||
assertEq(promise.seen, undefined);
|
||||
promise.seen = true;
|
||||
};
|
||||
|
||||
log = '';
|
||||
g.makeFakePromise();
|
||||
assertEq(log, 'n');
|
||||
|
||||
log = '';
|
||||
dbg.onNewPromise = undefined;
|
||||
g.makeFakePromise();
|
||||
assertEq(log, '');
|
41
js/src/jit-test/tests/debug/Debugger-onNewPromise-03.js
Normal file
41
js/src/jit-test/tests/debug/Debugger-onNewPromise-03.js
Normal file
@ -0,0 +1,41 @@
|
||||
// onNewPromise handlers on different Debugger instances are independent.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg1 = new Debugger(g);
|
||||
var log1;
|
||||
function h1(promise) {
|
||||
log1 += 'n';
|
||||
assertEq(promise.seen, undefined);
|
||||
promise.seen = true;
|
||||
}
|
||||
|
||||
var dbg2 = new Debugger(g);
|
||||
var log2;
|
||||
function h2(promise) {
|
||||
log2 += 'n';
|
||||
assertEq(promise.seen, undefined);
|
||||
promise.seen = true;
|
||||
}
|
||||
|
||||
log1 = log2 = '';
|
||||
g.makeFakePromise();
|
||||
assertEq(log1, '');
|
||||
assertEq(log2, '');
|
||||
|
||||
log1 = log2 = '';
|
||||
dbg1.onNewPromise = h1;
|
||||
g.makeFakePromise();
|
||||
assertEq(log1, 'n');
|
||||
assertEq(log2, '');
|
||||
|
||||
log1 = log2 = '';
|
||||
dbg2.onNewPromise = h2;
|
||||
g.makeFakePromise();
|
||||
assertEq(log1, 'n');
|
||||
assertEq(log2, 'n');
|
||||
|
||||
log1 = log2 = '';
|
||||
dbg1.onNewPromise = undefined;
|
||||
g.makeFakePromise();
|
||||
assertEq(log1, '');
|
||||
assertEq(log2, 'n');
|
15
js/src/jit-test/tests/debug/Debugger-onNewPromise-04.js
Normal file
15
js/src/jit-test/tests/debug/Debugger-onNewPromise-04.js
Normal file
@ -0,0 +1,15 @@
|
||||
// An onNewPromise handler can disable itself.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
var log;
|
||||
|
||||
dbg.onNewPromise = function (promise) {
|
||||
log += 'n';
|
||||
dbg.onNewPromise = undefined;
|
||||
};
|
||||
|
||||
log = '';
|
||||
g.makeFakePromise();
|
||||
g.makeFakePromise();
|
||||
assertEq(log, 'n');
|
24
js/src/jit-test/tests/debug/Debugger-onNewPromise-05.js
Normal file
24
js/src/jit-test/tests/debug/Debugger-onNewPromise-05.js
Normal file
@ -0,0 +1,24 @@
|
||||
// Creating a promise within an onNewPromise handler causes a recursive handler
|
||||
// invocation.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
var log;
|
||||
var depth;
|
||||
|
||||
dbg.onNewPromise = function (promise) {
|
||||
log += '('; depth++;
|
||||
|
||||
assertEq(promise.seen, undefined);
|
||||
promise.seen = true;
|
||||
|
||||
if (depth < 3)
|
||||
g.makeFakePromise();
|
||||
|
||||
log += ')'; depth--;
|
||||
};
|
||||
|
||||
log = '';
|
||||
depth = 0;
|
||||
g.makeFakePromise();
|
||||
assertEq(log, '((()))');
|
35
js/src/jit-test/tests/debug/Debugger-onNewPromise-06.js
Normal file
35
js/src/jit-test/tests/debug/Debugger-onNewPromise-06.js
Normal file
@ -0,0 +1,35 @@
|
||||
// Resumption values from onNewPromise handlers are disallowed.
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
var log;
|
||||
|
||||
dbg.onNewPromise = function (g) { log += 'n'; return undefined; };
|
||||
log = '';
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(log, 'n');
|
||||
|
||||
dbg.uncaughtExceptionHook = function (ex) { assertEq(/disallowed/.test(ex), true); log += 'u'; }
|
||||
dbg.onNewPromise = function (g) { log += 'n'; return { return: "snoo" }; };
|
||||
log = '';
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.onNewPromise = function (g) { log += 'n'; return { throw: "snoo" }; };
|
||||
log = '';
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.onNewPromise = function (g) { log += 'n'; return null; };
|
||||
log = '';
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
||||
dbg.uncaughtExceptionHook = function (ex) { assertEq(/foopy/.test(ex), true); log += 'u'; }
|
||||
dbg.onNewPromise = function (g) { log += 'n'; throw "foopy"; };
|
||||
log = '';
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(log, 'nu');
|
||||
|
13
js/src/jit-test/tests/debug/Debugger-onNewPromise-07.js
Normal file
13
js/src/jit-test/tests/debug/Debugger-onNewPromise-07.js
Normal file
@ -0,0 +1,13 @@
|
||||
// Errors in onNewPromise handlers are reported correctly, and don't mess up the
|
||||
// promise creation.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
|
||||
let e;
|
||||
dbg.uncaughtExceptionHook = ee => { e = ee; };
|
||||
dbg.onNewPromise = () => { throw new Error("woops!"); };
|
||||
|
||||
assertEq(typeof g.makeFakePromise(), "object");
|
||||
assertEq(!!e, true);
|
||||
assertEq(!!e.message.match(/woops/), true);
|
@ -46,7 +46,7 @@ js::Debugger::onDebuggerStatement(JSContext *cx, AbstractFramePtr frame, Mutable
|
||||
{
|
||||
MOZ_ASSERT_IF(frame.script()->isDebuggee(), frame.isDebuggee());
|
||||
return frame.isDebuggee()
|
||||
? dispatchHook(cx, vp, OnDebuggerStatement)
|
||||
? dispatchHook(cx, vp, OnDebuggerStatement, NullPtr())
|
||||
: JSTRAP_CONTINUE;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "gc/Marking.h"
|
||||
#include "jit/BaselineDebugModeOSR.h"
|
||||
#include "jit/BaselineJIT.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/UbiNodeTraverse.h"
|
||||
#include "js/Vector.h"
|
||||
@ -691,7 +690,7 @@ JSTrapStatus
|
||||
Debugger::slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
|
||||
{
|
||||
RootedValue rval(cx);
|
||||
JSTrapStatus status = dispatchHook(cx, &rval, OnExceptionUnwind);
|
||||
JSTrapStatus status = dispatchHook(cx, &rval, OnExceptionUnwind, NullPtr());
|
||||
|
||||
switch (status) {
|
||||
case JSTRAP_CONTINUE:
|
||||
@ -1197,9 +1196,11 @@ Debugger::fireNewScript(JSContext *cx, HandleScript script)
|
||||
}
|
||||
|
||||
/* static */ JSTrapStatus
|
||||
Debugger::dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which)
|
||||
Debugger::dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which, HandleObject payload)
|
||||
{
|
||||
MOZ_ASSERT(which == OnDebuggerStatement || which == OnExceptionUnwind);
|
||||
MOZ_ASSERT(which == OnDebuggerStatement ||
|
||||
which == OnExceptionUnwind ||
|
||||
which == OnNewPromise);
|
||||
|
||||
/*
|
||||
* Determine which debuggers will receive this event, and in what order.
|
||||
@ -1228,9 +1229,20 @@ Debugger::dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which)
|
||||
for (Value *p = triggered.begin(); p != triggered.end(); p++) {
|
||||
Debugger *dbg = Debugger::fromJSObject(&p->toObject());
|
||||
if (dbg->debuggees.has(global) && dbg->enabled && dbg->getHook(which)) {
|
||||
JSTrapStatus st = (which == OnDebuggerStatement)
|
||||
? dbg->fireDebuggerStatement(cx, vp)
|
||||
: dbg->fireExceptionUnwind(cx, vp);
|
||||
JSTrapStatus st;
|
||||
switch (which) {
|
||||
case OnDebuggerStatement:
|
||||
st = dbg->fireDebuggerStatement(cx, vp);
|
||||
break;
|
||||
case OnExceptionUnwind:
|
||||
st = dbg->fireExceptionUnwind(cx, vp);
|
||||
break;
|
||||
case OnNewPromise:
|
||||
st = dbg->fireNewPromise(cx, payload, vp);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("Unexpected debugger hook");
|
||||
}
|
||||
if (st != JSTRAP_CONTINUE)
|
||||
return st;
|
||||
}
|
||||
@ -1586,6 +1598,47 @@ Debugger::emptyAllocationsLog()
|
||||
allocationsLogLength = 0;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Debugger::slowPathOnNewPromise(JSContext *cx, HandleObject promise)
|
||||
{
|
||||
RootedValue rval(cx);
|
||||
JSTrapStatus status = dispatchHook(cx, &rval, OnNewPromise, promise);
|
||||
MOZ_ASSERT(status == JSTRAP_CONTINUE);
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
}
|
||||
|
||||
JSTrapStatus
|
||||
Debugger::fireNewPromise(JSContext *cx, HandleObject promise, MutableHandleValue vp)
|
||||
{
|
||||
RootedObject hook(cx, getHook(OnNewPromise));
|
||||
MOZ_ASSERT(hook);
|
||||
MOZ_ASSERT(hook->isCallable());
|
||||
|
||||
Maybe<AutoCompartment> ac;
|
||||
ac.emplace(cx, object);
|
||||
|
||||
RootedValue dbgObj(cx, ObjectValue(*promise));
|
||||
if (!wrapDebuggeeValue(cx, &dbgObj))
|
||||
return handleUncaughtException(ac, false);
|
||||
|
||||
// Like onNewGlobalObject, onNewPromise is infallible and the comments in
|
||||
// |Debugger::fireNewGlobalObject| apply here as well.
|
||||
|
||||
RootedValue rv(cx);
|
||||
bool ok = Invoke(cx, ObjectValue(*object), ObjectValue(*hook), 1, dbgObj.address(), &rv);
|
||||
if (ok && !rv.isUndefined()) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
|
||||
JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
JSTrapStatus status = ok ? JSTRAP_CONTINUE
|
||||
: handleUncaughtException(ac, vp, true);
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** Debugger code invalidation for observing execution ******************************************/
|
||||
|
||||
@ -1979,6 +2032,7 @@ Debugger::setObservesAllExecution(JSContext *cx, IsObserving observing)
|
||||
return updateExecutionObservability(cx, obs, observing);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** Debugger JSObjects **************************************************************************/
|
||||
|
||||
@ -2430,6 +2484,18 @@ Debugger::setOnNewScript(JSContext *cx, unsigned argc, Value *vp)
|
||||
return setHookImpl(cx, argc, vp, OnNewScript);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Debugger::getOnNewPromise(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return getHookImpl(cx, argc, vp, OnNewPromise);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Debugger::setOnNewPromise(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return setHookImpl(cx, argc, vp, OnNewPromise);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
Debugger::getOnEnterFrame(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
@ -3662,6 +3728,7 @@ const JSPropertySpec Debugger::properties[] = {
|
||||
JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
|
||||
Debugger::setOnExceptionUnwind, 0),
|
||||
JS_PSGS("onNewScript", Debugger::getOnNewScript, Debugger::setOnNewScript, 0),
|
||||
JS_PSGS("onNewPromise", Debugger::getOnNewPromise, Debugger::setOnNewPromise, 0),
|
||||
JS_PSGS("onEnterFrame", Debugger::getOnEnterFrame, Debugger::setOnEnterFrame, 0),
|
||||
JS_PSGS("onNewGlobalObject", Debugger::getOnNewGlobalObject, Debugger::setOnNewGlobalObject, 0),
|
||||
JS_PSGS("uncaughtExceptionHook", Debugger::getUncaughtExceptionHook,
|
||||
@ -7116,3 +7183,13 @@ JS_DefineDebuggerObject(JSContext *cx, HandleObject obj)
|
||||
debugProto->setReservedSlot(Debugger::JSSLOT_DEBUG_MEMORY_PROTO, ObjectValue(*memoryProto));
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::dbg::onNewPromise(JSContext *cx, HandleObject promise)
|
||||
{
|
||||
MOZ_ASSERT(!!promise);
|
||||
assertSameCompartment(cx, promise);
|
||||
MOZ_ASSERT(strcmp(promise->getClass()->name, "Promise") == 0 ||
|
||||
strcmp(promise->getClass()->name, "MozAbortablePromise") == 0);
|
||||
Debugger::slowPathOnNewPromise(cx, promise);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "gc/Barrier.h"
|
||||
#include "js/Debug.h"
|
||||
#include "js/HashTable.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/SavedStacks.h"
|
||||
@ -177,6 +178,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
friend class mozilla::LinkedListElement<Debugger>;
|
||||
friend bool (::JS_DefineDebuggerObject)(JSContext *cx, JS::HandleObject obj);
|
||||
friend bool SavedStacksMetadataCallback(JSContext *cx, JSObject **pmetadata);
|
||||
friend void JS::dbg::onNewPromise(JSContext *cx, HandleObject promise);
|
||||
|
||||
public:
|
||||
enum Hook {
|
||||
@ -185,6 +187,7 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
OnNewScript,
|
||||
OnEnterFrame,
|
||||
OnNewGlobalObject,
|
||||
OnNewPromise,
|
||||
HookCount
|
||||
};
|
||||
enum {
|
||||
@ -369,6 +372,8 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static bool setOnEnterFrame(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool getOnNewGlobalObject(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool setOnNewGlobalObject(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool getOnNewPromise(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool setOnNewPromise(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool getUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool setUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool getMemory(JSContext *cx, unsigned argc, Value *vp);
|
||||
@ -420,12 +425,15 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||
static void slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||
static bool slowPathOnLogAllocationSite(JSContext *cx, HandleSavedFrame frame,
|
||||
int64_t when, GlobalObject::DebuggerVector &dbgs);
|
||||
static JSTrapStatus dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which);
|
||||
static void slowPathOnNewPromise(JSContext *cx, HandleObject promise);
|
||||
static JSTrapStatus dispatchHook(JSContext *cx, MutableHandleValue vp, Hook which,
|
||||
HandleObject payload);
|
||||
|
||||
JSTrapStatus fireDebuggerStatement(JSContext *cx, MutableHandleValue vp);
|
||||
JSTrapStatus fireExceptionUnwind(JSContext *cx, MutableHandleValue vp);
|
||||
JSTrapStatus fireEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp);
|
||||
JSTrapStatus fireNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global, MutableHandleValue vp);
|
||||
JSTrapStatus fireNewPromise(JSContext *cx, HandleObject promise, MutableHandleValue vp);
|
||||
|
||||
/*
|
||||
* Allocate and initialize a Debugger.Script instance whose referent is
|
||||
@ -826,7 +834,7 @@ Debugger::observesGlobal(GlobalObject *global) const
|
||||
return debuggees.has(global);
|
||||
}
|
||||
|
||||
void
|
||||
/* static */ void
|
||||
Debugger::onNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal)
|
||||
{
|
||||
MOZ_ASSERT_IF(script->compileAndGo(), compileAndGoGlobal);
|
||||
|
Loading…
Reference in New Issue
Block a user