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

Layering: formalize the "continent" concept #226

Closed
wants to merge 1 commit into from
Closed

Conversation

domenic
Copy link
Member

@domenic domenic commented Dec 2, 2015

This includes a couple fixes to help HTML and ES play well together. The second one, allowing the global this and global object to diverge, is significant. It fixes the following from HTML:

This is a willful violation of the JavaScript specification current at the time of writing (ECMAScript edition 5, as defined in section 10.4.1.1 Initial Global Execution Context, step 3). The JavaScript specification requires that the this keyword in the global scope return the global object, but this is not compatible with the security design prevalent in implementations as specified herein.

/cc @annevk.

@ljharb
Copy link
Member

ljharb commented Dec 2, 2015

nice - if this goes in I'll be able to simplify the System.global proposal as well.

@domenic
Copy link
Member Author

domenic commented Dec 4, 2015

I have added another commit defining "continents" (aka "vats") and simplifying initialization. It is very nice and simplifies some confusion I had with HTML integration immensely.

I could use some help figuring out how to make my <dfn>s into auto-links; I would like "continent" to link to my dfn wherever it appears.

@anba
Copy link
Contributor

anba commented Dec 4, 2015

I don't understand how the simplified initialization is going to work: The new Realm is not yet created, but the host environment should already provide the globalObject and globalThis value. And to be able to create objects, you need an associated Realm.

8.3.5 GetGlobalObject should probably return the globalThis value or is there a difference between unresolvedVariable = 0 and this.unresolvedVariable = 0 in browsers? (GetGlobalObject is only used for unresolved references in 6.2.3.2 PutValue.)

9.2.1.2 OrdinaryCallBindThis: The function this-binding should use the globalThis value, shouldn't it? ((function(){ return this })() === this in browsers.)

@domenic
Copy link
Member Author

domenic commented Dec 4, 2015

And to be able to create objects, you need an associated Realm.

Can you explain why that is? My understanding is that functions have an associated realm, but not objects. And IIUC the realm-then-global-object order of operations is not how it works in browsers, so we should probably change the spec to accomodate if that's the case.

GetGlobalObject

OrdinaryCallBindThis

I think these are correct as-is but will produce test cases later to confirm for you.

@anba
Copy link
Contributor

anba commented Dec 4, 2015

IIUC realm and global creation happens at the same time in browsers (JS_NewGlobalObject in SM or Context::New in V8). I think it's just the CreateIntrinsics step which should be moved out of CreateRealm into InitializeHostDefinedRealm.

@domenic
Copy link
Member Author

domenic commented Dec 4, 2015

Hmm, so I didn't see you respond to my question of why you require a Realm to create objects. So I am going to assume that is OK?

GetGlobalObject

This should continue to return the global object, not the global this value. The reasoning is that var declarations create non-configurable properties on the global object. But, in order to preserve the fundamental invariants, any declared vars must disappear from the window proxy object after navigation. (Example.) Thus when observing the window proxy properties from the outside, they must appear non-configurable. And, it must not be possible to define a non-configurable property on the window proxy.

This is captured in the tentative window proxy spec. If GetGlobalObject used the thisValue, it would get a window proxy, and then defining any vars would fail, since you can't call [[DefineOwnProperty]] with Configurable: false. (GlobalDeclarationInstantiation passes D = false for global var declarations.)

So GetGlobalObject should continue to use the actual global object, which it can define such properties on.

OrdinaryCallBindThis

Correct, this should be changed. Uploading amended patch now.

@anba
Copy link
Contributor

anba commented Dec 4, 2015

Hmm, so I didn't see you respond to my question of why you require a Realm to create objects. So I am going to assume that is OK?

As long as no intrinsics are needed, for example %ObjectPrototype% on the proto-chain. Alternatively the prototype chain needs to be updated after the intrinsics are present. (This seems to be the case in SpiderMonkey).

GetGlobalObject

This should continue to return the global object, not the global this value.

GetGlobalObject is only used in PutValue, GlobalDeclarationInstantiation directly works on the global Environment Record. Nevertheless, I don't think the difference between this.unresolvedVariable = 0 and unresolvedVariable = 0 matters, it's more or less the same as the difference between this.globalVariable = 0 and globalVariable = 0 (the former calls Set() on the globalThis value whereas the latter calls Set() on the global object).

@domenic
Copy link
Member Author

domenic commented Dec 4, 2015

As long as no intrinsics are needed, for example %ObjectPrototype% on the proto-chain.

That makes sense. It would probably be easier to move those steps back into the middle of the algorithm as call-outs to the host. I'll do that then.

Nevertheless, I don't think the difference between this.unresolvedVariable = 0 and unresolvedVariable = 0 matters

I think I end up agreeing. This is largely because WindowProxy transparently proxies [[Set]]. If it did not then we would have an observable difference. In such a hypothetical world I still think global object makes more sense than global this value.

