Open Bug 962053 Opened 11 years ago Updated 2 years ago

Implement ES Realms


(Core :: JavaScript Engine, enhancement)





(Reporter: till, Unassigned)



(Keywords: dev-doc-needed, feature)


(1 file, 1 obsolete file)

The latest ES6 draft introduces realms: objects that describe the environment script is evaluated/executed in. They can be customized by passing in hooks for (direct and indirect) eval.

Jorendorff's pseudoimplementation of module loaders already contains a JS implementation of realms, so getting a self-hosted version in shouldn't be too hard.

It would be great to have this soon-ish, as it would make implementing some parts of Shumway's ActionScript runtime a lot easier.
The self-hosted implementation is incomplete, but I don't think it needs a ton of help beyond a newGlobal primitive. I guess we'll see. It seems like fun hacking to me.

In case it isn't obvious, Realm = Compartment = Global for us.
> In case it isn't obvious, Realm = Compartment = Global for us.

It ain't obvious. At least, not to me.
(In reply to Nicholas Nethercote [:njn] from comment #2)
> > In case it isn't obvious, Realm = Compartment = Global for us.
> It ain't obvious. At least, not to me.

It wasn't immediatly for me, either. After talking to jorendorff, I see that it's really the only option, though: code that's compiled in a new Realm doesn't share any bindings with the parent realm. That includes Object.prototype and Function.prototype. Given that, I don't really see any way we could get away with not creating a full new global, which in a compartment-per-global world means a new compartment.

There are upsides and downsides to this. An advantage we have is that our security story for Realm-based ocap systems such as Caja will be better than other engines'. Disadvantages are increased memory usage and, more importantly, I think, quite a bit more performance overhead than other engines will have: calls across realm-boundaries will have to go through CCWs, and there'll be no inlining at all.

The November 21 tc39 meeting notes[1] are a very interesting read on this topic. Search for "Decoupling Realms from Loaders".
and search for "Realm API"

It's hard for me to remember a time when it wasn't "obvious" to me that Realm = Global = Compartment.
But others found this surprising too, including dherman.

Here is dherman's nice explicit (but informal) argument for why Realms must be 1-1 with globals:
One more note: Realms are superficially similar to C.u.Sandbox, but they will be *fantastically* error-prone for sandboxing, because Realms don't provide Mozilla's cross-compartment security membranes or any other convenience features for getting sandboxing correct. Consider:

    var sandbox = new Realm;
    var sensitiveUserData; = function (params) {
        return sensitiveUserData.perfectlySafeQuery(params);


The untrusted code can break out of the sandbox:


So the security uses of Realm are an Advanced Topic. Some users will implement security membranes around sandboxes, using Proxy objects.
Attached patch Implement ES6 Realms. wip 0 (obsolete) — Splinter Review
This implements the parts of Realms that are fully specified. It mashes together various changes that I'll extract into multiple patches before asking for a proper review. Mostly, that means extracting the changes to the self-hosting infrastructure. Also, it probably means duplicating the newGlobal stuff in shell/js.cpp again once the Realm class gains proper behavior for eval and Function.

Unimplemented things:
- proper invocation of the initializer argument to the Realm constructor. It's not fully specified what the `builtins` argument is supposed to be
- creation of the global environment in CreateRealm. The NewGlobalEnvironment intrinsic is not specified
- Realm.prototype.eval: the IndirectEval intrinsic is not specified
- the behavior of eval and Function inside the created global. The behavior of these and their interaction with the various fields on the Realm Record isn't specified

It'd be great if you could give me some brief feedback on the implementation, and some guidance on when to expect the rest of the specification of Realms to happen.
Attachment #8376942 - Flags: feedback?(jorendorff)
Assignee: general → till
Forgot a final qref for the last version. This one actually implements Realm#eval.
Attachment #8377348 - Flags: feedback?(jorendorff)
Attachment #8376942 - Attachment is obsolete: true
Attachment #8376942 - Flags: feedback?(jorendorff)
Whiteboard: [Shumway] → [shumway:m2]
Whiteboard: [shumway:m2] → [shumway:m3]
Whiteboard: [shumway:m3] → [shumway:m3][js:p2]
Attachment #8377348 - Flags: feedback?(jorendorff)
Blocks: shumway-1.0
No longer blocks: shumway-m3
Whiteboard: [shumway:m3][js:p2] → [shumway][js:p2]
Any ETA for this?
Realms as a content-visible thing were deferred to ES7, so there's nothing to be done here, for now.
Assignee: till → nobody
Blocks: es7
No longer blocks: harmony:modules, es6, shumway-1.0
Summary: Implement ES6 Realms → Implement ES7 Realms
Whiteboard: [shumway][js:p2]
Blocks: 1317658
No longer blocks: 1317658
Type: defect → enhancement

For what it's worth: most of the information in this bug is outdated. Global objects no longer require a new compartment, just a JS::Realm.

See Also: → 1566145

This never made it into "ES7" (ECMAScript 2016). There is however a proposal for realms:

Summary: Implement ES7 Realms → Implement ES Realms
No longer blocks: es7
Blocks: es7

Is it possible to release to Nightly?

Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.