Bug 996060 - Part 2: Add a testing function and jit test for pending exception's stacks; r=sfink

This commit is contained in:
Nick Fitzgerald 2016-05-21 10:15:25 -07:00
Родитель d83fd413a3
Коммит 4777b6ccda
3 изменённых файлов: 72 добавлений и 0 удалений

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

@ -3495,6 +3495,40 @@ GetModuleEnvironmentValue(JSContext* cx, unsigned argc, Value* vp)
return GetProperty(cx, env, env, id, args.rval());
}
static bool
CatchAndReturnPendingExceptionStack(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() != 1) {
JS_ReportError(cx, "Wrong number of arguments, expected exactly 1");
return false;
}
if (!args[0].isObject() || !IsCallable(args[0])) {
JS_ReportError(cx, "Argument must be callable");
return false;
}
RootedValue thisv(cx, NullValue());
RootedObject fun(cx, &args[0].toObject());
RootedValue rval(cx);
if (JS::Call(cx, UndefinedHandleValue, fun, JS::HandleValueArray::empty(), &rval) ||
!cx->isExceptionPending())
{
JS_ReportError(cx, "Supplied callable did not throw");
return false;
}
RootedObject stack(cx);
if (!JS::GetPendingExceptionStack(cx, &stack))
return false;
cx->clearPendingException();
MOZ_ASSERT_IF(stack, stack->is<SavedFrame>());
args.rval().setObjectOrNull(stack);
return true;
}
static const JSFunctionSpecWithHelp TestingFunctions[] = {
JS_FN_HELP("gc", ::GC, 0, 0,
"gc([obj] | 'compartment' [, 'shrinking'])",
@ -4012,6 +4046,11 @@ gc::ZealModeHelpText),
"getModuleEnvironmentValue(module, name)",
" Get the value of a bound name in a module environment.\n"),
JS_FN_HELP("catchAndReturnPendingExceptionStack", CatchAndReturnPendingExceptionStack, 1, 0,
"catchAndReturnPendingExceptionStack(func)",
" Call `func`, catch its thrown exception, and return the stack captured when\n"
" the exception was thrown.\n"),
JS_FS_HELP_END
};

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

@ -0,0 +1,20 @@
let err;
const stack = catchAndReturnPendingExceptionStack(function a() {
err = new Error();
(function b() {
(function c() {
throw err;
}());
}());
});
assertEq(!!err, true);
// Yes, they're different!
assertEq(stack.toString() != err.stack, true);
assertEq(stack.functionDisplayName, "c");
assertEq(stack.parent.functionDisplayName, "b");
assertEq(stack.parent.parent.functionDisplayName, "a");
assertEq(stack.parent.parent.parent.functionDisplayName, null);
assertEq(stack.parent.parent.parent.parent, null);

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

@ -0,0 +1,13 @@
const stack = catchAndReturnPendingExceptionStack(function a() {
(function b() {
(function c() {
throw 42;
}());
}());
});
assertEq(stack.functionDisplayName, "c");
assertEq(stack.parent.functionDisplayName, "b");
assertEq(stack.parent.parent.functionDisplayName, "a");
assertEq(stack.parent.parent.parent.functionDisplayName, null);
assertEq(stack.parent.parent.parent.parent, null);