-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Layering: Revamp InitializeHostDefinedRealm #3728
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
base: main
Are you sure you want to change the base?
Conversation
(also SetDefaultGlobalBindings)
|
The rendered spec for this PR is available at https://tc39.es/ecma262/pr/3728. |
| <emu-clause id="sec-makerealm" type="abstract operation" oldids="sec-initializehostdefinedrealm,sec-createrealm,sec-setrealmglobalobject"> | ||
| <h1> | ||
| MakeRealm ( | ||
| _customizations_: an Abstract Closure that takes a Realm Record and returns a List of 2 elements, each of which is either an Object or *undefined*, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be slightly nicer for callers if they can omit the second return value (or return a single value or a list). Only window agents need this complexity, everything else has them be the same.
(Also, thanks for working on this, love to see this made more formal!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the HTML spec, I believe that would change 2 lines of the form
Return « <var>global</var>, undefined ».
to
Return « <var>global</var> ».
or
Return <var>global</var>.
I suppose it's slightly nicer, but I'm doubtful that it's worth the increased complexity for IHDR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also Service Workers and probably everything else that wants to build on the JS specification that isn't HTML, but fair enough to not optimize for that as it's largely theoretical.
|
There's an alternative to commit 1: rather than a single customizations parameter that returns a List of 2 values, IHDR could have 2 customization parameters, one for the global object and one for the global this binding. (Each would be either E.g., as it stands (with this PR), But with the above alternative, it wouldn't have to bother with the AC: Also, I think that would make it easier for HTML's "create a new realm" algo to make the global this binding customization optional, if that's desired. |
|
With that second approach we could also make both parameters optional, rather than expecting |
|
And another thing: in IHDR, after the invocation of I'm wondering if that should be 'formalized' too, and if so how? I think the two choices (besides do nothing) are pass it in as a customization parameter or declare it as a host hook. In the HTML spec, do all realms have the same set of host-defined global object properties? |
Yeah, but as far as I can tell, there's exactly 2 calls to IHDR, one in the HTML spec and one in the ShadowRealms proposal. And that one call in On the other hand, it's not much difference to IHDR, so I'd be willing if the editors like it. |
|
I think in HTML all global object properties are taken care of by IDL. As in, they are taken care of when we allocate the object. Except for the deletion of |
Including the ones that IHDR sets via SetDefaultGlobalBindings? Or just the HTML-specific ones?
So they're already in place when IHDR first 'sees' the object.
I.e., maybe the "Create any host-defined global object properties on global" step isn't needed? |
|
HTML only takes care of the HTML-specific ones (modulo sometimes deleting And yeah, I think step 17 is only needed if a host wanted an ordinary object as global with its own properties, but it might as well create its own ordinary object with its own properties during customizations to get there? |
Right. So anyway, this makes me wonder about possible conflicts between properties on the host-supplied global and properties created in SetDefaultGlobalBindings. Should ES require that a host-supplied global object can't have any 'standard' properties? More generally, hosts are allowed to "provide additional types, values, objects, properties, and functions beyond those described in this specification", but it's not entirely clear where (in the pseudo-code) this happens. For things connected to the global object, we can imagine they're created as part of creating the global object that the host supplies to IHDR (as @annevk described), but what about things not connected to the global object? (E.g., note that I'm not sure it's worth having the pseudo-code cover this, but it might be worth a Note saying that the layering here isn't so clear-cut -- there can be other non-standard stuff happening that isn't encompassed by the pseudo-code. |
|
To some extent ES already requires that I think by running SetDefaultGlobalBindings (as you also observed in OP), but I wouldn't mind having additional requirements there. I would certainly consider it a mistake if the web platform introduced something that ended up replacing a built-in. (And vice versa. That kind of thing warrants coordination.) |
|
Currently (in this PR, but effectively in the status quo too), realm.[[GlobalObject]] is set when IHDR's invocation of customizations returns, but whatwg/webidl#1547 indicates that HTML can't wait until then. That is, the host should have the responsibility (or at least the option) of setting realm.[[GlobalObject]] itself. This suggests a couple possibilities:
|
|
I think the former is a clearer API, but since hosts have to do this correctly to get a workable execution environment it might not matter too much which way we go. |
This PR comprises a bunch of changes to InitializeHostDefinedRealm (IHDR). They're mostly independent, but I'm putting them into one PR to reduce churn for IHDR's callers (i.e., HTML and the ShadowRealm proposal, AFAIK).
@annevk: If/when the time comes, I can create a PR to update the HTML spec accordingly.
commit 1: Add customizations parameter
Currently, IHDR has no parameters. However, steps 10 and 12 say "If the host requires ..." so there's implicitly a need for the host to communicate what it requires. In the HTML spec, the algorithm to 'create a new realm' has that spec's only call to IHDR, and says to perform it with "customizations for creating the global object and the global this binding".
This commit makes explicit the communication of these customizations to IHDR. Specifically, it adds a customizations parameter to IHDR. The caller passes it an abstract closure that receives the realm record being initialized, and returns two objects to serve as the global object and the global
thisbinding. (Or it can return undefined in either spot, to take the default.)For example, where the HTML spec might currently say (very roughly):
it would instead say:
(The abstract closure doesnt appear to make use of the realm passed to it, but the new Window object is presumably somehow created in realm.)
(This commit is basically the same as what I described here: #3274 (comment))
commit 2: Layering: Make IHDR non-throwing
Currently, IHDR is declared to return either a normal completion containing
~unused~or a throw completion.The only way that IHDR can throw is if
I think this can't happen if the global object is the IHDR-default, so it can only happen if the host provides the global object.
So, looking at IHDR's callers:
(1)
The proposed ShadowRealm function invokes IHDR with no customizations, so the global object is the IHDR-default, so this invocation IHDR can't throw. (So even without this commit, ShadowRealm should invoke IHDR with the '!' prefix instead of '?'.)
(2)
The HTML spec invokes IHDR with customizations, so IHDR could (theoretically) throw depending on what HTML supplies as the global object. Looking at the things it does supply, I haven't been able to prove to myself that they cannot possibly cause IHDR to throw, but it's clear that the HTML spec ignores the possibility that IHDR might throw, which suggests that no-one expects it to throw.
In any event, it seems like it would be self-sabotage for a host to supply a global object that could cause IHDR to throw.
So it seems reasonable for IHDR to become non-throwing, requiring that if the host provides the global object, it must be such that no abrupt completions occur.
It seemed cleanest to me to also make SetDefaultGlobalBindings non-throwing.
(@michaelficarra suggested this idea in #3497 (comment))
commit 3: Editorial: Create the realm execution context slightly later
Currently, IHDR creates+initializes the realm execution context in the middle of initializing the realm. Instead, do all the realm stuff, then do all the execution context stuff, just as a separation of concerns.
This is the same idea as in PR #3497, but here the context stuff can be right at the end of IHDR, because SetDefaultGlobalBindings is now non-throwing (assuming the previous commit).
commit 4: Layering: Return the realm EC from IHDR
Currently, IHDR creates an execution context (EC) for the new realm and pushes it onto the EC stack. Then IHDR's caller does (roughly):
It's unnecessary to involve the EC stack (and the concept of the running EC). Just have IHDR return the realm EC. So then IHDR's caller would do:
This is the same idea as PR #3274, but somewhat simpler given the above commits.
(It was the closure of that PR that prompted me to create this PR.)
commit 5: Layering: Rename IHDR as MakeRealm
To me, the name "InitializeHostDefinedRealm" suggests "the host has defined a realm, now this operation must initialize it", which is not very accurate.
Instead, "MakeRealm" seems appropriate.
The name CreateRealm would also work, except there used to be (before PR #3139 was merged) a CreateRealm operation that covered what's now the first 4 steps of IHDR, so that could possibly cause confusion (for very few people).
Renaming IHDR isn't necessary, of course, but given the changes of the preceding commits, it's a minor additional tweak.