So, as sfink sort of said, the way this works is that any nsIFoo object implemented by JS is exposed as an nsXPCWrappedJS. The QI of that C++ class is nsXPCWrappedJS::QueryInterface(), and it has a few special cases, including nsCycleCollectionISupports, that it checks before it calls into DelegatedQueryInterface(), which is the thing that would actually run JS.
Bug 1531956 Comment 6 Edit History
Note: The actual edited comment in the bug view page will always show the original commenter’s name and original timestamp.
So, as sfink sort of said, the way this works is that any nsIFoo object implemented by JS is exposed to C++ as an nsXPCWrappedJS. The QI of that C++ class is nsXPCWrappedJS::QueryInterface(), and it has a few special cases, including nsCycleCollectionISupports, that it checks before it calls into DelegatedQueryInterface(), which is the thing that would actually run JS.