The "initialization" steps for Web browsers
allen at wirfs-brock.com
Tue Jun 10 15:41:05 PDT 2014
On Jun 10, 2014, at 2:08 PM, Ian Hickson wrote:
> On Tue, 10 Jun 2014, Allen Wirfs-Brock wrote:
>>> Is my understanding correct that the HTML spec should invoke this
>>> algorithm when the HTML spec creates the Window object?:
>> Not exactly, although if you had said "first" Window object then maybe
>> you statement would be correct.
>> As you know, an ECMAScript environment may have multiple co-existent
>> "global objects". The ES spec. abstracts the concepts associated with
>> each global object as a "Realm". All ECMAScript code execution must take
>> place in the context of a Realm so an initial Realm must be established
>> before any ES code executes.
> What is an "ECMAScript environment" in this context? Is it the scripting
> engine behind a unit of related similar-origin browsing contexts? Or is it
> the scripting engine associated with a particular event loop?
> In the case of two pages that are running in different origins, each with
> their own Window object, does the ES spec attempt to answer the question
> of how those two scripts should interact if they access each others'
> Window objects? Or is that something for the HTML spec?
Almost every concept you used in the above two paragraphs are web platform specific concepts that are not even in the normal ECMAScript domain of discourse.
By an ECMAScript Environment (and this is what Ecma-262 defines, although it doesn't actually use that name) I mean a heap of ECMAScript objects (and related values) that may directly reference (point to) each other and a single thread of execution of ECMAScript code. The environment may include multiple "global objects".
In web terms, this could means several (same-origin??) windows and any associated Iframes, as long as there is only a single thread of ES code execution that encompasses them.
It could not include a both the object/script state of Window and of a WebWorker because logically a WebWorker's tobjects may not contain references to the Window's object (and visa-versa) and because both the Window and the Worker have independent and potentially concurrent execution threads for ES code.
While the spec. doesn't directly address this, I also like to assume fault isolation between ES environment. A fault in one ES environment should not be able to directly cause failure of another ES environment. Basically, like a Unix process.
Whether certain Web constructs are modeled by sharing a single ES environment or as separate (but possibly communicating) ES environment is up to you and/or browser implementors.
The possibility of interactions within an ES environment is all at the level of pointers between objects. If ES code has access to an object that contains a pointer to another object, then the code can interact with the second object. You might interpose proxying mechanism to try to isolate subgraphs of objects, but at the level of the ES semantics, such proxies are just additional objects with their own behaviors.
>> Section 8.5 defines the initialization process that occurs for an ES
>> engine before any ES code executes. It includes establishing the first
>> Realm. Whether or not that initial Realm actually corresponds to the
>> first "Window" is something you need to decide. For example, I can
>> imagine that for some hosts the first Realm might actually some sort of
>> utility Realm that is used for loading code and "forking" user Realms.
> Such a "utility Realm" sounds like an implementation detail that wouldn't
> appear in a spec, though, no? Would it be exposed or detectable in any way
> from aithor script?
> There's not really a "first" Window from the point of view of the HTML
> spec. I'm not sure how an initial Realm would really map to a browser.
Such a "utility Realm" doen't appear in the ES spec. But it might have a used in the spec. that defines some specific hosting environment.
If you want all documents from a given origin to operate within a single ES environment (is that a reasonable model?) then the first time you load a document from a new origin you might launch a new ES Environment with a a new Window object as its first Realm.
>> 8.5 can't be performed for each Window object that shares a common ES
>> engine because it essentially restarts the entire ES engine. Instead, I
>> would expect that the steps of InitializeFirstRealm (8.5.1) to be
>> approximately what should be called for each Window object.
> Ok. I think part of my confusion comes from step 7, then, which says "one
> or more" scripts. I think if that was changed to "zero or more", I could
> say in the HTML spec that the Initialization steps run as required by the
> ES spec, and that in HTML implementations, step 7 must obtain no scripts.
> Then, separate from this, I would call CreateRealm() to get a realm and
> then call InitializeFirstRealm(realm) with that realm? Is that right?
Yes, sounds about right. Particularly if I apply some renaming.
>> This suggests that InitializeFirstRealm is poorly named. Perhaps it
>> should be renamed InitializeHostRealm. There may be additional
>> refactoring that is needed between 8.5 and 8.5.1.
> I'm happy to use whatever terms you think are best.
>>> If so, what should the browser do in step 7? I don't fully understand
>>> how this is supposed to work. Suppose a page is just:
>>> <script> alert(document.body.innerHTML); </script>
>>> <script> alert(document.body.innerHTML); </script>
>>> If I read the #sec-initialization algorithm correctly, the scripts
>>> will execute back-to-back with no change in the DOM, so they'll output
>>> the same text. But the Web requires that these output different text,
>>> since the second <script> element won't be in the DOM when the first
>> ES doesn't know anything about the DOM, external script dependencies,
>> etc. The ES model is that it has a simple queue (populated by the host)
>> of script execution tasks and that the execution of the scripts in the
>> queue take place in order.
>> A simple command-line ES host probably would, as part of step 7, add a
>> ScriptEvaluationTask to the queue for each script file listed on the
>> command-line. They would then be evaluated in sequence.
>> However, you don't have to do that and step 7 isn't the only place you
>> can add new ScriptEvaluationTasks.
> If step 7's "one or more" is what is intended (as opposed to the "zero or
> more", see above), what is the script that a browser obtains in step 7?
I think it should be zero or more.
>> I would imagine you would maintain your own queues and dependency
>> algorithms that track order and DOM update dependencies such as between
>> the two script tags in your example. You would then only EnqueueTask a
>> ScriptEvaluationTask when it DOM update dependencies has been satisfied.
> Well, we want to make sure that browsers only have one dependency
> algorithm, we wouldn't want to have redundancy there. See the "Integrating
> the Webs' dependency systems" thread from a few weeks back. I'm trying to
> understand how ES6's loading logic works so that I can figure out how to
> integrate or extend it to handle the more elaborate needs of other parts
> of the Web platform, so that we can e.g. have image loading handled by the
> same logic as module loading, since they need to share network resources,
> can have interdependencies, etc.
We may have some chicken and egg issues to work through.
But, in general the ES spec. only needs to address the semantic issues of things it defines. For example, it cares about the relative ordering of Promise Tasks because that is part of the ES promise emantics. But it doesn't care about the relative ordering of individual PromiseTasks and future cript evaluation tasks because there are no defined semantic dependencies between those. However, as we move more semantics into ES (for example, event callbacks and timeouts are likely future additions) we will probably have more dependencies to specify.
>> Alternatively, you might define a new kind of ES Task, let's call it a
>> SyncDOMTask. Then at step 7 you might EnqueueTask a DOMSyncTask onto the
>> "ScriptTasks" queue between the two ScriptEvaluationTasks.
> Are these tasks related in any way to the HTML spec's task queues and
> event loop mechanism? Should we integrate these somehow also?
At our latest TC39 meeting we decided to use the term "Job" for what we had been calling "Task" in the ES spec. Specifically to avoid confusion with the HTML spec.
We need to avoid over-coupling the ES spec. to the HTML spec as ES is used in other host environments. That's why for Tasks(soon to be Jobs) we only define the minimum needed to have a consistent semantics across all ES hosts.
Basically, what you should do is use ES Jobs as the mechanism for saying here is a bit of ES code that needs to be executed before/after/independently from some other bit of code. But the actual criteria for deciding to make such a request needs to be in your spec.
>> I understand that this is all pretty vague and leaves a lot up to you.
> That's fine. :-)
> I just want to make sure it's all well-defined, I don't mind doing the
> heavy lifting.
>> But I need to define ES execution in a host independent manner. I'm
>> trying to provide the building blocks that you and other hosts need to
>> describe how their complex environment-specific semantics integrate with
>> the baseline ES execution semantics.
>>> (Also, how could step 6's substeps ever get triggered?)
>> Working backwards, step 5 does many things, some of which are specified
>> as having error conditions and exceptions, so I have to take into
>> account what happens if any errors occur. Step 6, just says that if they
>> do then the startup of the ES environment has failed. If an implementor
>> can prove that they [can't] trigger any of those error conditions then
>> they don't have to worry about it. But for completeness, I do.
> Do you have an example of how any of those steps could fail?
The implementation provided global object could throw during the processing of SetDefualtGlobalBindings
> It seems to me that if step 6 triggers, the whole scripting engine has
> failed to start up, which seems like it should be something that is
> non-conforming. :-)
Exactly, the spec. essentially says that if exceptions occur during start-up then a conforming implementation must terminate. If we said nothing then an implementation might not check for such exceptions and could start ES code execution with in incompletely initialized set of global bindings.
>> It's up to you to define what you initially enqueue in step 7. It could
>> be nothing (step 7 currently says "one or more", it probably should say
>> "zero or more").
> Zero or more would, I think, fix my confusion here.
>> Step 8 just says to dispatch the next pending ES Task. You need to do
>> that to actually get things started.
> NextTask seems like it is somewhat redundant with the HTML event loop
> mechanism. Ideally I think I'd like to have the hooks set up so that when
> a task completes on the ES side, it just returns to the HTML event loop,
> which then does its stuff, and eventually calls back into the ES spec to
> run the next script.
That's pretty much what NextTask is. Steps 1-3 cleans up after the just completed task. Steps 4-5 calls out to the host provided task scheduler. Steps 6-10 initiates execution of the task that was selected by the host. Step 9 is an extra hook that allow the host environment to do additional host-spec processing for each task immediately before it is executed. It's something Boris asked for to manage domain switching issues.
>> It occurs to be that these implementation-specific extension points may
>> be hard to find as they hare buried as steps in several algorithms. in
>> my next revision I see if I can define an abstraction operation
>> corresponding to each extension points. They we will have a list of
>> operations that a host must define.
> That would certainly help, yes.
> Ian Hickson U+1047E )\._.,--....,'``. fL
> http://ln.hixie.ch/ U+263A /, _.. \ _\ ;`._ ,.
> Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
More information about the es-discuss