@anba
Copy link
Contributor

anba commented Dec 5, 2015

Obviously I forgot to mention why the realm creation and initialization steps are currently split into several operations: These are all leftovers from previous drafts which contained the Realm API. That also means if the Realm API has a comeback, we will again need to split the initialization process into several methods. But I'm not sure it's worth to consider this aspect right now.


<p>Each continent contains a set of job queues, as defined in <emu-xref href="#sec-jobs-and-job-queues"></emu-xref>.</p>

<emu-note>Typically, a continent is implemented as a single thread of execution. For example, in a web browser, each unit of related similar-origin browsing contexts consists of a single continent, as does each worker.</emu-note>
Copy link
Member

Choose a reason for hiding this comment

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

This note doesn't clarify anything to me. In general, requiring super detailed domain knowledge of other specifications to understand what this note is saying seems bad.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm. This doesn't seem like super-detailed knowledge. Do you think there's a way to phrase this to make it easier? Maybe replace "unit of related similar origin browsing contexts" with "browser tab (including any frames or iframes)"?

Copy link
Member

Choose a reason for hiding this comment

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

If someone is not a browser implementer, this example would require much research to understand I think?

What are you trying to clarify with this note?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm trying to provide a somewhat-intuitive conceptual understanding for authors and implementers as to what a continent corresponds to in the "real world." Before embarking on this journey, it wasn't clear to me at all whether we were supposed to spin up a separate instance of the ES spec for each global, or each browser, or each browser window, or what. I am trying to point out that it's essentially one continent (or "instance of the ES spec") per thread/event loop. The "For example" tries to bring that even closer to real-world experience, showing a system where many realms can coexist (with "political barriers" between them, cf. es-discuss) within the same continent.

Copy link
Member

Choose a reason for hiding this comment

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

This seems like an appropriate clarification for HTML but I don't think it provides much value in the ECMAScript spec and has the downside of being potentially confusing.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it'd be helpful if ES were able to give some example of what a continent was in the real world of actual JS engine implementations. Can you suggest any such examples that you don't think would be confusing?

@bterlson
Copy link
Member

bterlson commented Dec 7, 2015

@domenic I left some specific comments, but in general I want to split this into two pieces. The globalThis thing is clearly a layering concern that I am happy to pull in now. The text around "continents" I worry is subtle enough and normative enough that it should probably advance through the normal proposal process. It should see some committee debate :)

@domenic
Copy link
Member Author

domenic commented Dec 8, 2015

The globalThis thing is clearly a layering concern that I am happy to pull in now.

Awesome!

The text around "continents" I worry is subtle enough and normative enough that it should probably advance through the normal proposal process. It should see some committee debate :)

Hmm. This wasn't my intent, although I do think it would be a good thing to highlight to the committee and let them help advise on changes to. Could we make it less normative perhaps? Perhaps by removing the object references sentence you noted? Would it help to get sign-off from committee members with particularly relevant interests, like @allenwb and @erights?

My main reason for introducing it was that I need something that HTML can stick on each HTML event loop to make it clear that each HTML event loop gets a single set of ES job queues. Currently the only term ES provides for that is "ECMAScript implementation," as in, "Every ECMAScript implementation has at least the Job Queues defined in Table 26." But using this term seems misleading in a number of ways, especially because the spec usually uses it in the sense of "JS engine". (Example: "The "callee" property has a more specific meaning for non-strict functions and a "caller" property has historically been provided as an implementation-defined extension by some ECMAScript implementations.")

That is, the main reason for introducing it is that I need some vague concept that HTML can:

  • Create whenever the browser creates a new event loop
  • Reference whenever it does EnqueueJob(...), in order to make it clear what collection of realms ("continent") the given script execution or promise microtask is executing in.

"Continent" seemed like a nice way to get this while also making at least a brief start toward the stuff outlined in the linked es-discuss threads.

@bterlson
Copy link
Member

bterlson commented Dec 8, 2015

I understand the intent and I completely agree with the rationale. I also agree that the normal proposal process is overweight for this change. It just seems to me like a subtle enough area that we should discuss more, and I think is something we would typically discuss in TC39 before including in a draft. That said, we definitely want feedback from @allenwb and @erights before pulling this in so let's get that first.

@domenic
Copy link
Member Author

domenic commented Dec 8, 2015

Sure, I guess I can try to work around the lack in HTML for the next couple months. I kind of think since it's non normative it should be fine to commit first ask questions later but I understand.

@domenic
Copy link
Member Author

domenic commented Dec 8, 2015

I addressed the review comments on the second commit, so those first two should be pull-in-able, I think. (I also rebased on master.) I left the third one in this branch because I didn't want to lose the conversations.

@domenic
Copy link
Member Author

domenic commented Dec 8, 2015

Actually, wait, I need to keep the merger of Initialization() and InitializeHostDefinedRealm(), even without the continent stuff. Let me separate out the continent commit into two, one that you can pull in now and one that we can leave for later.

