Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add hooks for all implementation-defined/host behaviour (that's possible at realm level) #210

Closed
Jamesernator opened this issue Jul 29, 2019 · 7 comments

Comments

@Jamesernator
Copy link

Jamesernator commented Jul 29, 2019

I previously opened this issue on the SES proposal but decided to open it here as well as it's relevant for all Realms not just SES ones.


ECMA262 has a number of "implementation-defined" and "host" defined operations.

It would be nice to be able to hook into any of these when creating a new Realm e.g.:

let i = 0;
let rng = getRngSomehow();

const realm = Realm.makeRootRealm({
  hostImplementations: {
    random: () => rng.next(),
    now: () => i++ // Use for both Date.now() and new Date(),
    locale: 'fr-FR', // Affects appropriate ECMA-402 APIs within Realm
    promiseRejectionTracker: (promise, operation) => { /* Track rejections */},
  },
})

This is a list of things that are marked as implementation-defined or host operations in ECMA262:

Should include in realms:

  • HostResolveImportedModule
    • This is important to be able to support modules in Realms
  • HostImportModuleDynamically
    • Ditto
  • InitializeHostDefinedRealm
    • Most of this will be handled by makeRootRealm but using an exotic object (e.g. Proxy) as the global isn't currently available in the current proposal
    • Ditto for globalThis
  • HostHasSourceTextAvailable
  • NativeError message
    • This is probably too complicated but worth considering
  • LocalTZA
    • This is important to be able to override for deterministic testing and such
  • TimeZoneString
    • Ditto
  • Locales and ECMA-402
    • Not sure of the best way to handle this, maybe specify a locale or add hooks to provide implementation of .localeCompare()/etc
  • Sort Order
  • HostPromiseRejectionTracker
  • Math.random()
  • Date.now / new Date()
  • HostEnsureCanCompileStrings

Unnecessary or not at the realm level:

  • RunJobs
    • While mplementation defined I'm not sure this can be separated from the agent
  • EnqueueJob
    • Ditto
  • [[Call]]
    • has an implementation-defined initialization step, not sure if worth exposing
  • [[Construct]]
    • same as [[Call]]
  • debugger
    • This should probably be an agent-level feature, but I'm not sure
  • HostReportErrors
    • Probably unnecessary as try/catch can be used directly when creating/evaluating modules/scripts to do the same
  • [[IsHTMLDDA]]
    • Web browser only, use of it is recommended against
  • hostDefined in Script/Module records
    • Can be handled by a Map/WeakMap
  • host-synchronizes-with and other atomics stuff
    • Definitely only agent level
@Jamesernator Jamesernator changed the title Add hooks for all implementation-defined/host behaviour Add hooks for all implementation-defined/host behaviour (that's possible at realm level) Jul 29, 2019
@caridy
Copy link
Collaborator

caridy commented Feb 6, 2020

This level of control can be exercised at the evaluator level, the realm will not provide any hooks. I have tagged accordingly, so we can move it to the other repo at some point.

@caridy caridy closed this as completed Feb 6, 2020
@devsnek
Copy link
Member

devsnek commented Feb 7, 2020

@caridy so none of these hooks (particularly HostEnsureCanCompileStrings) will be provided by this api?

@caridy
Copy link
Collaborator

caridy commented Feb 7, 2020

correct! no hooks at the Realm level. Eventually, once a Realm Object is created, it can resolve what parameterized evaluator it belongs to (if any), and use that as a host, providing the level of control that you might need at the evaluator level.

@devsnek
Copy link
Member

devsnek commented Feb 7, 2020

@caridy would it be possible to link to this "parameterized evaluator" in the proposal repo somewhere, combine the information, etc? I'm finding it incredibly difficult to get a complete picture of what the realms api is, what "parameterized evaluators" are, how they fit together, etc.

@erights
Copy link
Collaborator

erights commented Feb 7, 2020

The "parameterized evaluator" is now the Compartment. In the context of SES we explain the semantics of the Compartment at https://www.youtube.com/watch?list=PLzDw4TTug5O3vIAd4IR1Gp5t_46co_dv9&v=1sjpRqms_nA and https://github.com/tc39/proposal-ses .

attn @jfparadis

The SES group have not yet discussed the semantics of Compartment outside of SES. Until recently we were considering it only as part of SES and only present under SES. However, at the last SES meeting https://www.youtube.com/watch?v=zX2F0BEteOA&list=PLzDw4TTug5O1jzKodRDp3qec8zl88oxGd we agreed to move the host hooks that are naturally at the realm level into the Compartment API, at the price of making a Realm constructor per compartment, much as we currently make a Compartment constructor per compartment.

A consequence of this decision is that the Compartment API must be available both inside and outside SES. Most of the semantics of Compartment I explain in my talk is meaningful outside of SES. Outside SES, of course, compartments would not be a unit of isolation. They would only be a means to customize evaluation --- which is still useful without isolation.

@devsnek
Copy link
Member

devsnek commented Feb 7, 2020

@erights so to verify if i understand this...

Realms will not include methods for evaluation, just the ability to create new realm records from js. Compartments are like Realms except that they inherit their intrinsics from a realm instead of creating their own from scratch. Compartments would expose the methods for actually running scripts and modules.

Something like this? (pseudo-ish code):

const r = new Realm(global inits and whatnot);
// r.lockdown() // optionally call if you need frozen
const c = r.createCompartment(hooks and whatnot);
c.evaluateScript('1 + 1');

@erights
Copy link
Collaborator

erights commented Feb 7, 2020

yes!

As explained in the talk, the sooner we stop using the term "realm record" the better. The per-realm info is the shared intrinsics. (or shared primordials depending on where the definitions settle attn @allenwb ). The record-formerly-known-as-realm-record is now per-compartment rather than per-realm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants