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 upI need a concept of "currently running script" #78
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
anba
Oct 6, 2015
Contributor
I don't like "all execution contexts created from".
I think this part can be done in 8.4.2 NextJob, step 9:
- Perform any implementation or host environment defined job initialization using nextPending.
Define that step 9 calls a new abstract operation HostDefinedJobInitialization. In HostDefinedJobInitialization you can now enhance the execution context to store the HTML script info.
HostDefinedJobInitialization(job):
- If job.[[HostDefined]] contains HTML script, then
- Let callerContext be the running execution context.
- Install additional HTML properties in callerContext.
I think this part can be done in 8.4.2 NextJob, step 9:
Define that step 9 calls a new abstract operation HostDefinedJobInitialization. In HostDefinedJobInitialization you can now enhance the execution context to store the HTML script info. HostDefinedJobInitialization(job):
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@anba that was the motivation for including step 9 in the design |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Oct 6, 2015
Member
That seems like the piece I was missing; thank you @anba! My eyes must have just slipped over that line a number of times.
At some point I might submit a PR to refactor out all these "implementation-defined XXX" into abstract ops like your sample of HostDefinedJobInitialization. But I'll wait until I do the whole integration shebang...
Closing since my original question is answered.
|
That seems like the piece I was missing; thank you @anba! My eyes must have just slipped over that line a number of times. At some point I might submit a PR to refactor out all these "implementation-defined XXX" into abstract ops like your sample of HostDefinedJobInitialization. But I'll wait until I do the whole integration shebang... Closing since my original question is answered. |
domenic
closed this
Oct 6, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 9, 2015
Member
@anba OK, I tried this and it didn't work, because it didn't capture what I meant by "all execution contexts created from." In particular it only allows me to correlate the top-level execution contexts created by NextJob. But I am most concerned about the ones created by e.g. declaring functions or calling eval.
Let me try to give an overview of the problem. Given
a.html
<script id="a1">
frames[0].foo();
</script>
<script id="a2">
blah();
</script>
<iframe src="b.html"></iframe>b.html
<script id="b1">
function foo() {
// HERE
}
</script>
<script id="b2">
blahblah();
</script>I need some spec language I can insert such that at the "HERE" point, "the currently running script" gives b1.
The execution context stack has foo()'s context on top, then below it a1's top-level context. Your trick allows me to associate a1's top-level context with the a1 script, but I don't see how to associate foo's context with b1.
Any ideas?
|
@anba OK, I tried this and it didn't work, because it didn't capture what I meant by "all execution contexts created from." In particular it only allows me to correlate the top-level execution contexts created by NextJob. But I am most concerned about the ones created by e.g. declaring functions or calling eval. Let me try to give an overview of the problem. Given a.html <script id="a1">
frames[0].foo();
</script>
<script id="a2">
blah();
</script>
<iframe src="b.html"></iframe>b.html <script id="b1">
function foo() {
// HERE
}
</script>
<script id="b2">
blahblah();
</script>I need some spec language I can insert such that at the "HERE" point, "the currently running script" gives The execution context stack has foo()'s context on top, then below it a1's top-level context. Your trick allows me to associate a1's top-level context with the a1 script, but I don't see how to associate foo's context with b1. Any ideas? |
domenic
reopened this
Dec 9, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zenparsing
Dec 9, 2015
Contributor
Execution contexts have a Function component. Can you somehow associate all functions with their containing "scripts"? Would you need some kind of hook into FunctionAllocate to do that?
|
Execution contexts have a Function component. Can you somehow associate all functions with their containing "scripts"? Would you need some kind of hook into FunctionAllocate to do that? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 9, 2015
Member
Yeah I would need a hook in all the places that push execution contexts onto the stack, of which there are approximately ten.
|
Yeah I would need a hook in all the places that push execution contexts onto the stack, of which there are approximately ten. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zenparsing
Dec 9, 2015
Contributor
I was thinking one hook in NextJob and one in FunctionAllocate. Getting the script from an execution context would look like:
- If the current execution context has a non-empty Function component:
- Get the current script from the Function-to-current-script mapping.
- Else, we're evaluating a script or module:
- Get the current script from the execution-context-to-script mapping.
You'd set the Function-to-script mapping from within FunctionAllocate, and you'd set the execution-context-to-script mapping from HostDefinedJobInitialization as described above.
I'm not really familiar with how modules and execution contexts interact though. And I could be misunderstanding things as well.
|
I was thinking one hook in NextJob and one in FunctionAllocate. Getting the script from an execution context would look like:
You'd set the Function-to-script mapping from within FunctionAllocate, and you'd set the execution-context-to-script mapping from HostDefinedJobInitialization as described above. I'm not really familiar with how modules and execution contexts interact though. And I could be misunderstanding things as well. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 9, 2015
Member
Hmm, I think that might suffice. The eval and generator context manipulation can all be subsumed by the function manipulation, i.e. they can "inherit" their parent function or top-level script. I thought about that for a bit and it seems web-compatible.
and you'd set the execution-context-to-script mapping from HostDefinedJobInitialization as described above.
This isn't quite accurate, it turns out. InitializeHostDefinedRealm only has a single execution context for the entire realm. Within those each ScriptEvaluationJob/ScriptEvaluation and ModuleEvaluationJob/ModuleEvaluation create per-script/module execution contexts. So the right hook is not in NextJob step 9 but in ScriptEvaluation and ModuleEvaluation.
I can probably smuggle this in, although it will be linguistically awkward, since calling EnqueueJob("ScriptJobs", ScriptEvaluationJob, <>) doesn't actually let me customize the [[HostDefined]] part of the PendingJob. Maybe I can add a hostDefined parameter to EnqueueJob.
Hmm, now I am tempted to just not use ScriptEvaluationJob or ModuleEvaluationJob at all, and directly use ScriptEvaluation and ModuleEvaluation... that actually seems a lot easier.
Next problem. When I'm at these hook locations, how do I know what script to associate with?
Consider a modification of the above example that has
<script id="b1">
function foo() {
function bar() {
// HERE
}
bar();
}
</script>It seems like I need to create the Function-to-script mapping via:
- If the running execution context has no Function component, this is a top-level function, so use the script from the top-level-execution-context-to-script mapping.
- Otherwise, use the script from the Function-to-script mapping keyed on the running execution context's Function component.
OK, willing to give this a try.
Does anyone have opinions on whether we should do this in ES, or in HTML? That is, I see two possibilities:
- Add hooks to ES ModuleEvaluation, ScriptEvaluation, and FunctionAllocate, which HTML uses to associate HTML scripts with the created execution contexts. HTML maintains the Function-to-script mapping and the top-level-execution-context-to-script mapping.
- ES takes over, and creates or reuses some notion of script or module, so that instead of hooks, it just does the bookkeeping itself, and we add a ScriptOrModule component to all execution contexts. This could be a ModuleRecord for modules. Unsure about scripts; the spec likes to talk about ECMAScript Script but that's kind of strange since it's a grammar production, not an actual thing.
|
Hmm, I think that might suffice. The eval and generator context manipulation can all be subsumed by the function manipulation, i.e. they can "inherit" their parent function or top-level script. I thought about that for a bit and it seems web-compatible.
This isn't quite accurate, it turns out. InitializeHostDefinedRealm only has a single execution context for the entire realm. Within those each ScriptEvaluationJob/ScriptEvaluation and ModuleEvaluationJob/ModuleEvaluation create per-script/module execution contexts. So the right hook is not in NextJob step 9 but in ScriptEvaluation and ModuleEvaluation. I can probably smuggle this in, although it will be linguistically awkward, since calling EnqueueJob("ScriptJobs", ScriptEvaluationJob, <>) doesn't actually let me customize the [[HostDefined]] part of the PendingJob. Maybe I can add a hostDefined parameter to EnqueueJob. Hmm, now I am tempted to just not use ScriptEvaluationJob or ModuleEvaluationJob at all, and directly use ScriptEvaluation and ModuleEvaluation... that actually seems a lot easier. Next problem. When I'm at these hook locations, how do I know what script to associate with? Consider a modification of the above example that has <script id="b1">
function foo() {
function bar() {
// HERE
}
bar();
}
</script>It seems like I need to create the Function-to-script mapping via:
OK, willing to give this a try. Does anyone have opinions on whether we should do this in ES, or in HTML? That is, I see two possibilities:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
zenparsing
Dec 10, 2015
Contributor
@domenic After thinking about it, it seems yucky and scattershot to add this kind of hook to FunctionAllocate. I think we should explore the ScriptOrModule thing a bit more. I need to look into the module stuff before I have any useful input though.
|
@domenic After thinking about it, it seems yucky and scattershot to add this kind of hook to FunctionAllocate. I think we should explore the ScriptOrModule thing a bit more. I need to look into the module stuff before I have any useful input though. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 10, 2015
Member
I tend to agree. I might work on a PR for that, using the ModuleRecord (extended with a [[HostDefined]] field) for modules and a new ScriptRecord which contains { [[Realm]], [[Environment]], [[HostDefined]] }. It seems much nicer to have ES track the concept of modules/scripts here.
I don't think there's much to look in to on the modules side FWIW; it works pretty similarly.
|
I tend to agree. I might work on a PR for that, using the ModuleRecord (extended with a [[HostDefined]] field) for modules and a new ScriptRecord which contains { [[Realm]], [[Environment]], [[HostDefined]] }. It seems much nicer to have ES track the concept of modules/scripts here. I don't think there's much to look in to on the modules side FWIW; it works pretty similarly. |
added a commit
to domenic/ecma262
that referenced
this issue
Dec 10, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 10, 2015
domenic
referenced this issue
Dec 10, 2015
Closed
Layering: track execution contexts' script/module #242
added a commit
to domenic/ecma262
that referenced
this issue
Dec 11, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 14, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 14, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 14, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 14, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 14, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 15, 2015
added a commit
to domenic/ecma262
that referenced
this issue
Dec 15, 2015
domenic
closed this
in
698819c
Dec 15, 2015
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
allenwb
Dec 15, 2015
Member
What you are trying specify here seems very host specific and hence the complexity associated with it should be part of the HTML spec rather than the ES spec. But I think the main hook you need is already there.
Every execution context has a "code evaluation state" component. The intent of that component is that it corresponds to whatever implementation state is needed to actually execute/suspend/resume ES code. In practice it subsumes concepts such as native code cache references, program counters, literal frames, etc. It would also presumably abstract a source map or any other implementation specific state that describes characteristics of the executing code. I don't see why the "HTMLScript" association can't also be treated as part of the host/implementation code evaluation state".
If you look at it that way, then the "implementation dependent unhanded exception handling" just needs to be specified to use the "code evaluation state" of the context that originated the exception to determine the "HTMLScript" and any associated semantics.
There does seem to be a missing hook point that is a more general problem. Currently the point where the exception originated is not captured in a CompletionRecord. So, there is actually no way to get from the job level (implementation-dependent) unhandled exception handler back to the execution context that originated the exception. An likely fix for this is probably to capture a reference to the originating execution context within a throw Completion Record. The [[target]] field could probably be used for that purpose.
|
What you are trying specify here seems very host specific and hence the complexity associated with it should be part of the HTML spec rather than the ES spec. But I think the main hook you need is already there. Every execution context has a "code evaluation state" component. The intent of that component is that it corresponds to whatever implementation state is needed to actually execute/suspend/resume ES code. In practice it subsumes concepts such as native code cache references, program counters, literal frames, etc. It would also presumably abstract a source map or any other implementation specific state that describes characteristics of the executing code. I don't see why the "HTMLScript" association can't also be treated as part of the host/implementation code evaluation state". If you look at it that way, then the "implementation dependent unhanded exception handling" just needs to be specified to use the "code evaluation state" of the context that originated the exception to determine the "HTMLScript" and any associated semantics. There does seem to be a missing hook point that is a more general problem. Currently the point where the exception originated is not captured in a CompletionRecord. So, there is actually no way to get from the job level (implementation-dependent) unhandled exception handler back to the execution context that originated the exception. An likely fix for this is probably to capture a reference to the originating execution context within a |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
domenic
Dec 16, 2015
Member
In the end what we have here is used by both Node and browsers, so it's not host specific. But more importantly, it's true that this could be done by using the appropriate slots in execution contexts. The problem is we would need to add hooks in various places in the spec to allow the host to modify those slots (as seen from the many places the diff sets ScriptOrModule). As we concluded upthread it seems better and more natural to have ES track script/module associations, especially since ES already has a module record type, and introducing a script record type (as that commit does) brings script and module execution closer together, and once you have both of those it's a natural step.
|
In the end what we have here is used by both Node and browsers, so it's not host specific. But more importantly, it's true that this could be done by using the appropriate slots in execution contexts. The problem is we would need to add hooks in various places in the spec to allow the host to modify those slots (as seen from the many places the diff sets ScriptOrModule). As we concluded upthread it seems better and more natural to have ES track script/module associations, especially since ES already has a module record type, and introducing a script record type (as that commit does) brings script and module execution closer together, and once you have both of those it's a natural step. |
domenic commentedOct 6, 2015
This is for HTML/ES integration. HTML has a concept of script which contains a few useful pieces of information. Notably, it contains a "muted errors flag", which is set based on whether the script was retrieved in a cross-origin manner.
When performing NextJob's "implementation defined unhandled exception processing", I need to be able to retrieve the current "HTML script" given the information available to me in the ES context.
I would have thought this would be simple: I'd simply get whatever concept ES has for "script", and add a pointer between them associating "HTML script" and "ES script". Or, I could even try to get rid of "HTML script" entirely, and just store a couple things on the ES script.
But, I can't find any concept of script in ES! :(
The closest thing I can find is the top-level execution context scriptCtx created by ScriptEvaluation.
So far the best I've come up with is:
Does this seem vaguely legit? I don't like "all execution contexts created from".