For the Servo debugger, we need some kind of IPC layer:

The debugger server (i.e. the thing that talks the Chrome debugging
protocol) needs to live in the same process (and perhaps even the same
thread) as the constellation; it needs to work closely with the
constellation to figure out which script threads exists, and to route
messages to individual script threads.

At the other end, the debugger API (i.e. the thing we use to examine the
execution state of the JS engine) needs to live in the same thread as the
one it is debugging (i.e. the script thread). In multiprocess mode, there
will be a process boundary between the constellation and the script
threads. Consequently, we need an IPC layer between the debugger server and
the debugger API in each script thread.

Since the debugger API consists of a set of shadow objects (each of which
represents som part of the execution state, such as stack frames,
environments, scripts, etc), the obvious way to implement such an IPC layer
is as a set of proxies to each shadow object: to serialize a shadow object
over ipc, we assign it a unique ID. In the other direction, any message
addressed to that id will be routed to the appropriate object.

To route messages addressed to a specific id to the corresponding object,
we need to maintain some for of id -> object map. Moreover, because the
same shadow object can be obtained via different API calls, we need an
object -> id map; this allows us to ensure that we never create more than
one proxy for the same shadow object.

Creating an object -> id map is problematic; since a *mut JSObject does not
have a stable address, it cannot be used as a key in a HashMap. The obvious
answer here is to use a WeakMap. WeakMaps are available in JSAPI, but as
far as I can tell, not usable with the Rust bindings for JSAPI.

Adding WeakMap support to the Rust bindings for JSAPI is probably
non-trivial, so I'm looking for some kind of temporary workaround. The
simplest option is perhaps to store the id directly on the JSObject. The
Debugger API is designed so that defining arbitrary properties on shadow
objects is well-defined. Since we control how these JSObjects are used
(i.e. they are not exposed to arbitrary client JS), this should not lead to
conflicts.

Another option is to create a WeakMap indirectly, by doing the equivalent
of evaluating "new WeakMap()", storing the resulting JSObject, and then
providing some strongly typed Rust API on top of it. Note that this is very
similar to what we do for the shadow objects in the debugger API.

I am currently leaning towards the first option, but perhaps someone has a
better idea?
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to