tc39 / proposal-compartments

Compartmentalization of host behavior hooks for JS
MIT License
122 stars 10 forks source link

Layer 0: Replace `importMeta` object with `importMetaHook` function #77

Closed nicolo-ribaudo closed 2 years ago

nicolo-ribaudo commented 2 years ago

ECMA-262 exposes two host hooks to initialize import.meta: HostGetImportMetaProperties and HostFinalizeImportMeta.

The second host hook is enough to cover all the use cases of the first hook, but not the other way around.

This proposal currently implements HostGetImportMetaProperties: the importMeta parameter of the Module constructor is equivalent to the list of properties returned by the hook. However, this is not enough to replicate the behavior of the various hosts:

With importMetaHook, both behaviors would be possible:

new Module(source, {
  importMetaHook(importMeta) {
    importMeta.url = someURL;
    Object.freeze(importMeta);
  }
});
new Module(source, {
  importMetaHook(importMeta) {
    importMeta.url = someURL;
    Object.setPrototypeOf(importMeta, ImportMetaPrototype);
  }
});

This has the same serializability implications of importHook: modules with a non-default importMetaHook would not be serializable.

caridy commented 2 years ago

Few clarifications needed:

  1. is the argument passed into importMetaHook an ordinary object created by the engine, empty at first, and passed into the hook?
  2. If the answer to 1 is "yes", then what's the __proto__ of the importMeta object argument?
  3. how many times is this hook called? once and then cached as it is today for the host hooks?
nicolo-ribaudo commented 2 years ago
  1. yes
  2. I propose null, which is what is already happening with the host hook (so that by default import.meta objects have a null prototype): step 4.a of https://tc39.es/ecma262/#sec-meta-properties-runtime-semantics-evaluation
  3. Yes, it's cached per-module and only called when import.meta is evaluated the first time.
caridy commented 2 years ago

I'm fine with this proposal.