This is a Jetpack package that allows Firefox addons to be created that execute in a separate process from Firefox itself.
This package contains the following sub-packages:
-
e10s-core
makes the Jetpack platform multi-process-aware. Specifically, it replaces parts of Jetpack's module loader to allow non-chrome-privileged modules to be loaded in a separate process. Citing this package as a dependency in an addon'spackage.json
will cause it to be loaded and executed with the semantics described in the rest of this document. -
e10s-test-runner
provides a multi-process-aware test runner that executes all non-chrome-privileged test modules in both a separate process and the chrome process.
- The latest Firefox 4 Beta, or a recent Firefox nightly.
- The latest Jetpack SDK.
-
Activate your SDK and clone this git repository in the
packages
subdirectory of your SDK and enter thetwitter-widget
example:git clone git://github.com/toolness/jetpack-e10s.git cd jetpack-e10s/examples/twitter-widget
-
Run the test suite for the example:
cfx test --test-runner-pkg=e10s-test-runner
The extra arguments tell
cfx
to use the multi-process-aware test runner. -
Run the example itself:
cfx run
-
Once Firefox starts up, you should see a widget at the bottom of the browser labeled "Click me!" (it may be truncated due to size constraints). Do what it says.
-
The widget label should change to "..." for a moment and then change to the Twitter status of toolness.
Addons are awesome, but like any software, they have the ability to behave in unexpected ways. An addon that's gone rogue should have as little ability to negatively affect the rest of your browsing experience as possible; one way to achieve this is by running the addon's code in a separate process.
These separate processes are relatively lightweight, don't have access to XPCOM, and can innately do little other than compute. Messaging facilities that allow them to communicate with their parent Firefox process are the only means by which they can be endowed with any real power.
The above diagram is a simplified depiction of what happens when the example twitter-widget addon is loaded.
First, the Jetpack Platform Loader initializes the Jetpack Platform and loads main.js
in a separate process.
When main.js
calls require("widget")
, the Addon Process sends a message to the Firefox Process and awaits a reply.
The Firefox Process then notices that the widget
module requires chrome privileges and therefore won't work properly if sent to the Addon Process for evaluation. So it looks for an e10s adapter for the module by appending -e10s-adapter
to the module's name and searching for it.
This causes widget-e10s-adapter.js
to be found and imported as the widget-e10s-adapter
module in the Firefox Process. The exact same code is also returned to the Addon Process for evaluation as the widget
module in its world, and its exports are returned by require()
. In other words, different sides of the message-passing boundary between the two processes are contained in the same adapter file, which is typically of the following form:
if (this.sendMessage) {
/* We're being evaluated in the Addon Process. Set up message-passing
* infrastructure to communicate with the Firefox Process
* and export an API. */
} else {
/* We're being evaluated in the Firefox Process. */
exports.register = function register(process) {
/* Set-up Firefox Process message-passing infrastructure
* to communicate with the given Addon Process. */
};
}
Note that this only describes what happens when a module requiring chrome privileges and having an e10s adapter is requested by code in the Addon Process.
If the Addon Process code attempts to import a chrome-privileged module that does not have an e10s adapter, an access denied exception is thrown.
If the Addon Process code attempts to import a module that does not explicitly require chrome privileges, the code for the module is sent to the Addon Process and evaluated there, just like the main
module.
If both a module in the Firefox Process and a module in the Addon Process request the same module that doesn't require chrome privileges, it is actually loaded twice: once in each process. This means that modules which intend to provide singleton-like functionality may need an e10s adapter to proxy calls into a single process.
Code for the creation and bootstrapping of the remote process is contained in e10s.js
, which uses the nsIJetpackService
and nsIJetpack
XPCOM interfaces to create a Jetpack process and send bootstrap-remote-process.js
to it for evaluation. The e10s
module also contains most of the require()
logic for the Addon Process.