-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
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:
- The purpose of doing things on a job queue is two fold: one, to ensure ordering inside the job queue; and two, to ensure that the job executes with a clean stack.
- Ordering inside the job queue is arbitrary, since the host environment supplies the script/module source codes to InitializeHostDefinedRealm() itself.
- 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. (The running execution context is always the dummy execution context shared by the entire realm and created in InitializeHostDefinedRealm(), anyway.)
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:
- (do HTML-specific setup stuff)
- EnqueueJob(
"ScriptJobs"
, ScriptEvaluationJob, « sourceText ») - Update "the implementation manner" of choosing a non-empty Job Queue in NextJob to choose "ScriptJobs" next.
- Call NextJob undefined. Wait for the resulting completion (i.e. until the ScriptEvaluationJob calls NextJob with the script's completion value) and return that as the result of running the script. Have implementation-defined error processing, in both ScriptEvaluation and in NextJob, delegate to HTML's report-an-error logic.
- (do HTML-specific teardown stuff)
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)
- Assert: sourceText is an ECMAScript source text (see clause 10).
- Parse sourceText using Script as the goal symbol and analyze the parse result for any Early Error conditions. If the parse was successful and no early errors were found, let code be the resulting parse tree. Otherwise, let code be an indication of one or more parsing errors and/or early errors. Parsing and early error detection may be interweaved in an implementation dependent manner. If more than one parse or early error is present, the number and ordering of reported errors is implementation dependent but at least one error must be reported.
- If code is an error indication, then return Completion{[[type]]: throw, [[value]]: code}.
- Otherwise, return the result of ScriptEvaluation of code with argument realm.
(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:
- (do HTML-specific setup stuff)
- Let result be EvaluateScript(realm, sourceText).
- If result is an abrupt completion, report an exception given result.[[value]]. Otherwise, return result.[[value]].
- (do HTML-specific teardown stuff)
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.