Bug 1271653 - Bound function properties should assert that referent is debuggee function;r=jimb

This commit is contained in:
Eddy Bruel 2016-06-06 18:13:07 +02:00
Родитель c8d5762f34
Коммит 7bce2ff615
4 изменённых файлов: 60 добавлений и 21 удалений

Просмотреть файл

@ -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);