Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upScriptEvaluationJob and TopLevelModuleEvaluationJob seem to be useless; let's remove them #240
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Dec 10, 2015
Contributor
Ordering inside the job queue is arbitrary, since the host environment supplies the script/module source codes to InitializeHostDefinedRealm() itself.
Host environments may enqueue new jobs to the "ScriptJobs" queue during runtime, these additional jobs are performed after the initial jobs passed to InitializeHostDefinedRealm/Initialization have finished. If and when a host environment enqueues additional jobs is not part of the ECMAScript specification.
Execution with a clean stack is important. However, this is already accomplished by the ScriptEvaluation and ModuleEvaluation algorithms themselves, which suspend the running context and restore it after.
I don't understand this point. What is a "clean" stack? And how does suspending and resuming the running execution context provide a "clean" stack? (Suspending an execution context does not imply it is removed from the execution context stack, so I don't know if you've used "clean" as synonym for "empty".)
EvaluateScript(realm, sourceText)
[...]
If code is an error indication, then return Completion{[[type]]: throw, [[value]]: code}.
code is not an ECMAScript language value, so it cannot be used in a Completion record (6.2.2 Table 8).
(4) Remove the ScriptJobs job queue, since nobody enqueues any jobs in it.
Other host environments may use the ScripJobs queue, e.g. CLI environments were used multiple times in the past to explain how ScripJobs can be used.
It's probably more useful for HTML to define its own _HTML_ScriptEvaluationJob which performs the additional setup/teardown and error handling logic.
Host environments may enqueue new jobs to the "ScriptJobs" queue during runtime, these additional jobs are performed after the initial jobs passed to InitializeHostDefinedRealm/Initialization have finished. If and when a host environment enqueues additional jobs is not part of the ECMAScript specification.
I don't understand this point. What is a "clean" stack? And how does suspending and resuming the running execution context provide a "clean" stack? (Suspending an execution context does not imply it is removed from the execution context stack, so I don't know if you've used "clean" as synonym for "empty".)
Other host environments may use the ScripJobs queue, e.g. CLI environments were used multiple times in the past to explain how ScripJobs can be used. It's probably more useful for HTML to define its own _HTML_ScriptEvaluationJob which performs the additional setup/teardown and error handling logic. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 10, 2015
Member
Host environments may enqueue new jobs to the "ScriptJobs" queue during runtime, these additional jobs are performed after the initial jobs passed to InitializeHostDefinedRealm/Initialization have finished. If and when a host environment enqueues additional jobs is not part of the ECMAScript specification.
Sure. But this doesn't impact anything, since as you said, host environments aren't forced to use "ScriptJobs" at all. If a host environment wants to run things after script evaluation has finished, it can just, well, run them after ScriptEvaluation has finished. The job queue isn't actually helping here.
I don't understand this point. What is a "clean" stack? And how does suspending and resuming the running execution context provide a "clean" stack? (Suspending an execution context does not imply it is removed from the execution context stack, so I don't know if you've used "clean" as synonym for "empty".)
No code must be running, is what I meant. A tangential point, in the end.
code is not an ECMAScript language value, so it cannot be used in a Completion record (6.2.2 Table 8).
Easy to fix.
Other host environments may use the ScripJobs queue, e.g. CLI environments were used multiple times in the past to explain how ScripJobs can be used.
A job queue that is unused by the spec does not need to go in the table of required-to-be-supported job queues. That's the only thing I mean by removing it.
CLI environments can just as easily use the scheme I described, which also works for HTML (whereas the current setup does not).
If CLI environments want to use a simple job queue for their script execution, they can of course create a new job queue (named whatever they want, even "ScriptJobs").
It's probably more useful for HTML to define its own HTMLScriptEvaluationJob which performs the additional setup/teardown and error handling logic.
This is not feasible for multiple reasons which I won't bother to get in to here. The overarching reason though is that we cannot have ES driving HTML's script execution, but instead we need to drive ES's script execution and job queue from within the preexisting HTML event loop framework, to better integrate with rendering, the microtask queue, worker termination, etc. We can do this the easy way, with HTML calling the proposed EvaluateScript() and EvaluateModule(), or the semi-hard way, with HTML calling out to ScriptEvaluation and ModuleEvaluation directly, or the extra-hard way, with HTML enqueuing ScriptEvaluationJob then immediately pumping the NextJob queue.
If my proposal is not accepted, I plan to do this the semi-hard way, which just means that ScriptEvaluationJob and its friend will be effectively "dead code" from the perspective of HTML, and that HTML will need to copy and paste some of the text in those sections into its own algorithms. That seems suboptimal compared to the easy way, especially since I've explained how the easy way is just as usable by other host environments as well.
Sure. But this doesn't impact anything, since as you said, host environments aren't forced to use "ScriptJobs" at all. If a host environment wants to run things after script evaluation has finished, it can just, well, run them after ScriptEvaluation has finished. The job queue isn't actually helping here.
No code must be running, is what I meant. A tangential point, in the end.
Easy to fix.
A job queue that is unused by the spec does not need to go in the table of required-to-be-supported job queues. That's the only thing I mean by removing it. CLI environments can just as easily use the scheme I described, which also works for HTML (whereas the current setup does not). If CLI environments want to use a simple job queue for their script execution, they can of course create a new job queue (named whatever they want, even "ScriptJobs").
This is not feasible for multiple reasons which I won't bother to get in to here. The overarching reason though is that we cannot have ES driving HTML's script execution, but instead we need to drive ES's script execution and job queue from within the preexisting HTML event loop framework, to better integrate with rendering, the microtask queue, worker termination, etc. We can do this the easy way, with HTML calling the proposed EvaluateScript() and EvaluateModule(), or the semi-hard way, with HTML calling out to ScriptEvaluation and ModuleEvaluation directly, or the extra-hard way, with HTML enqueuing ScriptEvaluationJob then immediately pumping the NextJob queue. If my proposal is not accepted, I plan to do this the semi-hard way, which just means that ScriptEvaluationJob and its friend will be effectively "dead code" from the perspective of HTML, and that HTML will need to copy and paste some of the text in those sections into its own algorithms. That seems suboptimal compared to the easy way, especially since I've explained how the easy way is just as usable by other host environments as well. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 10, 2015
Member
In the end there's a greater point, which is that if these mechanisms end up not being usable by host specifications, they've failed. We should be looking to collaborate on something usable, instead of assuming what's written down is already correct. During the design of ES2015 we didn't have time to validate that, but now we're making the effort, and changes should be expected.
|
In the end there's a greater point, which is that if these mechanisms end up not being usable by host specifications, they've failed. We should be looking to collaborate on something usable, instead of assuming what's written down is already correct. During the design of ES2015 we didn't have time to validate that, but now we're making the effort, and changes should be expected. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 10, 2015
Member
Actually, as noted in https://esdiscuss.org/topic/the-initialization-steps-for-web-browsers#content-18, this mess extends beyond script/module evaluation jobs. Promise jobs also have an impedance mismatch, where we want to make sure they are ordered correctly relevant to other enqueued microtasks.
The proposal there is to awkwardly spoon-feed the job queues, using the "implementation defined" sections to always empty them so that there is only one job to run, and then we can call NextJob undefined to trigger that job at the appropriate place in the event loop.
This seems over-complicated. I think maybe what will be better is for HTML to override the definitions of EnqueueJob and NextJob to be actually useful, and I can put together a slideshow for the next TC39 meeting explaining the problems with the current set up and proposing a revision. That revision which will essentially consist of replacing EnqueueJob with HostDefinedEnqueueJob and NextJob with YieldToHostEnvironment, and stipulating that host environments must follow the ordering invariant that the current spec awkwardly enforces. (Except it doesn't actually enforce them, because there are enough "implementation defined" steps which allow you to change the ordering arbitrarily.) We can even provide default implementations similar to the current ones.
|
Actually, as noted in https://esdiscuss.org/topic/the-initialization-steps-for-web-browsers#content-18, this mess extends beyond script/module evaluation jobs. Promise jobs also have an impedance mismatch, where we want to make sure they are ordered correctly relevant to other enqueued microtasks. The proposal there is to awkwardly spoon-feed the job queues, using the "implementation defined" sections to always empty them so that there is only one job to run, and then we can call NextJob undefined to trigger that job at the appropriate place in the event loop. This seems over-complicated. I think maybe what will be better is for HTML to override the definitions of EnqueueJob and NextJob to be actually useful, and I can put together a slideshow for the next TC39 meeting explaining the problems with the current set up and proposing a revision. That revision which will essentially consist of replacing EnqueueJob with HostDefinedEnqueueJob and NextJob with YieldToHostEnvironment, and stipulating that host environments must follow the ordering invariant that the current spec awkwardly enforces. (Except it doesn't actually enforce them, because there are enough "implementation defined" steps which allow you to change the ordering arbitrarily.) We can even provide default implementations similar to the current ones. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Looking forward to the presentation : ) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Dec 10, 2015
Member
I for one support this work and also look forward to the presentation. I would also suggest getting early feedback from @allenwb!
|
I for one support this work and also look forward to the presentation. I would also suggest getting early feedback from @allenwb! |
added a commit
to whatwg/html
that referenced
this issue
Dec 14, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 15, 2015
Member
OMG +1 @anba
The ES spec. is not a dependent spec. of the HTML spec. It has to support and proivide a common and consistent runtime semantics that is applicable to all hosting environments. The most basic hosting environment is a basic CLI invoked engine where all Scripts and Modules are available prior to runtime. That is the model whose semantics are directly provided by the specification; but those semantics include extension points that, if used properly, allow for host specific dynamic/deferred script/module loading semantics. In designing those hooks, I factored in requirements there were given to me by HTML folks but I also considered the probable requirements (based upon my experience with many different languages and hosts) of other likely hosts. At this time, we shouldn't be simplifying solely based upon HTML hosts without also having confirming support from other environments.
In particular,
- It's fine that your HTML binding does not provide any ECMAScript source texts to ECMAScript Initialization(). That is just an indication that there are no statically determined source texts (and note that the spec. says "zero or more..."). But this would not be the case for many other host environments and certainly not for most CLI hosts.
- Jobs and the job queues define the semantics for ES' "empty stack", run to completion execution model. This is essential.
- All jobs start with the invocation of an abstract operation, so there must be a distinct abstract operation for each distinct kind of job. It is the abstract operation that defines the specific semantics for each kind of job. The ability to define additional job kinds via additional abstract operations is one of the extension points. Separating the job specific semantics from the enqueuing semantics is a natural separation of concerns.
- ScriptEvaluationJob and TopLevelModuleEvaluationJob are the abstract operation used for those two specific kinds of jobs. It is important that there is a base, host independent semantics for initiating the evaluation of a Script or Module.
- ScriptEvaluationJob and TopLevelModuleEvaluationJob are only mentioned in ECMAScript Initialization() because the basic ES spec only explicitly covers the case of statically predetermined ECMAScript source texts. A host that supports dynamic source loading would would reference them in its host-specific dynamic loading semantics. (this would most likely occur in a host-specific job scheduler invoked as part of step 4 of NextJob.
- A HTML event handler is not a Script. Hosts that defined addition kinds of run-to-completion entities need to define their semantics via new kinds of job abstract operations. Annex B may be the place for doing this for HTML features that require new syntax driven semantics. See Bug 3139
|
OMG +1 @anba The ES spec. is not a dependent spec. of the HTML spec. It has to support and proivide a common and consistent runtime semantics that is applicable to all hosting environments. The most basic hosting environment is a basic CLI invoked engine where all Scripts and Modules are available prior to runtime. That is the model whose semantics are directly provided by the specification; but those semantics include extension points that, if used properly, allow for host specific dynamic/deferred script/module loading semantics. In designing those hooks, I factored in requirements there were given to me by HTML folks but I also considered the probable requirements (based upon my experience with many different languages and hosts) of other likely hosts. At this time, we shouldn't be simplifying solely based upon HTML hosts without also having confirming support from other environments. In particular,
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 15, 2015
Member
Nobody is thinking of the ES spec as a dependent of the HTML spec. We're just working out a way to make sure that the ES spec accurately reflects implementations. As of right now the ES spec is failing to do that. It tries to create a job queue abstraction, but does not allow that abstraction to integrate with hosts in a natural way, which is required for real-world implementation.
In particular, the only way to usably integrate the job queue is to spoon-feed it one job at a time, using the various implementation-defined extension points to ensure that only one job is ever in the queue, because this gives hosts the freedom to interleave jobs with other host operations in the appropriate order. Many of the jobs enqueued by the ES spec itself aren't even ever executed, because they need to be removed from the queue and then replayed later so that they can interleave properly with other host operations. (See https://esdiscuss.org/topic/the-initialization-steps-for-web-browsers#content-18.) And for script execution, hosts are better served by ignoring ScriptEvaluationJob and TopLevelModuleEvaluationJob, and use ParseScript/ScriptEvaluation and their module counterparts directly. This is in fact 100% necessary for some cases, like importScript()s or Node.js's require, both of which parse and evaluates a script when the call stack is non-empty.
A setup like the one I described, with EnqueueJob being replaced by a properly-restricted HostDefinedEnqueueJob, and NextJob being replaced by YieldToHostEnvironment, is much more flexible, and e.g. allows promise jobs to be properly interleaved with other host environment operations without the kind of awkwardness described above. We can achieve the same guarantees of empty stack and ordering by placing restrictions on the definition of HostDefinedEnqueueJob. And as I said, if we want to give an outline for a "simple reference virtual machine" and how it would execute, we can define default implementations of these that look similar to the current definitions.
Note that the issues I am discussing here are not unique to HTML. Node.js also has a structure that requires completely disregarding ES's current script/module evaluation and job queue semantics, given its interleaving of promise jobs with other microtasks, and its manner of script execution (both at startup and dynamically).
To some more specific points:
It's fine that your HTML binding does not provide any ECMAScript source texts to ECMAScript Initialization(). That is just an indication that there are no statically determined source texts (and note that the spec. says "zero or more..."). But this would not be the case for many other host environments and certainly not for most CLI hosts.
We are at this point talking about a fiction. Neither Node.js nor web browsers behave this way. Certainly nothing that anyone has written a spec for behaves this way. As such these hooks don't provide any value over just having these host environments do the script/module parsing and execution at the appropriate point in time.
It's basically a single responsibility principle thing. There's no reason to couple initializing a host-defined realm with finding, parsing, and executing scripts or modules. It seems to just be a "I thought maybe some places would do these at the same time, so I put them together in one algorithm," which in practice hasn't borne out.
Jobs and the job queues define the semantics for ES' "empty stack", run to completion execution model. This is essential.
Yes, 100% agreed. (Although awkwardly there is still one execution context on the stack, the one associated with the realm created in InitializeHostDefinedRealm.) This is an important thing to capture in the requirements for HostDefinedEnqueueJob. Of course it does not apply to script execution, just to promises, since scripts can (and sometimes must) be executed with a non-clean stack.
All jobs start with the invocation of an abstract operation, so there must be a distinct abstract operation for each distinct kind of job. It is the abstract operation that defines the specific semantics for each kind of job. The ability to define additional job kinds via additional abstract operations is one of the extension points. Separating the job specific semantics from the enqueuing semantics is a natural separation of concerns.
I completely agree. The job abstract operations should remain. It's the enqueuing process that needs to be made more flexible, leaving only the base ordering requirements instead of specifying an entire inflexible processing model.
ScriptEvaluationJob and TopLevelModuleEvaluationJob are the abstract operation used for those two specific kinds of jobs. It is important that there is a base, host independent semantics for initiating the evaluation of a Script or Module.
I agree. That is why I propose renaming these to ScriptEvaluation and ModuleEvaluation and not coupling them to the job queue.
ScriptEvaluationJob and TopLevelModuleEvaluationJob are only mentioned in ECMAScript Initialization() because the basic ES spec only explicitly covers the case of statically predetermined ECMAScript source texts.
Sure, but I don't think it should. That's an unnecessary embellishment that is not used by any real-world implementations or specs, and goes some basic separation of concerns design principles. As mentioned above.
A host that supports dynamic source loading would would reference them in its host-specific dynamic loading semantics. (this would most likely occur in a host-specific job scheduler invoked as part of step 4 of NextJob.
As mentioned, going through the job queue is not interesting or reasonable for host environments that want to execute scripts; in many cases it is impossible, and in other cases it requires awkward spoon-feeding that can be just collapsed down to performing the relevant abstract operation directly instead of adding the job to the currently-empty queue and then immediately pumping the queue to execute the job.
A HTML event handler is not a Script. Hosts that defined addition kinds of run-to-completion entities need to define their semantics via new kinds of job abstract operations. Annex B may be the place for doing this for HTML features that require new syntax driven semantics. See Bug 3139
Yeah, it would be great to get this straightened out. For now I am just having HTML continue to manually create Function objects, but resolving bug 3139 would be great. Yet again though, the job queue is not an appropriate place for this to occur, since e.g. el.onmouseover() must execute the compiled function synchronously, not on the job queue.
|
Nobody is thinking of the ES spec as a dependent of the HTML spec. We're just working out a way to make sure that the ES spec accurately reflects implementations. As of right now the ES spec is failing to do that. It tries to create a job queue abstraction, but does not allow that abstraction to integrate with hosts in a natural way, which is required for real-world implementation. In particular, the only way to usably integrate the job queue is to spoon-feed it one job at a time, using the various implementation-defined extension points to ensure that only one job is ever in the queue, because this gives hosts the freedom to interleave jobs with other host operations in the appropriate order. Many of the jobs enqueued by the ES spec itself aren't even ever executed, because they need to be removed from the queue and then replayed later so that they can interleave properly with other host operations. (See https://esdiscuss.org/topic/the-initialization-steps-for-web-browsers#content-18.) And for script execution, hosts are better served by ignoring ScriptEvaluationJob and TopLevelModuleEvaluationJob, and use ParseScript/ScriptEvaluation and their module counterparts directly. This is in fact 100% necessary for some cases, like A setup like the one I described, with EnqueueJob being replaced by a properly-restricted HostDefinedEnqueueJob, and NextJob being replaced by YieldToHostEnvironment, is much more flexible, and e.g. allows promise jobs to be properly interleaved with other host environment operations without the kind of awkwardness described above. We can achieve the same guarantees of empty stack and ordering by placing restrictions on the definition of HostDefinedEnqueueJob. And as I said, if we want to give an outline for a "simple reference virtual machine" and how it would execute, we can define default implementations of these that look similar to the current definitions. Note that the issues I am discussing here are not unique to HTML. Node.js also has a structure that requires completely disregarding ES's current script/module evaluation and job queue semantics, given its interleaving of promise jobs with other microtasks, and its manner of script execution (both at startup and dynamically). To some more specific points:
We are at this point talking about a fiction. Neither Node.js nor web browsers behave this way. Certainly nothing that anyone has written a spec for behaves this way. As such these hooks don't provide any value over just having these host environments do the script/module parsing and execution at the appropriate point in time. It's basically a single responsibility principle thing. There's no reason to couple initializing a host-defined realm with finding, parsing, and executing scripts or modules. It seems to just be a "I thought maybe some places would do these at the same time, so I put them together in one algorithm," which in practice hasn't borne out.
Yes, 100% agreed. (Although awkwardly there is still one execution context on the stack, the one associated with the realm created in InitializeHostDefinedRealm.) This is an important thing to capture in the requirements for HostDefinedEnqueueJob. Of course it does not apply to script execution, just to promises, since scripts can (and sometimes must) be executed with a non-clean stack.
I completely agree. The job abstract operations should remain. It's the enqueuing process that needs to be made more flexible, leaving only the base ordering requirements instead of specifying an entire inflexible processing model.
I agree. That is why I propose renaming these to ScriptEvaluation and ModuleEvaluation and not coupling them to the job queue.
Sure, but I don't think it should. That's an unnecessary embellishment that is not used by any real-world implementations or specs, and goes some basic separation of concerns design principles. As mentioned above.
As mentioned, going through the job queue is not interesting or reasonable for host environments that want to execute scripts; in many cases it is impossible, and in other cases it requires awkward spoon-feeding that can be just collapsed down to performing the relevant abstract operation directly instead of adding the job to the currently-empty queue and then immediately pumping the queue to execute the job.
Yeah, it would be great to get this straightened out. For now I am just having HTML continue to manually create Function objects, but resolving bug 3139 would be great. Yet again though, the job queue is not an appropriate place for this to occur, since e.g. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Dec 15, 2015
Member
It is indeed important for us to define a layering interface that is clearly applicable to a CLI. I think this proposal is on its way there - EvaluateScript and EvaluateModule seem easily applicable and especially since there is currently no way in standard ECMAScript to enqueue a "ScriptJob", the queue for such jobs seems like an overreach to me. Perhaps we can even explicitly define (likely non-normatively) the behavior for a simple CLI by defining abstract operations (say, ECMAScript CLI Initialization and friends) that uses the layering API to create a simple host that has a queue of scripts and (presumably) some way to actually create new scripts to justify its inclusion?
|
It is indeed important for us to define a layering interface that is clearly applicable to a CLI. I think this proposal is on its way there - EvaluateScript and EvaluateModule seem easily applicable and especially since there is currently no way in standard ECMAScript to enqueue a "ScriptJob", the queue for such jobs seems like an overreach to me. Perhaps we can even explicitly define (likely non-normatively) the behavior for a simple CLI by defining abstract operations (say, ECMAScript CLI Initialization and friends) that uses the layering API to create a simple host that has a queue of scripts and (presumably) some way to actually create new scripts to justify its inclusion? |
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 15, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 16, 2015
Member
Nobody is thinking of the ES spec as a dependent of the HTML spec. We're just working out a way to make sure that the ES spec accurately reflects implementations. As of right now the ES spec is failing to do that. It tries to create a job queue abstraction, but does not allow that abstraction to integrate with hosts in a natural way, which is required for real-world implementation.
I disagree that the job of the ES spec. is to accurately reflection implementations. It's just as much to tell implementations what they must do in order to be inoperable. And that extends across all implementations, not just HTML hosts.
The philosophy I tried to follow was to only include devices in the ES spec. that were necessary to describe actual semantics mandated by the spec. The ES6 job queue device was never intended as a general scheduler that could do all scheduling activites for all purposes. It has three specific semantic purposes. It allow for the ordered execution of Scripts and top level "Modules", as would occur in a command line innovation of a ES execution engine. It allows for the ordered execution of Promise derived asynchronous activities. It allows for the separate scheduling of Script/Module jobs and promise associated jobs. The ES6 job queue device is hopefully extensible for other purposes but not necessarily for all. In particularly, it was determined early on that, by itself, it wasn't an adequate device for all of HTML's task scheduling. The only requirement in that regard was that it could, if necessary, get out of the way.
In particular, the only way to usably integrate the job queue is to spoon-feed it one job at a time, using the various implementation-defined extension points to ensure that only one job is ever in the queue, because this gives hosts the freedom to interleave jobs with other host operations in the appropriate order.
Yes, this is exactly as intended. If a host environment has complex scheduling it can do its own scheduling and plug into the ES execution semantics by conceptually enqueuing one job at a time using EnqueueJob abstract operation. (of course, it wouldn't actually implement separate ES queues and scheduler in that case_
Many of the jobs enqueued by the ES spec itself aren't even ever executed, because they need to be removed from the queue and then replayed later so that they can interleave properly with other host operations. (See https://esdiscuss.org/topic/the-initialization-steps-for-web-browsers#content-18.)
Don't know what that many is about, as other than the initial scripts/top level modules, the only jobs enqueued by the ES6 spec. are Promise related jobs where the promise related ordering is a specified semantics that must be maintained for interoperability.
Also don't see what the esdiscuss thread has to do with that point. I like that thread and it had a lot of influence on fine tuning what ES6 said about jobs.
And for script execution, hosts are better served by ignoring ScriptEvaluationJob and TopLevelModuleEvaluationJob, and use ParseScript/ScriptEvaluation and their module counterparts directly. This is in fact 100% necessary for some cases, like importScript()s or Node.js's require, both of which parse and evaluates a script when the call stack is non-empty.
I disagree on this point. It is very important that there is a standard execution semantics for Script and top-level Module that is common to all ES environments. Providing that semantics is the role of TopLevelModuleEvaluationJob and ScriptEvaluationJob. Interrupting a Script before it runs to completion is not script "run to completion" semantics. Perhaps that can be accommodated but I'd want to here explicitly from MSM and other before we committed to that in the spec. It was certainly never stated as a requirement that ES needed to specify anything other than run-to-completion.
A setup like the one I described, with EnqueueJob being replaced by a properly-restricted HostDefinedEnqueueJob, and NextJob being replaced by YieldToHostEnvironment, is much more flexible, and e.g. allows promise jobs to be properly interleaved with other host environment operations without the kind of awkwardness described above. We can achieve the same guarantees of empty stack and ordering by placing restrictions on the definition of HostDefinedEnqueueJob.
This sounds primarily like a simple naming consideration. I think there is already enough "implementation defined" language in these two abstract operations to let you do pretty much anything you want. If you want to be clearer about that you could include text/algorithm steps that says something like "evaluate these steps or an implementation defined alternative that maintains the same invariant"
And as I said, if we want to give an outline for a "simple reference virtual machine" and how it would execute, we can define default implementations of these that look similar to the current definitions.
Just to be clear, the intent of the spec. is not to describe a virtual machine, instead it is to define the baseline semantics that applies to all implementations. Executing scripts in order and promise tasks in order is part of those required baseline semantics. Extension beyond that should be in hosting specs.
Note that the issues I am discussing here are not unique to HTML. Node.js also has a structure that requires completely disregarding ES's current script/module evaluation and job queue semantics, given its interleaving of promise jobs with other microtasks, and its manner of script execution (both at startup and dynamically).
Yes, but just like for HTML is there anything in the ES6 spec. (except for run-to-completion) that prevents this? As I've stated, the ES job schedule is just a starting point for describing what ES requires. Node.js is free to extend it using its own abstractions and scheduler. (I'm basically make a simplicity argument, put the complexity in the HTML or node.js spec., not in the ES spec. where we don't (yet) have any motivating interoperability requirements stated yet.
(I would sooner see this discussion occurring in the context of how to make events/event handling and ES user level scheduled jobs part of ES. Then we would have a motivating language-level host independent semantics to drive the discussion.
To some more specific points:
It's fine that your HTML binding does not provide any ECMAScript source texts to ECMAScript Initialization(). That is just an indication that there are no statically determined source texts (and note that the spec. says "zero or more..."). But this would not be the case for many other host environments and certainly not for most CLI hosts.
We are at this point talking about a fiction. Neither Node.js nor web browsers behave this way. Certainly nothing that anyone has written a spec for behaves this way. As such these hooks don't provide any value over just having these host environments do the script/module parsing and execution at the appropriate point in time.
Certainly, CLI level JS engines exist as do embedded implementations (that aren't node based). The purpose of the ES spec. is not just to describe what already exists. It purpose is more about what should be implemented by new implementation.
It's basically a single responsibility principle thing. There's no reason to couple initializing a host-defined realm with finding, parsing, and executing scripts or modules. It seems to just be a "I thought maybe some places would do these at the same time, so I put them together in one algorithm," which in practice hasn't borne out.
Sure there is. It is specifying the minimal required behavior. A initial realm must be created before execution of ECMAScript source text begins. But in a way that is sufficiently extensible that host extension (but not total replacement) is essentially possible at each step.
And remember the spec. states requirements for observable behavior but using linear algorithms. The ordering of the steps are important only to the degree that there are inter-step dependencies or observable ordering effects.
Jobs and the job queues define the semantics for ES' "empty stack", run to completion execution model. This is essential.
Yes, 100% agreed. (Although awkwardly there is still one execution context on the stack, the one associated with the realm created in InitializeHostDefinedRealm.)
I think you mean the one created by ECMAScript Initializtion(). It primarily exists so NextJob doesn't have to be special cased for dispatching the first job.
This is an important thing to capture in the requirements for HostDefinedEnqueueJob. Of course it does not apply to script execution, just to promises, since scripts can (and sometimes must) be executed with a non-clean stack.
I already covered that this mode of script execution was never a ES6 requirement nor were a semantics ever discussed within TC39. What you are describing is closer to an eval semantics and that may be a better way to conceptualize it.
All jobs start with the invocation of an abstract operation, so there must be a distinct abstract operation for each distinct kind of job. It is the abstract operation that defines the specific semantics for each kind of job. The ability to define additional job kinds via additional abstract operations is one of the extension points. Separating the job specific semantics from the enqueuing semantics is a natural separation of concerns.
I completely agree. The job abstract operations should remain. It's the enqueuing process that needs to be made more flexible, leaving only the base ordering requirements instead of specifying an entire inflexible processing model.
Glad we agree on something. Of course, my argument is that the ordering requirements are really the only essential thing stated by the ES6 jobs scheduler spec. Most of what you are seeing as an inflexible processing model is may be in your head and not what the spec. was actually trying to say. I think the trick is to find a way to describe it that doesn't imply things that were not intended but also provides a complete specification for baseline implementations.
ScriptEvaluationJob and TopLevelModuleEvaluationJob are the abstract operation used for those two specific kinds of jobs. It is important that there is a base, host independent semantics for initiating the evaluation of a Script or Module.
I agree. That is why I propose renaming these to ScriptEvaluation and ModuleEvaluation and not coupling them to the job queue.
This mostly comes back to the run-to-completion issue. These were intentionally specified to be run-to-completion and making them a job is how that is accomplished.
ScriptEvaluationJob and TopLevelModuleEvaluationJob are only mentioned in ECMAScript Initialization() because the basic ES spec only explicitly covers the case of statically predetermined ECMAScript source texts.
Sure, but I don't think it should. That's an unnecessary embellishment that is not used by any real-world implementations or specs, and goes some basic separation of concerns design principles. As mentioned above.
That was the case prior to ES6 and it was a problem. There was nothing in the spec. that actually provide the requirements for starting the execution of code. That is now there and can also provides the foundation for HTML/node.js style extensions.
But don't assume that the primary audience are browser JS engine implementors. They already know how browsers work. This material is more for people who need to build a basic greenfield ES engine.
A host that supports dynamic source loading would would reference them in its host-specific dynamic loading semantics. (this would most likely occur in a host-specific job scheduler invoked as part of step 4 of NextJob.
As mentioned, going through the job queue is not interesting or reasonable for host environments that want to execute scripts; in many cases it is impossible, and in other cases it requires awkward spoon-feeding that can be just collapsed down to performing the relevant abstract operation directly instead of adding the job to the currently-empty queue and then immediately pumping the queue to execute the job.
Don't read the spec. as a design document for an implementation. It is just a set of requirements. There is no reason such an implementation would maintain distinct host and ES job queues and distinct schedulers. I'm sure it would all be unsobervably merged into a single implementation. But we can't write a spec. that is merged in that way because there is too much host variation.
A HTML event handler is not a Script. Hosts that defined addition kinds of run-to-completion entities need to define their semantics via new kinds of job abstract operations. Annex B may be the place for doing this for HTML features that require new syntax driven semantics. See Bug 3139
Yeah, it would be great to get this straightened out. For now I am just having HTML continue to manually create Function objects, but resolving bug 3139 would be great. Yet again though, the job queue is not an appropriate place for this to occur, since e.g. el.onmouseover() must execute the compiled function synchronously, not on the job queue.
Whatever is required need to be specified. Bug 3139 is probably where I would have started into this whole mess.
I disagree that the job of the ES spec. is to accurately reflection implementations. It's just as much to tell implementations what they must do in order to be inoperable. And that extends across all implementations, not just HTML hosts. The philosophy I tried to follow was to only include devices in the ES spec. that were necessary to describe actual semantics mandated by the spec. The ES6 job queue device was never intended as a general scheduler that could do all scheduling activites for all purposes. It has three specific semantic purposes. It allow for the ordered execution of Scripts and top level "Modules", as would occur in a command line innovation of a ES execution engine. It allows for the ordered execution of Promise derived asynchronous activities. It allows for the separate scheduling of Script/Module jobs and promise associated jobs. The ES6 job queue device is hopefully extensible for other purposes but not necessarily for all. In particularly, it was determined early on that, by itself, it wasn't an adequate device for all of HTML's task scheduling. The only requirement in that regard was that it could, if necessary, get out of the way.
Yes, this is exactly as intended. If a host environment has complex scheduling it can do its own scheduling and plug into the ES execution semantics by conceptually enqueuing one job at a time using EnqueueJob abstract operation. (of course, it wouldn't actually implement separate ES queues and scheduler in that case_
Don't know what that many is about, as other than the initial scripts/top level modules, the only jobs enqueued by the ES6 spec. are Promise related jobs where the promise related ordering is a specified semantics that must be maintained for interoperability. Also don't see what the esdiscuss thread has to do with that point. I like that thread and it had a lot of influence on fine tuning what ES6 said about jobs.
I disagree on this point. It is very important that there is a standard execution semantics for Script and top-level Module that is common to all ES environments. Providing that semantics is the role of TopLevelModuleEvaluationJob and ScriptEvaluationJob. Interrupting a Script before it runs to completion is not script "run to completion" semantics. Perhaps that can be accommodated but I'd want to here explicitly from MSM and other before we committed to that in the spec. It was certainly never stated as a requirement that ES needed to specify anything other than run-to-completion.
This sounds primarily like a simple naming consideration. I think there is already enough "implementation defined" language in these two abstract operations to let you do pretty much anything you want. If you want to be clearer about that you could include text/algorithm steps that says something like "evaluate these steps or an implementation defined alternative that maintains the same invariant"
Just to be clear, the intent of the spec. is not to describe a virtual machine, instead it is to define the baseline semantics that applies to all implementations. Executing scripts in order and promise tasks in order is part of those required baseline semantics. Extension beyond that should be in hosting specs.
Yes, but just like for HTML is there anything in the ES6 spec. (except for run-to-completion) that prevents this? As I've stated, the ES job schedule is just a starting point for describing what ES requires. Node.js is free to extend it using its own abstractions and scheduler. (I'm basically make a simplicity argument, put the complexity in the HTML or node.js spec., not in the ES spec. where we don't (yet) have any motivating interoperability requirements stated yet. (I would sooner see this discussion occurring in the context of how to make events/event handling and ES user level scheduled jobs part of ES. Then we would have a motivating language-level host independent semantics to drive the discussion.
Certainly, CLI level JS engines exist as do embedded implementations (that aren't node based). The purpose of the ES spec. is not just to describe what already exists. It purpose is more about what should be implemented by new implementation.
Sure there is. It is specifying the minimal required behavior. A initial realm must be created before execution of ECMAScript source text begins. But in a way that is sufficiently extensible that host extension (but not total replacement) is essentially possible at each step. And remember the spec. states requirements for observable behavior but using linear algorithms. The ordering of the steps are important only to the degree that there are inter-step dependencies or observable ordering effects.
I think you mean the one created by ECMAScript Initializtion(). It primarily exists so NextJob doesn't have to be special cased for dispatching the first job.
I already covered that this mode of script execution was never a ES6 requirement nor were a semantics ever discussed within TC39. What you are describing is closer to an eval semantics and that may be a better way to conceptualize it.
Glad we agree on something. Of course, my argument is that the ordering requirements are really the only essential thing stated by the ES6 jobs scheduler spec. Most of what you are seeing as an inflexible processing model is may be in your head and not what the spec. was actually trying to say. I think the trick is to find a way to describe it that doesn't imply things that were not intended but also provides a complete specification for baseline implementations.
This mostly comes back to the run-to-completion issue. These were intentionally specified to be run-to-completion and making them a job is how that is accomplished.
That was the case prior to ES6 and it was a problem. There was nothing in the spec. that actually provide the requirements for starting the execution of code. That is now there and can also provides the foundation for HTML/node.js style extensions. But don't assume that the primary audience are browser JS engine implementors. They already know how browsers work. This material is more for people who need to build a basic greenfield ES engine.
Don't read the spec. as a design document for an implementation. It is just a set of requirements. There is no reason such an implementation would maintain distinct host and ES job queues and distinct schedulers. I'm sure it would all be unsobervably merged into a single implementation. But we can't write a spec. that is merged in that way because there is too much host variation.
Whatever is required need to be specified. Bug 3139 is probably where I would have started into this whole mess. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 16, 2015
Member
Regardless of the seemingly-large philosophical differences, I am heartened to see
This sounds primarily like a simple naming consideration. I think there is already enough "implementation defined" language in these two abstract operations to let you do pretty much anything you want. If you want to be clearer about that you could include text/algorithm steps that says something like "evaluate these steps or an implementation defined alternative that maintains the same invariant"
I am glad we agree on this, and it sounds like my upcoming proposed revisions will meet your approval :). This paragraph
Glad we agree on something. Of course, my argument is that the ordering requirements are really the only essential thing stated by the ES6 jobs scheduler spec. Most of what you are seeing as an inflexible processing model is may be in your head and not what the spec. was actually trying to say. I think the trick is to find a way to describe it that doesn't imply things that were not intended but also provides a complete specification for baseline implementations.
is also encouraging.
Given these core points of agreement, instead of continuing the back and forth, I will simply work on a proposal that we can probably agree on.
|
Regardless of the seemingly-large philosophical differences, I am heartened to see
I am glad we agree on this, and it sounds like my upcoming proposed revisions will meet your approval :). This paragraph
is also encouraging. Given these core points of agreement, instead of continuing the back and forth, I will simply work on a proposal that we can probably agree on. |
added a commit
to whatwg/html
that referenced
this issue
Dec 16, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 16, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 17, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 17, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 18, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 18, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 21, 2015
added a commit
to whatwg/html
that referenced
this issue
Dec 21, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bterlson
Feb 18, 2016
Member
Closing this now (not sure if some of the proposals recently merged trace their lineage to this issue, but if not, feel free to re-open).
|
Closing this now (not sure if some of the proposals recently merged trace their lineage to this issue, but if not, feel free to re-open). |
domenic commentedDec 10, 2015
Another tale in the saga of my attempt to use ES's new hooks inside an actual host environment...
ScriptEvaluationJob and TopLevelModuleEvaluationJob are enqueued in exactly one place: InitializeHostDefinedRealm() (in master; Initialization() in gh-pages). However, their presence there does not accomplish anything. Here is my reasoning:
Further evidence comes from how these are being used in my current draft of HTML-with-new-ES-semantics. There, we supply no script or module source text to InitializeHostDefinedRealm(); we need to do other setup operations before we run scripts/modules, and inserting ourselves into the middle of an ES algorithm by specifying "In an implementation defined manner" is not very ergonomic.
We also need to be able to execute script at other times (for example in reaction to event handlers, or upon navigation to
javascript:URLs). So we have a generic script-execution process that ends up looking like this:"ScriptJobs", ScriptEvaluationJob, « sourceText »)This is actually entirely pointless, since the whole EnqueueJob/NextJob dance can just be replaced by directly calling ScriptEvaluationJob. (Or, if you say that calling jobs is not allowed, then it can be replaced by inlining the steps performed by ScriptEvaluationJob into those lines.)
I would thus like to propose the following edits:
(1) Convert ScriptEvaluationJob into an abstract operation written like so:
EvaluateScript(realm, sourceText)
(2) Do the same for TopLevelModuleEvaluationJob producing EvaluateTopLevelModule(realm, sourceText).
(3) Remove the implementation-defined gathering of initial scripts and modules inInitializeHostDefinedRealm(). As shown, this can easily be replaced by the host simply calling EvaluateScript() and EvaluateModule() in whatever order it wants, subsequent to calling InitializeHostDefinedRealm().
(4) Remove the ScriptJobs job queue, since nobody enqueues any jobs in it.
With these changes HTML can simply call ScriptEvaluation(realm, sourceText) and TopLevelModuleEvaluation(realm, sourceText) as appropriate inside HTML's own run-a-script algorithms, which become very simply:
I'd love it if any objections to this plan were voiced ASAP as otherwise I'm going to start working on the pull request :) As usual, this has zero impact on observable semantics, and I've tried to show that even to other specifications it does not change the semantic interface and restrictions, since those were basically nonexistant to begin with due to the uselessness of the jobs as specified.