зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1207868 - Implement Debugger.Object.asEnvironment. (r=jimb)
This commit is contained in:
Родитель
61b07632ad
Коммит
cd0445bf55
|
@ -427,9 +427,9 @@ code), the call throws a [`Debugger.DebuggeeWouldRun`][wouldrun] exception.
|
|||
|
||||
`asEnvironment()`
|
||||
: If the referent is a global object, return the [`Debugger.Environment`][environment]
|
||||
instance representing the referent as a variable environment for
|
||||
evaluating code. If the referent is not a global object, throw a
|
||||
`TypeError`.
|
||||
instance representing the referent's global lexical scope. The global
|
||||
lexical scope's enclosing scope is the global object. If the referent is
|
||||
not a global object, throw a `TypeError`.
|
||||
|
||||
<code>setObjectWatchpoint(<i>handler</i>)</code> <i>(future plan)</i>
|
||||
: Set a watchpoint on all the referent's own properties, reporting events
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// Tests D.O.asEnvironment() returning the global lexical scope.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger;
|
||||
var gw = dbg.addDebuggee(g);
|
||||
|
||||
g.evaluate(`
|
||||
var x = 42;
|
||||
let y = "foo"
|
||||
`);
|
||||
|
||||
var globalLexical = gw.asEnvironment();
|
||||
assertEq(globalLexical.names().length, 1);
|
||||
assertEq(globalLexical.getVariable("y"), "foo");
|
||||
assertEq(globalLexical.parent.getVariable("x"), 42);
|
|
@ -7687,6 +7687,24 @@ DebuggerObject_executeInGlobalWithBindings(JSContext* cx, unsigned argc, Value*
|
|||
args.rval(), dbg, globalLexical, nullptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
DebuggerObject_asEnvironment(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "asEnvironment", args, dbg, referent);
|
||||
if (!RequireGlobalObject(cx, args.thisv(), referent))
|
||||
return false;
|
||||
|
||||
Rooted<Env*> env(cx);
|
||||
{
|
||||
AutoCompartment ac(cx, referent);
|
||||
env = GetDebugScopeForGlobalLexicalScope(cx);
|
||||
if (!env)
|
||||
return false;
|
||||
}
|
||||
|
||||
return dbg->wrapEnvironment(cx, env, args.rval());
|
||||
}
|
||||
|
||||
static bool
|
||||
DebuggerObject_unwrap(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
@ -7764,6 +7782,7 @@ static const JSFunctionSpec DebuggerObject_methods[] = {
|
|||
JS_FN("makeDebuggeeValue", DebuggerObject_makeDebuggeeValue, 1, 0),
|
||||
JS_FN("executeInGlobal", DebuggerObject_executeInGlobal, 1, 0),
|
||||
JS_FN("executeInGlobalWithBindings", DebuggerObject_executeInGlobalWithBindings, 2, 0),
|
||||
JS_FN("asEnvironment", DebuggerObject_asEnvironment, 0, 0),
|
||||
JS_FN("unwrap", DebuggerObject_unwrap, 0, 0),
|
||||
JS_FN("unsafeDereference", DebuggerObject_unsafeDereference, 0, 0),
|
||||
JS_FS_END
|
||||
|
|
|
@ -2859,6 +2859,13 @@ js::GetDebugScopeForFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc)
|
|||
return GetDebugScope(cx, si);
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::GetDebugScopeForGlobalLexicalScope(JSContext* cx)
|
||||
{
|
||||
ScopeIter si(cx, &cx->global()->lexicalScope(), &cx->global()->lexicalScope().staticBlock());
|
||||
return GetDebugScope(cx, si);
|
||||
}
|
||||
|
||||
// See declaration and documentation in jsfriendapi.h
|
||||
JS_FRIEND_API(JSObject*)
|
||||
js::GetNearestEnclosingWithScopeObjectForFunction(JSFunction* fun)
|
||||
|
|
|
@ -1109,13 +1109,13 @@ class LiveScopeVal
|
|||
* now incomplete: it may not contain all, or any, of the ScopeObjects to
|
||||
* represent the current scope.
|
||||
*
|
||||
* To resolve this, the debugger first calls GetDebugScopeFor(Function|Frame)
|
||||
* to synthesize a "debug scope chain". A debug scope chain is just a chain of
|
||||
* objects that fill in missing scopes and protect the engine from unexpected
|
||||
* access. (The latter means that some debugger operations, like redefining a
|
||||
* lexical binding, can fail when a true eval would succeed.) To do both of
|
||||
* these things, GetDebugScopeFor* creates a new proxy DebugScopeObject to sit
|
||||
* in front of every existing ScopeObject.
|
||||
* To resolve this, the debugger first calls GetDebugScopeFor* to synthesize a
|
||||
* "debug scope chain". A debug scope chain is just a chain of objects that
|
||||
* fill in missing scopes and protect the engine from unexpected access. (The
|
||||
* latter means that some debugger operations, like redefining a lexical
|
||||
* binding, can fail when a true eval would succeed.) To do both of these
|
||||
* things, GetDebugScopeFor* creates a new proxy DebugScopeObject to sit in
|
||||
* front of every existing ScopeObject.
|
||||
*
|
||||
* GetDebugScopeFor* ensures the invariant that the same DebugScopeObject is
|
||||
* always produced for the same underlying scope (optimized or not!). This is
|
||||
|
@ -1128,6 +1128,9 @@ GetDebugScopeForFunction(JSContext* cx, HandleFunction fun);
|
|||
extern JSObject*
|
||||
GetDebugScopeForFrame(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc);
|
||||
|
||||
extern JSObject*
|
||||
GetDebugScopeForGlobalLexicalScope(JSContext* cx);
|
||||
|
||||
/* Provides debugger access to a scope. */
|
||||
class DebugScopeObject : public ProxyObject
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче