
Programming Servo: My own private runtime - polyglotfacto
https://medium.com/programming-servo/programming-servo-my-own-private-runtime-8a5ba74c63c8
======
jakearmitage
Building and using Servo as a library has been a huge pain. I've been waiting
for improvements since
[https://github.com/paulrouget/servoshell](https://github.com/paulrouget/servoshell)
was abandoned

~~~
AlbertoGP
Same here, I thought it would have been ready for that long ago as they touted
embeddability as a prominent goal, but every few months I try again, and have
to give up again.

So far I’m using WebKit while I wait for libservo to be ready.

The article however is a very good explanation (as far as I can tell) of how
the SpiderMonkey Javascript interpreter is linked to Servo. What I need in the
first place is the layout and rendering engine, but hopefully this article
will be useful for me in the future.

~~~
polyglotfacto
I personally haven't much work on embedding Servo, however I do think there
has been some progress the last few years, Servo is being embedded in a
Hololens applications(see
[https://github.com/servo/servo/tree/master/support/hololens](https://github.com/servo/servo/tree/master/support/hololens)),
as well as a Magicleap application(see
[https://github.com/servo/servo/tree/master/support/magicleap](https://github.com/servo/servo/tree/master/support/magicleap)).

The embedding API used can be found at
[https://github.com/servo/servo/tree/master/ports/libsimplese...](https://github.com/servo/servo/tree/master/ports/libsimpleservo)

I think it's a pretty low-level embedding API, so perhaps not comparable with
embedding Webkit(I have no experience with that either), it does seem to do
the trick.

~~~
jakearmitage
The problem with libsimpleservo is that it only supports one view.

------
silok
I think this article should contain some references and comparison to the deno
rutime, [https://deno.land/](https://deno.land/)

~~~
reubenmorais
...why? Servo and Deno are doing very different things.

~~~
sankha93
The article doesn't try to use any feature of the web platform, but tries to
piggy back on it to provide their own runtime functions. WebIDL could be a
overkill in such a scenario. Usage of WebIDL means there is a bindings
generation process using a Python script during compilation of servo.

I could imagine one can define all the functions available in the JS runtime
using the same facilities that are used to define the intrinsic objects like
Array, Number and so on. Their implementation could use an event loop provided
by Tokio.

Comparison with Deno is interesting and could provide interesting insight into
how SpiderMoney can be used to build such a runtime. I tried to build one at
[https://github.com/ngsankha/rustynode](https://github.com/ngsankha/rustynode)
couple of years ago, but abandoned due to other commitments. The
implementation is far from optimal.

~~~
polyglotfacto
Yeah I agree Deno is an interesting comparison, thanks for pointing it out I
wasn't aware of it.

On the other points, I would still stick to my suggestion of using WebIDL, at
least for Spidermonkey, since you'd have to otherwise write all the glue code
yourself. The bindings generation is worth it I think.

Re using Tokio to run the event-loop of the VM, I would probably just use a
native thread, like I suggested in the article.

Tokio is really like a runtime for Rust, meaning that if you use it to
implement a runtime for say Wasm, then you're trying to run your own runtime
within someone else's runtime. Not saying it can't be done, just not how I
would do it.

I think Tokio on the other hand could really shine if used in a separate
"networking component" that, in a Deno-like server-side runtime, would handle
all incoming requests/connections, and then have the "runtime" run in a
separate component(and process, if you want some isolation). Let's say you
wanted to run different VM's, isolated from each other, you could run each in
it's own process, and the networking would also be done in its own, or the
"main", process of the overall engine.

Incoming networking requets could then be translated into events or other kind
of calls into the user-code running on an isolated VM, which itself is
probably best run using a simple event-loop running on a single-thread.

It's similar to what Servo does actually, where there is a "net" component to
do the networking(although it's client-side networking off-course), then there
is the "constellation" component that is like "one ring to rule them all" main
component, and you have the "script" component actually running Spidermonkey
VMs each on their own event-loop(let's say roughly one per "tab", plus one per
worker).

So the JS/Wasm running on Spidermonkey is "async", like you can await a
promise and so on, however it's actually driven by a single-thread, with other
components, like "net", running "in-parallel" of "script", in their own
process, and using whatever threading or async runtime they need.

So for example, if you do a fetch in JS, then the script component can keep
running other stuff in it's task-queues in the meantime(in a single-threaded,
one task at a time, fashion), while the net component will do the fetch over
the network, and as "stuff happens" related to this fetch, net will enqueue
tasks back on the event-loop where the fetch originated, resulting in
events/promise resolving on the VM, and executing of handlers in JS.

So not only do "net" and "script" have to run in separate processes for
security(spectre) and robustness, they also have to run in parallel of each
other, and according to a very specific specification(see for the event-loop
of script for example: [https://html.spec.whatwg.org/multipage/#event-loop-
processin...](https://html.spec.whatwg.org/multipage/#event-loop-processing-
model))

So I guess you could run a tokio runtime in both processes, but it would
actually be kinda overkill(Servo does uses Tokio in the "net" component, and
that's obviously a good fit since it's doing the networking).

So I'd say the trick would be clearly separating the networking, from the
VM(s), probably use something like Tokio in the networking component, and to
implement the event-loop driving the VM, I'd just use a native thread, one per
VM.

This article is part of a collection of articles going into the architecture
of Servo, if you're interested: [https://medium.com/programming-
servo](https://medium.com/programming-servo)

