jsdbg.cpp: Implement Debug.Object.prototype.parameterNames. Add tests. Also, change DebugObject_getName to follow return-on-error conventions.

This commit is contained in:
Jim Blandy 2011-05-23 14:53:04 -07:00
parent db390bcad3
commit fd054f5c39
3 changed files with 89 additions and 7 deletions

View File

@ -0,0 +1,36 @@
// |jit-test| debug
load(libdir + 'array-compare.js');
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var hits = 0;
dbg.hooks = {
debuggerHandler: function (frame) {
var arr = frame.arguments;
assertEq(arraysEqual(arr[0].parameterNames, []), true);
assertEq(arraysEqual(arr[1].parameterNames, ["x"]), true);
assertEq(arraysEqual(arr[2].parameterNames,
["a","b","c","d","e","f","g","h","i","j","k","l","m",
"n","o","p","q","r","s","t","u","v","w","x","y","z"]),
true);
assertEq(arraysEqual(arr[3].parameterNames, ["a", (void 0), (void 0)]), true);
assertEq(arr[4].parameterNames, (void 0));
assertEq(arraysEqual(arr[5].parameterNames, [(void 0), (void 0)]), true);
assertEq(arr.length, 6);
hits++;
}
};
g.eval("("
+ function () {
(function () { debugger; }
(function () {},
function (x) {},
function (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) {},
function (a, [b, c], {d, e:f}) { },
{a:1},
Math.atan2
));
}
+")()");
assertEq(hits, 1);

View File

@ -2009,7 +2009,7 @@ class AutoReleaseNullablePtr {
class AutoLocalNameArray {
public:
explicit AutoLocalNameArray(JSContext *cx, JSFunction *fun
explicit AutoLocalNameArray(JSContext *cx, const JSFunction *fun
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: context(cx),
mark(JS_ARENA_MARK(&cx->tempPool)),

View File

@ -1313,13 +1313,58 @@ static JSBool
DebugObject_getName(JSContext *cx, uintN argc, Value *vp)
{
THIS_DEBUGOBJECT_REFERENT(cx, vp, "get name", obj);
if (obj->isFunction()) {
if (JSString *name = obj->getFunctionPrivate()->atom) {
vp->setString(name);
return Debug::fromChildJSObject(&vp[1].toObject())->wrapDebuggeeValue(cx, vp);
}
if (!obj->isFunction()) {
vp->setNull();
return true;
}
vp->setNull();
JSString *name = obj->getFunctionPrivate()->atom;
if (!name) {
vp->setNull();
return true;
}
vp->setString(name);
return Debug::fromChildJSObject(&vp[1].toObject())->wrapDebuggeeValue(cx, vp);
}
static JSBool
DebugObject_getParameterNames(JSContext *cx, uintN argc, Value *vp)
{
THIS_DEBUGOBJECT_REFERENT(cx, vp, "get parameterNames", obj);
if (!obj->isFunction()) {
vp->setUndefined();
return true;
}
const JSFunction *fun = obj->getFunctionPrivate();
JSObject *result = NewDenseAllocatedArray(cx, fun->nargs, NULL);
if (!result)
return false;
if (fun->isInterpreted()) {
JS_ASSERT(fun->nargs == fun->script()->bindings.countArgs());
if (fun->nargs > 0) {
const AutoLocalNameArray names(cx, fun);
if (!names)
return false;
for (size_t i = 0; i < fun->nargs; i++) {
JSAtom *name = JS_LOCAL_NAME_TO_ATOM(names[i]);
Value *elt = result->addressOfDenseArrayElement(i);
if (name)
elt->setString(name);
else
elt->setUndefined();
}
}
} else {
for (size_t i = 0; i < fun->nargs; i++)
result->addressOfDenseArrayElement(i)->setUndefined();
}
vp->setObject(*result);
return true;
}
@ -1385,6 +1430,7 @@ static JSPropertySpec DebugObject_properties[] = {
JS_PSG("class", DebugObject_getClass, 0),
JS_PSG("callable", DebugObject_getCallable, 0),
JS_PSG("name", DebugObject_getName, 0),
JS_PSG("parameterNames", DebugObject_getParameterNames, 0),
JS_PS_END
};