@domenic
Copy link
Member Author

domenic commented Dec 8, 2015

OK, all separated. This should make it easier for @allenwb and @erights (and anyone else) to review just the last commit about continents, if they want.

domenic added a commit to whatwg/html that referenced this pull request Dec 8, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution.
domenic added a commit to whatwg/html that referenced this pull request Dec 8, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution.
@zenparsing
Copy link
Member

I would tend to agree that any specification of vats within 262 needs to have some tc39-time.

@bterlson
Copy link
Member

bterlson commented Dec 8, 2015

I merged the uncontroversial aspects. Continent work is now pending consensus.

@bterlson bterlson added the needs consensus This needs committee consensus before it can be eligible to be merged. label Dec 8, 2015
domenic added a commit to whatwg/html that referenced this pull request Dec 8, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution.
domenic added a commit to whatwg/html that referenced this pull request Dec 11, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution. This also fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=27419.
domenic added a commit to whatwg/html that referenced this pull request Dec 14, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution. This also fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=27419.
domenic added a commit to whatwg/html that referenced this pull request Dec 14, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon. This fixes #380 and fixes #382.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution. This also fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=27419.
domenic added a commit to whatwg/html that referenced this pull request Dec 15, 2015
Points of note:

- ECMAScript now has the appropriate hooks (as of tc39/ecma262#226) for a separate global this value and global object, allowing us to fix a long-standing willful violation.

- Worker initialization was refactored extensively, to avoid creating WorkerGlobalScope objects before the corresponding realm was created. (The existing setup had the problem where it was creating a WorkerGlobalScope, derived from Object, in a thread that didn't even exist yet.)

- The "JavaScript global environment" concept was hackily removed. As discussed in #380 and #382, the only uses of "JavaScript global environment" are for a couple of canvas-related concepts which need to be removed anyway. And the definition we were using did not line up very well with ES's. We temporarily replace them with vague phrasing "lives in a window" and "lives in a worker"; this is OK since those sections will be deleted soon. This fixes #380 and fixes #382.

This is roughly steps 3, 4, and 6 of https://www.w3.org/Bugs/Public/show_bug.cgi?id=25981. It contains all the changes necessary to integrate with ES's new initialization mechanisms for a given host-defined realm, without yet any of the changes for script execution. This also fixes https://www.w3.org/Bugs/Public/show_bug.cgi?id=27419.
Previously, the concept of "ECMAScript implementation" initialization was highly implicit, and it was not clear that e.g. a browser would contain multiple "ECMAScript implementations", each with their own set of job queues. We make that explicit here by defining a "continent", per previous discussions in e.g. https://esdiscuss.org/topic/event-loops-in-navigated-away-from-windows and https://esdiscuss.org/topic/holy-mixed-metaphors-batman-was-event-loops-in-navigated-away-from-windows.

Since a continent now contains a set of job queues, it is now clearer (with the help of an additional non-normative note) that when doing EnqueueJob, a host should specify which continent they are working in.
@domenic domenic changed the title HTML layering Layering: formalize the "continent" concept Dec 17, 2015
@domenic
Copy link
Member Author

domenic commented Dec 17, 2015

I rebased this on master, and renamed the PR, so that it only contains the "continent" concept now. The previous commits were merged in b1ef33b, 9474c58, and eacbc9d.

This turns out to not be as necessary for HTML's clarity as I thought, given that HTML now overrides EnqueueJob and NextJob, so I don't feel too strongly about this addition any more. But, I think it's kind of a nice start at speccing something TC39 would probably like to spec anyway. It makes it clearer to readers, IMO, how a host environment with multiple "threads" would work, and fit with the existing specification. So I'll leave it up for brief discussion next meeting.

In the meantime, I'd invite @allenwb to take a look and give his thoughts, since the original idea is largely due to him.


<p>A continent may contain multiple realms, as defined in <emu-xref href="#sec-code-realms"></emu-xref>. Each realm belongs to exactly one continent. Depending on the host environment, code executed within a given continent's realms may or may not be able to reach objects from other realms in that continent. However, code executed in one continent must not be able to directly reference or share objects from another continent.</p>

<p>Each continent contains a set of job queues, as defined in <emu-xref href="#sec-jobs-and-job-queues"></emu-xref>.</p>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Presumably each continent also contains a single execution context stack.

@bterlson
Copy link
Member

bterlson commented Feb 8, 2016

Going to close this PR for now as the continent formalization has moved to the shared memory proposal.

@bterlson bterlson closed this Feb 8, 2016
@bterlson bterlson deleted the html-layering branch February 10, 2016 22:31
@lars-t-hansen
Copy link
Contributor

For reference, work continues in tc39/proposal-ecmascript-sharedmem#27.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs consensus This needs committee consensus before it can be eligible to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants