зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1271653 - Bound function properties should assert that referent is debuggee function;r=jimb
This commit is contained in:
Родитель
c8d5762f34
Коммит
7bce2ff615
|
@ -19,7 +19,7 @@ assertEq(fw.boundArguments, undefined);
|
|||
assertEq(nw.boundTargetFunction, undefined);
|
||||
|
||||
var ow = gw.executeInGlobal("var o = {}; o").return;
|
||||
assertEq(ow.isBoundFunction, false);
|
||||
assertEq(ow.isBoundFunction, undefined);
|
||||
assertEq(ow.boundThis, undefined);
|
||||
assertEq(fw.boundArguments, undefined);
|
||||
assertEq(ow.boundTargetFunction, undefined);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
var g1 = newGlobal();
|
||||
g1.eval('function f() { return "from f"; }');
|
||||
g1.eval('function g() { return "from g"; }');
|
||||
g1.eval('this.h = f.bind(g, 42, "foo");');
|
||||
|
||||
// Create a debuggee compartment with CCWs referring to f and g.
|
||||
var g2 = newGlobal();
|
||||
|
@ -20,6 +21,7 @@ var dbg = new Debugger;
|
|||
var g2w = dbg.addDebuggee(g2);
|
||||
g2.f = g1.f;
|
||||
g2.g = g1.g;
|
||||
g2.h = g1.h;
|
||||
|
||||
// At this point, g1.f should still be a lazy function. Unwrapping a D.O
|
||||
// referring to g2's CCW of f should yield a D.O referring to f directly.
|
||||
|
@ -36,8 +38,22 @@ assertEq(gDO.global, g2w);
|
|||
assertEq(gDO.unwrap().global === g2w, false);
|
||||
assertEq(gDO.unwrap().parameterNames, undefined);
|
||||
|
||||
// Similarly for g1.h, and asking for its bound function properties.
|
||||
var hDO = g2w.getOwnPropertyDescriptor('h').value;
|
||||
assertEq(hDO.global, g2w);
|
||||
assertEq(hDO.unwrap().global === g2w, false);
|
||||
assertEq(hDO.unwrap().isBoundFunction, undefined);
|
||||
assertEq(hDO.unwrap().boundTargetFunction, undefined);
|
||||
assertEq(hDO.unwrap().boundThis, undefined);
|
||||
assertEq(hDO.unwrap().boundArguments, undefined);
|
||||
|
||||
// Add g1 as a debuggee, and verify that we can get everything.
|
||||
dbg.addDebuggee(g1);
|
||||
assertEq(fDO.unwrap().script instanceof Debugger.Script, true);
|
||||
assertEq(gDO.unwrap().parameterNames instanceof Array, true);
|
||||
|
||||
assertEq(hDO.unwrap().isBoundFunction, true);
|
||||
assertEq(hDO.unwrap().boundTargetFunction, fDO.unwrap());
|
||||
assertEq(hDO.unwrap().boundThis, gDO.unwrap());
|
||||
assertEq(hDO.unwrap().boundArguments.length, 2);
|
||||
assertEq(hDO.unwrap().boundArguments[0], 42);
|
||||
assertEq(hDO.unwrap().boundArguments[1], "foo");
|
||||
|
|
|
@ -8073,6 +8073,11 @@ DebuggerObject_getIsBoundFunction(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
THIS_DEBUGOBJECT(cx, argc, vp, "get isBoundFunction", args, object)
|
||||
|
||||
if (!DebuggerObject::isDebuggeeFunction(cx, object)) {
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
args.rval().setBoolean(DebuggerObject::isBoundFunction(cx, object));
|
||||
return true;
|
||||
}
|
||||
|
@ -8082,7 +8087,9 @@ DebuggerObject_getBoundTargetFunction(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
THIS_DEBUGOBJECT(cx, argc, vp, "get boundTargetFunction", args, object)
|
||||
|
||||
if (!DebuggerObject::isBoundFunction(cx, object)) {
|
||||
if (!DebuggerObject::isDebuggeeFunction(cx, object) ||
|
||||
!DebuggerObject::isBoundFunction(cx, object))
|
||||
{
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -8100,7 +8107,9 @@ DebuggerObject_getBoundThis(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
THIS_DEBUGOBJECT(cx, argc, vp, "get boundThis", args, object)
|
||||
|
||||
if (!DebuggerObject::isBoundFunction(cx, object)) {
|
||||
if (!DebuggerObject::isDebuggeeFunction(cx, object) ||
|
||||
!DebuggerObject::isBoundFunction(cx, object))
|
||||
{
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -8113,7 +8122,9 @@ DebuggerObject_getBoundArguments(JSContext* cx, unsigned argc, Value* vp)
|
|||
{
|
||||
THIS_DEBUGOBJECT(cx, argc, vp, "get boundArguments", args, object)
|
||||
|
||||
if (!DebuggerObject::isBoundFunction(cx, object)) {
|
||||
if (!DebuggerObject::isDebuggeeFunction(cx, object) ||
|
||||
!DebuggerObject::isBoundFunction(cx, object))
|
||||
{
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -8850,6 +8861,16 @@ DebuggerObject::isFunction(JSContext* cx, Handle<DebuggerObject*> object)
|
|||
return referent->is<JSFunction>();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerObject::isDebuggeeFunction(JSContext* cx, Handle<DebuggerObject*> object)
|
||||
{
|
||||
RootedObject referent(cx, object->referent());
|
||||
Debugger* dbg = object->owner();
|
||||
|
||||
return referent->is<JSFunction>() &&
|
||||
dbg->observesGlobal(&referent->as<JSFunction>().global());
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DebuggerObject::className(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandleString result)
|
||||
|
@ -8873,7 +8894,7 @@ DebuggerObject::className(JSContext* cx, Handle<DebuggerObject*> object,
|
|||
/* static */ bool
|
||||
DebuggerObject::name(JSContext* cx, Handle<DebuggerObject*> object, MutableHandleString result)
|
||||
{
|
||||
MOZ_ASSERT(DebuggerObject::isFunction(cx, object));
|
||||
MOZ_ASSERT(isFunction(cx, object));
|
||||
|
||||
RootedFunction referent(cx, &object->referent()->as<JSFunction>());
|
||||
|
||||
|
@ -8885,7 +8906,7 @@ DebuggerObject::name(JSContext* cx, Handle<DebuggerObject*> object, MutableHandl
|
|||
DebuggerObject::displayName(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandleString result)
|
||||
{
|
||||
MOZ_ASSERT(DebuggerObject::isFunction(cx, object));
|
||||
MOZ_ASSERT(isFunction(cx, object));
|
||||
|
||||
RootedFunction referent(cx, &object->referent()->as<JSFunction>());
|
||||
|
||||
|
@ -8896,6 +8917,8 @@ DebuggerObject::displayName(JSContext* cx, Handle<DebuggerObject*> object,
|
|||
/* static */ bool
|
||||
DebuggerObject::isBoundFunction(JSContext* cx, Handle<DebuggerObject*> object)
|
||||
{
|
||||
MOZ_ASSERT(isDebuggeeFunction(cx, object));
|
||||
|
||||
RootedObject referent(cx, object->referent());
|
||||
|
||||
return referent->isBoundFunction();
|
||||
|
@ -8905,12 +8928,12 @@ DebuggerObject::isBoundFunction(JSContext* cx, Handle<DebuggerObject*> object)
|
|||
DebuggerObject::boundTargetFunction(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandleObject result)
|
||||
{
|
||||
RootedObject referent(cx, object->referent());
|
||||
MOZ_ASSERT(isBoundFunction(cx, object));
|
||||
|
||||
RootedFunction referent(cx, &object->referent()->as<JSFunction>());
|
||||
Debugger* dbg = object->owner();
|
||||
|
||||
MOZ_ASSERT(referent->isBoundFunction());
|
||||
|
||||
result.set(referent->as<JSFunction>().getBoundFunctionTarget());
|
||||
result.set(referent->getBoundFunctionTarget());
|
||||
return dbg->wrapDebuggeeObject(cx, result);
|
||||
}
|
||||
|
||||
|
@ -8918,12 +8941,12 @@ DebuggerObject::boundTargetFunction(JSContext* cx, Handle<DebuggerObject*> objec
|
|||
DebuggerObject::boundThis(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandleValue result)
|
||||
{
|
||||
RootedObject referent(cx, object->referent());
|
||||
MOZ_ASSERT(isBoundFunction(cx, object));
|
||||
|
||||
RootedFunction referent(cx, &object->referent()->as<JSFunction>());
|
||||
Debugger* dbg = object->owner();
|
||||
|
||||
MOZ_ASSERT(referent->isBoundFunction());
|
||||
|
||||
result.set(referent->as<JSFunction>().getBoundFunctionThis());
|
||||
result.set(referent->getBoundFunctionThis());
|
||||
return dbg->wrapDebuggeeValue(cx, result);
|
||||
}
|
||||
|
||||
|
@ -8931,17 +8954,16 @@ DebuggerObject::boundThis(JSContext* cx, Handle<DebuggerObject*> object,
|
|||
DebuggerObject::boundArguments(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandle<ValueVector> result)
|
||||
{
|
||||
RootedObject referent(cx, object->referent());
|
||||
MOZ_ASSERT(isBoundFunction(cx, object));
|
||||
|
||||
RootedFunction referent(cx, &object->referent()->as<JSFunction>());
|
||||
Debugger* dbg = object->owner();
|
||||
|
||||
MOZ_ASSERT(referent->isBoundFunction());
|
||||
|
||||
Rooted<JSFunction*> fun(cx, &referent->as<JSFunction>());
|
||||
size_t length = fun->getBoundFunctionArgumentCount();
|
||||
size_t length = referent->getBoundFunctionArgumentCount();
|
||||
if (!result.resize(length))
|
||||
return false;
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
result[i].set(fun->getBoundFunctionArgument(cx, i));
|
||||
result[i].set(referent->getBoundFunctionArgument(cx, i));
|
||||
if (!dbg->wrapDebuggeeValue(cx, result[i]))
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1052,6 +1052,7 @@ class DebuggerObject : public NativeObject
|
|||
HandleNativeObject debugger);
|
||||
|
||||
static bool isFunction(JSContext* cx, Handle<DebuggerObject*> object);
|
||||
static bool isDebuggeeFunction(JSContext* cx, Handle<DebuggerObject*> object);
|
||||
static bool className(JSContext* cx, Handle<DebuggerObject*> object,
|
||||
MutableHandleString result);
|
||||
static bool name(JSContext* cx, Handle<DebuggerObject*> object, MutableHandleString result);
|
||||
|
|
Загрузка…
Ссылка в новой задаче