This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 18242 - Not clear what "script that invoked the method" means exactly in the case of e.g. a.setTimeout(b.postMessage, 0) // called from c
Summary: Not clear what "script that invoked the method" means exactly in the case of ...
Status: RESOLVED FIXED
Alias: None
Product: WebAppsWG
Classification: Unclassified
Component: WebIDL (show other bugs)
Version: unspecified
Hardware: Other other
: P2 critical
Target Milestone: ---
Assignee: Domenic Denicola
QA Contact: public-webapps-bugzilla
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
: 17481 (view as bug list)
Depends on:
Blocks: 19662 23780
  Show dependency treegraph
 
Reported: 2012-07-18 17:48 UTC by contributor
Modified: 2016-06-02 20:46 UTC (History)
18 users (show)

See Also:


Attachments

Description contributor 2012-07-18 17:48:30 UTC
This was was cloned from bug 17481 as part of operation convergence.
Originally filed: 2012-06-13 12:59:00 +0000

================================================================================
 #0   contributor@whatwg.org                          2012-06-13 12:59:15 +0000 
--------------------------------------------------------------------------------
Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/web-messaging.html
Multipage: http://www.whatwg.org/C#posting-messages
Complete: http://www.whatwg.org/c#posting-messages

Comment:
Not clear what "script that invoked the method" means exactly. Should this be
changed to "entry script" instead? If not, please specify what it means.

Posted from: 2001:4c28:a030:30:fdc9:a7c:a388:2bea by simonp@opera.com
User agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.7.3; U; en) Presto/2.10.229 Version/11.64
================================================================================
 #1   Simon Pieters                                   2012-06-20 06:58:55 +0000 
--------------------------------------------------------------------------------
So we have a site compat issue here. Yahoo Mail requires the following to alert true

 a.html: 
 <iframe src=b.html></iframe> 
 <script> 
 function A() { window[0].B(); } 
 onload = A; 
 onmessage = function(e) { alert(e.source === window[0]); }; 
 </script> 

 b.html: 
 <script> 
 function B() { parent.postMessage('foo', '*'); } 
 </script>

That is, .source should be the window of the function that calls postMessage (even if that function was called from another window). The same logic should apply to .origin.
================================================================================
Comment 1 Adam Barth 2012-08-21 20:06:08 UTC
> Should this be changed to "entry script" instead?

Entry script is incorrect.  I'm not sure what terms the spec uses, but it's the script that actually called the function.  Consider the following runtime stack:

Entry script, which calls...
function f defined in document A, which calls...
function g defined in document B, which calls...
function h defined in document C, which calls...
postMessage

The correct window object to use is the defaultView of document C.
Comment 2 Ian 'Hixie' Hickson 2012-10-19 22:30:23 UTC
That's what the spec is trying to say.

zcorpan: What text would you use to mean that?
Comment 3 Simon Pieters 2012-10-25 13:32:18 UTC
I think s/script/code entry-point/ makes it clearer, if that's defined somewhere in http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#processing-model-2

In particular "script" and function/code entry-point are different concepts in the spec.
Comment 4 Ian 'Hixie' Hickson 2013-01-30 23:12:05 UTC
Well the entry-point is just that, a point of entry, it's not the actual code. It's the actual code that calls the method.

I could change "script that invoked the method" to "script of the most recently accessed code entry-point", which should in theory be equivalent; would that help?

If we did this I'd probably just define a term, maybe "incumbent script", to mean "the script of the most recently accessed code entry-point", with some examples, and then replace all the mentions of "script that invoked..." with "incumbent script" cross-references. Would that work?
Comment 5 Boris Zbarsky 2013-01-31 02:30:42 UTC
We need a really really clear definition of things here.  In particular, there can easily be cases in which the function is not invoked by "script" per se but by some random ES5 spec algorithm, which may itself have been called by script.  Or not.  Whatever "called by script" means in cases like that.

If a function running in window A applies a generic Array method, say, from window B to window C and that method ends up, in its guts, invoking postMessage because it was defined as the getter or setter func for some indexed property on the window (can that be done nowadays?), are we looking for window A, B, or C here?  Does it matter?  Do UAs even agree on the behavior?

