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

Editorial: Return created EC from InitializeHostDefinedRealm #3274

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

linusg
Copy link
Member

@linusg linusg commented Jan 27, 2024

This AO is not being used in ECMA-262 directly, but from real-world experience implementing & using is as-is I can say that having to pull the Realm out of the running execution context is somewhat awkward.

This change is not backwards compatible with how the HTML spec uses the AO, but will allow simplifying the following:

  1. Perform InitializeHostDefinedRealm() with the provided customizations for creating the global object and the global this binding.
  2. Let realm execution context be the running JavaScript execution context.
  3. Remove realm execution context from the JavaScript execution context stack.
  4. Let realm be realm execution context's Realm component.

to

  1. Let realm execution context be InitializeHostDefinedRealm() with the provided customizations for creating the global object and the global this binding.
  2. Let realm be realm execution context's Realm component.

(https://html.spec.whatwg.org/#creating-a-new-javascript-realm)

For hosts that don't have HTML's requirement of removing the running
execution context, it becomes a simple:

  1. Let executionContext be InitializeHostDefinedRealm().
  2. Let realm be executionContext.[[Realm]].

@linusg
Copy link
Member Author

linusg commented Jan 27, 2024

(can someone tell me why the IPR form check is failing? This isn't even my first contribution 😅)

@bakkot
Copy link
Contributor

bakkot commented Jan 27, 2024

(can someone tell me why the IPR form check is failing? This isn't even my first contribution 😅)

main is currently broken, unrelated to this PR.

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 27, 2024

This still requires the HTML spec to grab the running execution context and remove it from the execution context stack. This seems to me like bad coupling (effectively global-data coupling via the EC stack): The HTML spec is relying on InitializeHostDefinedRealm (IHDR) having pushed the EC onto the EC stack, and the ES spec is sort-of relying on the HTML spec popping it from the EC stack.

Moreover, HTML would be getting realm and realm execution context via different means, so one might want to assert that the returned realm is in fact realm execution context's Realm component, which kind of defeats the purpose.

Instead, I think things would be cleaner if IHDR just returned the EC (having popped it from the EC stack, so that's not the caller's job any more). Sure, it isn't backwards compatible, but this PR is suggesting a change to the HTML spec anyway.

So then the HTML spec would say:

  1. Let realm execution context be InitializeHostDefinedRealm() with the provided customizations for creating the global object and the global this binding.
  2. Let realm be realm execution context's Realm component.

For hosts that don't have HTML's requirement of removing the running execution context, it becomes a simple:

  1. Let realm be InitializeHostDefinedRealm().

Are there any such hosts? I.e., ones that are documented to invoke IHDR? I couldn't find any.

If they do exist and they're currently invoking IHDR without popping the new EC from the EC stack, that could create problems. (Apparently, it lead to issues for HTML, see whatwg/html#3784, though I don't know what the issues were.)

@linusg
Copy link
Member Author

linusg commented Jan 28, 2024

Thanks for the suggestions! I'm open to alternative solutions if the end result is a net positive :)

Instead, I think things would be cleaner if IHDR just returned the EC (having popped it from the EC stack, so that's not the caller's job any more).

Interestingly that's also what we did in LibJS, although without popping it from the stack beforehand:

https://github.com/SerenityOS/serenity/blob/99fbd33d7d887723372e861be27f2743d335ecb5/Userland/Libraries/LibJS/Runtime/Realm.cpp#L83

Are there any such hosts? I.e., ones that are documented to invoke IHDR? I couldn't find any.

Depends on what you mean by documented - by means of another spec? Probably not, but outside of ECMA-402/HTML I'm not even aware of anything else having a dependency on ECMA-262. Known to exist? Sure, I know of at least two (https://codeberg.org/kiesel-js/kiesel/src/commit/3177581d63753baf525fac5d0151c78f039d09a9/src/cli.zig#L757-L758, https://github.com/SerenityOS/serenity/blob/99fbd33d7d887723372e861be27f2743d335ecb5/Userland/Libraries/LibJS/Runtime/VM.h#L339-L344), and not popping the EC was never problematic for either - that always seemed like a HTML-ism to me.

@linusg linusg force-pushed the return-realm-from-initializehostdefinedrealm branch from da96f27 to 4ed1126 Compare January 28, 2024 15:43
@linusg linusg changed the title Editorial: Return created Realm from InitializeHostDefinedRealm Editorial: Return created EC from InitializeHostDefinedRealm Jan 28, 2024
@linusg
Copy link
Member Author

linusg commented Jan 28, 2024

I've implemented your suggestion, PTAL!

@jmdyck
Copy link
Collaborator

jmdyck commented Jan 30, 2024

(This reply probably doesn't have much bearing on the PR.)

Instead, I think things would be cleaner if IHDR just returned the EC (having popped it from the EC stack, so that's not the caller's job any more).

Interestingly that's also what we did in LibJS, although without popping it from the stack beforehand:

Cool.

... hosts that don't have HTML's requirement of removing the running execution context ...

Are there any such hosts? I.e., ones that are documented to invoke IHDR? I couldn't find any.

Depends on what you mean by documented - by means of another spec?

Yup, that's what I meant. The details of how IHDR conveys an execution context to its caller are only relevant for a spec that defines how a host interacts with ECMA-262. The implementation can convey it however it likes (if it even has that separation), as your LibJS example shows.

I know of at least two [such hosts] (https://codeberg.org/kiesel-js/kiesel/src/commit/3177581d63753baf525fac5d0151c78f039d09a9/src/cli.zig#L757-L758, https://github.com/SerenityOS/serenity/blob/99fbd33d7d887723372e861be27f2743d335ecb5/Userland/Libraries/LibJS/Runtime/VM.h#L339-L344), and not popping the EC was never problematic for either -

I'm curious whether, for those implementations, leaving the EC on the stack was not just unproblematic but actually necessary. (ScriptEvaluation asserts that there's an underlying EC on the stack, but I don't understand why.)

that always seemed like a HTML-ism to me.

Isn't LibJS used in Serenity's browser? (Doesn't it need to be concerned with HTML-isms?)

spec.html Show resolved Hide resolved
@linusg linusg force-pushed the return-realm-from-initializehostdefinedrealm branch from 4ed1126 to 4112041 Compare January 31, 2024 18:51
@linusg
Copy link
Member Author

linusg commented Jan 31, 2024

Have updated ? to ! after the completion check.


I'm curious whether, for those implementations, leaving the EC on the stack was not just unproblematic but actually necessary.

At least in LibJS it was primarily to ease creating objects in the "main" realm as things like "current realm" rely on an EC being on the stack. There certainly are ways around that if you can guarantee nothing downstream asks for the current realm.

Isn't LibJS used in Serenity's browser? (Doesn't it need to be concerned with HTML-isms?)

Indeed, but for the most part is is a clean ECMA-262 implementation that doesn't try to concern itself with HTML-specific functionality (there are minor exceptions to this). Host-defined behavior is usually made opt-in by providing a callback to the AO that requires it, and host-defined data passed around as void* and casted/accessed exclusively on the web side.

@jmdyck
Copy link
Collaborator

jmdyck commented Feb 1, 2024

I also wonder if the only reason IHDR pushed newContext onto the EC stack was to make it accessible to HTML. So if IHDR instead returns newContext, does it even need to involve the EC stack? But that isn't something this PR needs to answer.

@linusg linusg force-pushed the return-realm-from-initializehostdefinedrealm branch from 4112041 to 947b436 Compare March 6, 2024 23:19
This AO is not being used in ECMA-262 directly, but from real-world
experience implementing & using is as-is I can say that having to pull
the Realm out of the running execution context is somewhat awkward.

This change is not backwards compatible with how the HTML spec uses the
AO, but will allow simplifying the following:

1. Perform InitializeHostDefinedRealm() with the provided customizations
   for creating the global object and the global this binding.
2. Let realm execution context be the running JavaScript execution
   context.
3. Remove realm execution context from the JavaScript execution context
   stack.
4. Let realm be realm execution context's Realm component.

to

1. Let realm execution context be InitializeHostDefinedRealm() with the
   provided customizations for creating the global object and the global
   this binding.
2. Let realm be realm execution context's Realm component.

(https://html.spec.whatwg.org/#creating-a-new-javascript-realm)

For hosts that don't have HTML's requirement of removing the running
execution context, it becomes a simple:

1. Let executionContext be InitializeHostDefinedRealm().
2. Let realm be executionContext.[[Realm]].
@linusg linusg force-pushed the return-realm-from-initializehostdefinedrealm branch from 947b436 to 668b11d Compare April 9, 2024 13:52
Copy link
Contributor

@syg syg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems fine to me, but this entire AO is odd (because it's old) because the host provides steps instead of providing definitions for host hooks.

Specifically, the steps for creating a new global object and for what the this value ought to be can be combined into a single host hook that returns a pair containing those things.

Since we're making HTML changes anyway, would you be up for doing that at the same time @linusg? I'd like to minimize the number of HTML spec PRs we'll need to make.

@jmdyck
Copy link
Collaborator

jmdyck commented May 15, 2024

This seems fine to me, but this entire AO is odd (because it's old)

See also PR #3139 re eliminating some of this AO's oddness. I think it's mostly independent of this PR or the change you're suggesting, but you might want to consider it at the same time.

@linusg
Copy link
Member Author

linusg commented May 16, 2024

Specifically, the steps for creating a new global object and for what the this value ought to be can be combined into a single host hook that returns a pair containing those things.

I agree, that seems nicer!

Since we're making HTML changes anyway, would you be up for doing that at the same time @linusg? I'd like to minimize the number of HTML spec PRs we'll need to make.

Sure :) Looking at @jmdyck's PR again I very much prefer the unification of these AOs, would you be fine with merging that and me making these changes + an upstream HTML PR on top of it?

@michaelficarra michaelficarra added layering affects the public spec interface and may require updates to integrating specs and removed editorial change labels May 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
layering affects the public spec interface and may require updates to integrating specs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants