Assertion failure in enqueuePromiseJob
System information
What is your operating system and version? Fedora 32
What is your version of GJS? 1.64.4 (also present in 1.66)
Bug information
Steps to reproduce
- Run a test suite in jasmine-gjs
- In one of the test suites, nest an async function or Promise in an async test
- Execute the test suite with coverage enabled
function testPromise() {
return new Promise(resolve => resolve());
}
async function testAsync() {
await testPromise();
}
// Enabled one of these tests at a time to see the differing behaviour
describe('awaiting', function () {
it('a Promise never resolves with coverage', async function () {
await testPromise();
expect(true).toBe(true);
});
it('a nested async function fails with coverage', async function () {
await testAsync();
expect(true).toBe(true);
});
});
Current behaviour
If an async function is nested in an async tests, GJS crashes with:
Gjs:ERROR:../gjs/context.cpp:708:virtual bool GjsContextPrivate::enqueuePromiseJob(JSContext*, JS::HandleObject, JS::HandleObject, JS::HandleObject, JS::HandleObject): assertion failed: (empty())
Backtrace:
#0 0x00007ffff79839e5 in raise () at /lib64/libc.so.6
#1 0x00007ffff796c895 in abort () at /lib64/libc.so.6
#2 0x00007ffff7d8db6c in g_assertion_message
(domain=<optimized out>, file=0x7ffff7f3ac88 "../gjs/context.cpp", line=<optimized out>, func=<optimized out>, message=<optimized out>)
at ../glib/gtestutils.c:2914
#3 0x00007ffff7deb9ff in g_assertion_message_expr
(domain=domain@entry=0x7ffff7f31e1e "Gjs", file=file@entry=0x7ffff7f3ac88 "../gjs/context.cpp", line=line@entry=708, func=func@entry=0x7ffff7f3b7c0 "virtual bool GjsContextPrivate::enqueuePromiseJob(JSContext*, JS::HandleObject, JS::HandleObject, JS::HandleObject, JS::HandleObject)", expr=expr@entry=0x7ffff7f3af1c "empty()") at ../glib/gtestutils.c:2940
#4 0x00007ffff7efc03f in GjsContextPrivate::enqueuePromiseJob(JSContext*, JS::Handle<JSObject*>, JS::Handle<JSObject*>, JS::Handle<JSObject*>, JS::Handle<JSObject*>) (this=0x5555555860b0, cx=<optimized out>, promise=..., job=..., allocation_site=..., incumbent_global=...) at ../gjs/context.cpp:708
#5 0x00007ffff64ccd47 in JSRuntime::enqueuePromiseJob(JSContext*, JS::Handle<JSFunction*>, JS::Handle<JSObject*>, JS::Handle<js::GlobalObject*>)
(this=<optimized out>, cx=0x555555585380, job=..., promise=..., incumbentGlobal=...)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/dist/include/js/RootingAPI.h:1212
#6 0x00007ffff6388c7c in EnqueuePromiseResolveThenableBuiltinJob (thenable=..., promiseToResolve=..., cx=0x555555585380)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/dist/include/js/RootingAPI.h:1212
#7 ResolvePromiseInternal(JSContext*, JS::HandleObject, JS::HandleValue) (cx=cx@entry=0x555555585380, promise=promise@entry=..., resolutionVal=...,
resolutionVal@entry=...) at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/builtin/Promise.cpp:913
#8 0x00007ffff638bf70 in InternalAwait<js::AsyncFunctionAwait(JSContext*, JS::Handle<js::AsyncFunctionGeneratorObject*>, JS::HandleValue)::<lambda(JS::Handle<PromiseReactionRecord*>)> > (extraStep=..., onRejected=..., onFulfilled=..., resultPromise=..., value=..., cx=0x555555585380)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/builtin/Promise.cpp:3906
#9 js::AsyncFunctionAwait(JSContext*, JS::Handle<js::AsyncFunctionGeneratorObject*>, JS::Handle<JS::Value>) (cx=0x555555585380, genObj=..., value=...)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/builtin/Promise.cpp:3974
#10 0x00007ffff633424b in Interpret(JSContext*, js::RunState&) (cx=0x555555585380, state=...)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/dist/include/js/RootingAPI.h:618
#11 0x00007ffff633ecb6 in js::RunScript(JSContext*, js::RunState&) (cx=0x555555585380, state=...)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/vm/Interpreter.cpp:423
#12 0x00007ffff633f320 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct)
(cx=0x555555585380, args=..., construct=js::NO_CONSTRUCT) at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/vm/Interpreter.cpp:563
#13 0x00007ffff633f6ad in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>)
(cx=<optimized out>, fval=..., thisv=..., args=..., rval=...) at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/vm/Interpreter.cpp:606
#14 0x00007ffff676b466 in js::jit::InvokeFunction(JSContext*, JS::Handle<JSObject*>, bool, bool, unsigned int, JS::Value*, JS::MutableHandle<JS::Value>)
(cx=0x555555585380, obj=..., constructing=<optimized out>, ignoresReturnValue=<optimized out>, argc=<optimized out>, argv=0x7fffffff9660, rval=...)
at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/dist/include/js/RootingAPI.h:1212
#15 0x00007ffff676b776 in js::jit::InvokeFromInterpreterStub(JSContext*, js::jit::InterpreterStubExitFrameLayout*)
(cx=<optimized out>, frame=0x7fffffff9638) at /usr/src/debug/mozjs68-68.12.0-1.fc32.x86_64/dist/include/js/RootingAPI.h:1212
#16 0x00003217ba1dcf64 in ()
#17 0x00003931b5c63340 in ()
#18 0x00007fffffff9638 in ()
#19 0x00007fffffff9708 in ()
#20 0x00000000000000fc in ()
#21 0x00003217ba21a995 in ()
#22 0x0000000000001842 in ()
#23 0x00003931b5c8cd00 in ()
#24 0x0000000000000000 in ()
If a Promise is nested in an async test, it will never resolve.
Expected behaviour
Promises and async functions should resolve as normal.
Edited by Andy Holmes