In either case, we really need a very clear definition of things, not handwaving.  Yes, I know I already said that.  It's really important. ;)
Comment 6 Ian 'Hixie' Hickson 2013-02-13 00:46:00 UTC
*** Bug 17481 has been marked as a duplicate of this bug. ***
Comment 7 Ian 'Hixie' Hickson 2013-02-13 00:46:15 UTC
(bug 17481 comment #3 - Hixie)
> That's what the "script that invoked the method" is. Why is this ambiguous?
> The concept of a "script" is defined in quite excruciating detail...

(bug 17481 comment #4 - Hixie)
> zcorpan: Can you elaborate on what you'd like the spec to say? Would
> hyperlinking "script" to concept-script be enough?

(bug 17481 comment #5 - zcorpan)
> Yeah, I think so.
Comment 8 Ian 'Hixie' Hickson 2013-04-09 21:22:23 UTC
(In reply to comment #5)
> We need a really really clear definition of things here.  In particular,
> there can easily be cases in which the function is not invoked by "script"
> per se but by some random ES5 spec algorithm, which may itself have been
> called by script.

Well that's an interesting point. All these functions are really being called by an ES spec algorithm, right? Whatever algorithm it is that implements calling a host environment function on a host object, or whatever the right terminology is.

Specifically, I guess we're talking about all the various algorithms that say "the result calling the [[Call]] internal method..." or "the result of calling the [[Call]] internal method..." or "Call the [[Call]] internal method..." in ES5.

There's a lot of these (around 30 in ES5). But they all have a common ancestor on their call stack, namely, the algorithm introduced as "The production SourceElements : SourceElements SourceElement is evaluated as follows".

So what we really need is a way to refer to the script that a SourceElements production belongs to...
Comment 9 Boris Zbarsky 2013-04-10 00:26:04 UTC
> All these functions are really being called by an ES spec algorithm, right?

Possibly somewhat indirectly, yes.

So to take a specific silly example, if I have an array that was created in window A, then script in window B defines a getter on one of the array indices, and then script in window C calls sort() on the array, then do we want "script that invoked the method" to be talking about window A, window B, or window C?

And note that it's not like window C meant to call this function; it just called sort() on an array.
Comment 10 Boris Zbarsky 2013-04-10 00:41:35 UTC
Oh, and the situation in comment 9 is especially interesting in cases when A, B, and C might have different origins (yes, I know, I know, but it's a case that arises anyway for me, so I have to think about it).
Comment 11 Ian 'Hixie' Hickson 2013-04-10 22:54:52 UTC
The prose in http://dev.w3.org/2006/webapi/WebIDL/#es-throwing-exceptions might be helpful here (I haven't determined one way or the other, I just ran across this while doing something else and wanted to note it for future reference.)
Comment 12 Ian 'Hixie' Hickson 2013-06-11 21:42:54 UTC
Ok, I've tried to fix this. See patch in upcoming comment.

(In reply to comment #9)
> So to take a specific silly example, if I have an array that was created in
> window A, then script in window B defines a getter on one of the array
> indices, and then script in window C calls sort() on the array, then do we
> want "script that invoked the method" to be talking about window A, window
> B, or window C?

Assuming that the getter is the one calling, say, postMessage(), then I think the answer is B.

(In reply to comment #10)
> Oh, and the situation in comment 9 is especially interesting in cases when
> A, B, and C might have different origins (yes, I know, I know, but it's a
> case that arises anyway for me, so I have to think about it).

It can arise on the Web platform too, with document.domain (at least, as it is implemented in WebKit/Blink-derived browsers and in IE).
Comment 13 contributor 2013-06-11 21:45:34 UTC
Checked in as WHATWG revision r7954.
Check-in comment: Try to clean up text where I referred to scripts that called a method, etc. Introduces the term 'incumbent script'.
http://html5.org/tools/web-apps-tracker?from=7953&to=7954
Comment 14 Boris Zbarsky 2013-06-11 21:55:30 UTC
> Assuming that the getter is the one calling, say, postMessage()

No, the case I'm thinking about is when the getter _is_ postMessage.  Or more likely postMessage.bind(stuff).  Your changed text seems to say that in this case the answer is C (maybe; in this case there is no SourceElements production invoking postMessage at all; it's called directly from engine code implementing bound methods), whereas I believe the correct answer should in fact be B.  Or rather should be the origin of the postMessage method in question.

> It can arise on the Web platform too, with document.domain (at least, as it is
> implemented in WebKit/Blink-derived browsers and in IE).

Ah, I guess for purposes of the origin stuff in postMessage it can, indeed.
Comment 15 Boris Zbarsky 2013-06-11 21:56:52 UTC
> No, the case I'm thinking about is when the getter _is_ postMessage.

And I _did_ say that in comment 5, for what it's worth...  Maybe I should have repeated in comment 9 to make it clearer.
Comment 16 Bobby Holley (:bholley) 2013-06-11 21:59:20 UTC
> The incumbent script is the script corresponding to the most-recently 
> evaluated SourceElements JavaScript production

What does this mean?
Comment 17 Boris Zbarsky 2013-06-11 22:06:16 UTC
> What does this mean?

It's a production in the ES grammar.  So for example:

  FunctionBody :
    SourceElements_opt

  Program :
    SourceElements_opt

so basically it's the syntactic thing that is a function body or toplevel script.

In Gecko parlance it would basically be the subject principal for a scripted stackframe.  But the case that we need to define is what happens when the method in question is _not_ invoked from a scripted stackframe.

Another simple exampl of that comes to mind, actually: setTimeout(postMessage.bind(stuff), 0).  When postMessage is called in that situation there is no SourceElements anything anywhere in sight.
Comment 18 Ian 'Hixie' Hickson 2013-06-11 22:11:44 UTC
Hm, yeah, I didn't think that through all the way.
Comment 19 Ian 'Hixie' Hickson 2013-06-18 19:43:06 UTC
What script should be in the incumbent scripts in those cases? Any opinions?
Comment 20 Boris Zbarsky 2013-06-18 19:59:21 UTC
I _think_ the case I described in comment 9 ends up using Window C in Gecko, for lack of anything better...  Bobby, is that correct?

That is, for the specific case of postMessage, which is special-cased up the wazoo for this stuff.
Comment 21 Boris Zbarsky 2013-06-18 20:23:00 UTC
Ah, but in the setTimeout case... I don't know.  I'll test.
Comment 22 Bobby Holley (:bholley) 2013-06-19 01:42:13 UTC
(In reply to comment #20)
> I _think_ the case I described in comment 9 ends up using Window C in Gecko,
> for lack of anything better...  Bobby, is that correct?

I think so, but worth testing. To implement any kind of incumbent script stuff in Gecko, we're going to end up having to relying on JS_DescribeScriptCaller, which filters out "selfHosted" stack frames. The extent to which that is a well-defined and robust concept is unclear to me. I'm going to ask luke whether he thinks it's robust enough to use for things like this.
Comment 23 Boris Zbarsky 2013-06-19 02:42:38 UTC
Finding a place to put up decent testcases for this is hard, so I have not actually verified this via a test but I _think_ based on stepping throught the code that what gecko will do in the case at http://jsfiddle.net/k9euP/2/ is that it will use the origin of the window that made the setTimeout call (as opposed to the window that setTimeout was called on or the window that the function came from).  But don't quote me on that... If you know a place where I can usefully create testcases using document.domain that would help here.  ;)
Comment 24 Bobby Holley (:bholley) 2013-06-28 01:59:50 UTC
So, I've discussed this a bit with bz and luke, and we've come up with a potentially-workable proposal for the async problem:

Any WebIDL function that accepts a callback or callback interfaces captures the current incumbent script and stashes it on the callback. When the callback is invoked, that incumbent script is pushed onto a stack so that it appears to be the current incumbent script.

This is nice because it produces consistent behavior between async and non-async versions of functions. If we have some WebIDL function Foopy.process(args, cb) and Foopy.processAsync(args, cb), the incumbent script for |cb| does not depend on whether we use the async variant or not.

Thoughts, Hixie?
Comment 25 Ian 'Hixie' Hickson 2013-07-02 23:54:07 UTC
I like it. No idea how to spec it, exactly, but that's a separate problem...

heycam, any thoughts on this? I think it most naturally will involve some sort of change on your end, but I'm not sure what exactly. Happy to collaborate on this; ping me on IRC (or we can meet for lunch and figure it out, if you want).
Comment 26 Ian 'Hixie' Hickson 2013-07-03 23:03:48 UTC
heycam suggested we should define this in WebIDL.

heycam, feel free to take the bug if you need something to track the issue on your end. If you take it, reassign it back to me when you're done so I can clean up the HTML spec accordingly.
Comment 27 Cameron McCormack 2013-07-31 07:24:51 UTC
OK.  I've made these changes:

* defined that at the IDL level, callback interface and callback function types are actually represented by a tuple of the object reference and a "callback context"

* made the ES->IDL conversion algorithms grab the incumbent script and store it as the "callback context" of the IDL value

* made the algorithms that invoke an operation or get/set an attribute on a user object, or invoke a callback function, push and pop the callback context in to the "stack of incumbent scripts".

http://dev.w3.org/cvsweb/2006/webapi/WebIDL/Overview.xml.diff?r1=1.649;r2=1.650;f=h
http://dev.w3.org/cvsweb/2006/webapi/WebIDL/v1.xml.diff?r1=1.89;r2=1.90;f=h
Comment 28 Cameron McCormack 2013-07-31 07:25:35 UTC
I've got "stack of incumbent scripts" pointing to HTML (though not with a specific anchor yet), in the hope you'll define it there.  Feel free to come up with a better name. :-)  Then I think you can define "incumbent script" as "the top element of the stack of incumbent scripts, or if the stack is empty, whatever the current definition you have is".
Comment 29 Ian 'Hixie' Hickson 2013-08-01 19:46:40 UTC
Ok, here we go: http://html5.org/tools/web-apps-tracker?from=8113&to=8114

Please reopen if it's not what you wanted! I think this cleans up everything we had open on this, right?
Comment 30 Cameron McCormack 2013-08-01 23:53:27 UTC
(In reply to comment #29)
> Ok, here we go: http://html5.org/tools/web-apps-tracker?from=8113&to=8114
> 
> Please reopen if it's not what you wanted! I think this cleans up everything
> we had open on this, right?

Thanks.  Reopening just to get your attention for this question: since you have this concept of "unit of related similar-origin browsing contexts", how do I determine that so that I can find the right stack to push and pop from?  I assume that "incumbent script" is something that is also related to the "unit of related similar-origin browsing contexts" now?
Comment 31 Ian 'Hixie' Hickson 2013-08-02 20:21:24 UTC
Hm, yeah, good question. The spec kinda glosses over that and assumes that you'll figure it out from context, but we should be more explicit.
Comment 32 Ian 'Hixie' Hickson 2013-08-02 20:49:23 UTC
Actually, it would be attached to something else, not sure if we have a name for it — the world, for lack of a better term — and not a unit of related similar-origin browsing contexts. For example, in a single-threaded browser (ignoring Workers), there's only one world, not one per unit of related similar-origin browsing contexts.
Comment 33 Ian 'Hixie' Hickson 2013-11-09 00:27:37 UTC
So I've been testing this:
   http://www.hixie.ch/tests/adhoc/html/script/callbacks/001.html

I've also adjusted the spec so now we're talking about a stack of script settings objects. So we don't need to have or manufacture a fake script to handle weird cases. We just need this script settings object. Each global has one.

So first, I guess I'll provide a hook to get from a global to the script settings object.

Then I need to update "prepare to run a script-based callback" and company to handle being called from WebIDL in this new world.

Then I'll describe what I think you need to write on your end, heycam.
Comment 34 Ian 'Hixie' Hickson 2013-11-11 18:15:54 UTC
So there's these hooks for you:

 - *relevant settings object for a global object*.
 - *relevant settings object for a script*.
 - *prepare to run a callback* for a settings object.
 - *clean up after running a callback*.

You call the first two to get a settings object from a script or global object. In the global object case, you want the global of the object you're going to call the method on. (I hope this is well defined for .bind() bound methods.) When you are ready to do the callback, you call the "prepare" hook with the settings object you stashed away, then you invoke the callback, then you call the "clean up" hook.
Comment 35 Domenic Denicola 2016-06-02 20:46:01 UTC
This text no longer appears in HTML, so closing. There is still ongoing work around figuring out the right globals in various places but that's tracked elsewhere.