Skip to content

Instantly share code, notes, and snippets.

@benjamn
Created March 24, 2010 21:20
Show Gist options
  • Save benjamn/342838 to your computer and use it in GitHub Desktop.
Save benjamn/342838 to your computer and use it in GitHub Desktop.
[11:48] <smaug_> ping
[11:48] <benjamn> pong
[11:49] <smaug_> about CPOW
[11:49] <benjamn> what's up
[11:49] <smaug_> now that it has landed I'd like to add support for them to TabChildMessages
[11:49] <smaug_> I'm trying to understand who manages what and where
[11:50] <benjamn> where is TabChildMessage defined?
[11:50] <smaug_> that is the global object in the content process
[11:50] <smaug_> used by content process event listeners
[11:51] <smaug_> er
[11:51] <smaug_> TabChildGlobal
[11:51] <smaug_> that is just the name for the global object I've been using
[11:51] <benjamn> ah, ok
[11:51] <benjamn> right
[11:51] <smaug_> it can send synchronous and asynchronous messages to chrome process
[11:52] <smaug_> So, I get JSObjects, or perhaps jsvals as parameters
[11:52] <smaug_> and I'd like to send them to chrome
[11:52] <smaug_> I see there is ObjectWrapperChild(JSContext* cx, JSObject* obj)
[11:52] <smaug_> which looks pretty much the ctor I need
[11:53] <benjamn> yep, I think so
[11:53] <benjamn> let me remember the specific syntax
[11:54] <smaug_> Note, the JSContext I'm using isn't the JSContext of the topmost page in the content process
[11:55] <benjamn> ah, ok
[11:55] <smaug_> so do I need to create ContextWrapperChild somehow first?
[11:55] <benjamn> you might then have to create a new PContextWrapper
[11:55] <benjamn> that's what I do
[11:55] <smaug_> who keeps what alive?
[11:56] <smaug_> how long does the Pcontextwrapper stay alive?
[11:56] <benjamn> until it gets torn down when the tabchild dies
[11:56] <benjamn> it's managed by the IPDL hierarchy
[11:56] <benjamn> which might be too long
[11:56] <smaug_> ok
[11:57] <benjamn> but hopefully isn't too short :)
[11:57] <benjamn> so, you need something a little different from http://mxr.mozilla.org/projects-central/source/electrolysis/dom/ipc/TabChild.cpp#384
[11:57] <benjamn> you need to remember the result of SendPContextWrapperConstructor(), so that you can reuse it
[11:57] <smaug_> hmm, so how do I get access to PContextWrapperChild?
[11:57] <smaug_> right, so I just take the pointer there
[11:57] <smaug_> and then reuse it
[11:58] <benjamn> yep
[11:58] <benjamn> so, the zero-argument version will just use TabChild::AllocPContextWrapper
[11:58] <benjamn> which gets the jscontext from mWebNav
[11:59] <smaug_> but can I pass my own JSContext as a parameter?
[11:59] <benjamn> so if you have a different JSContext*, you'll want to do SendPContextWrapperConstructor(new ContextWrapperChild(yourJSContext))
[11:59] <smaug_> ok
[11:59] <benjamn> there's another version of the constructor message that lets you pass the allocated object directly
[12:00] <smaug_> Is there a version of SendPObjectWrapperConstructor which takes ObjectWrapperChild as parameter?
[12:01] <smaug_> (it is occasionally a bit difficult to see what all is possible, because IPDL auto-generates all kinds of stuff)
[12:01] <benjamn> (I agree!)
[12:01] <smaug_> what is the true in SendPObjectWrapperConstructor(true);?
[12:02] <benjamn> that says "use the global object from the context"
[12:02] <benjamn> in short, yes, there is another version of that constructor
[12:02] <smaug_> PObjectWrapperChild* AllocPObjectWrapper(JSObject* obj) {
[12:02] <smaug_> return new ObjectWrapperChild(mContext, obj);
[12:02] <smaug_> }
[12:02] <smaug_>
[12:02] <smaug_> PObjectWrapperChild* AllocPObjectWrapper(const bool&) {
[12:02] <smaug_> return AllocPObjectWrapper(JS_GetGlobalObject(mContext));
[12:02] <smaug_> }
[12:03] <smaug_> bool isn't used for anything
[12:03] <smaug_> but ok, there is the JSObject versino
[12:03] <smaug_> version
[12:03] <smaug_> good good
[12:03] <smaug_> this seems to be pretty trivial to implement
[12:03] <benjamn> that's on ObjectWrapperChild, though, not PObjectWrapperChild
[12:03] <benjamn> er, s/Object/Context/
[12:03] <benjamn> so you might have to downcast
[12:04] <benjamn> also, those methods are protected
[12:04] <benjamn> so you want to use ContextWrapperChild::GetOrCreateWrapper(JSObject*)
[12:04] <benjamn> that will reuse ObjectWrapperChild*s that have already been created
[12:05] <smaug_> ah, hmm, in the IPDL there is just async PObjectWrapper(bool makeGlobal);
[12:05] <benjamn> right
[12:05] <benjamn> there's no way to have a JSObject* as an IPDL method parameter
[12:05] <benjamn> since there's no way to serialize that
[12:06] <smaug_> right
[12:06] <benjamn> AllocPObjectWrapper(JSObject*) is just a normal methods
[12:06] <smaug_> ok, still one question
[12:06] <smaug_> about the managing CPOW objects
[12:06] <smaug_> when will they be deleted?
[12:07] <smaug_> when chrome JS gc runs?
[12:07] <smaug_> or something like that?
[12:07] <benjamn> possibly, but not necessarily
[12:07] <benjamn> if chrome is the only thing holding the object alive, then yes
[12:08] <smaug_> ok
[12:08] <benjamn> well, actually, if we're talking about PObjectWrappers
[12:08] <benjamn> then yes
[12:08] <benjamn> those die when the chrome gc runs
[12:08] <benjamn> the JSObject* in the child process might outlive its ObjectWrapperChild
[12:09] * smaug_ tries to use PObjectWrapper as a parameter in PIFrameEmbedding
[12:09] <smaug_> thanks again.
[12:09] <benjamn> can't just #include "mozilla/jsipc/PObjectWrapper.h"?
[12:09] <benjamn> oh, you're going to try :)
[12:09] <benjamn> it hasn't failed yet (hopefully)
[12:10] <smaug_> I waited until CPOW actually landed
[12:10] <smaug_> so hopefully I get this done in a day or two
[12:10] <benjamn> let me know if you have any complaints
[12:10] <benjamn> by the way, the PObjectWrapper actor pair can also be destroyed if the PContextWrapper that created it is destroyed, like if the owning TabChild dies
[12:11] <benjamn> then JSObject operations in chrome start throwing exceptions
[12:11] <smaug_> right. makes sense
[12:12] <benjamn> well, good luck, and thanks for being eager to work with CPOWs
[12:12] <smaug_> still one thing. are there limitations whether I can send PObjectWrappers synchronously and/or asynchronously ?
[12:13] <benjamn> the PObjectWrapper constructor method of PContextWrapper is marked async, so presumably you can do async
[12:14] <smaug_> and also sync, I guess
[12:14] <smaug_> ok, I'll try
[12:14] <benjamn> yep
[12:34] <smaug_> benjamn: I wonder if http://mxr.mozilla.org/projects-central/source/electrolysis/dom/ipc/TabParent.cpp?mark=204-206#196 needs to be changed a bit, if there will be another context for TabChildGlobal
[12:35] <benjamn> yes, I think it might
[12:36] <benjamn> maybe GetGlobalJSObject should be replaced with an interface that allows selecting between TabChildGlobals?
[12:38] <benjamn> I admit the GetGlobalJSObject interface is ambiguous
[12:38] <benjamn> and should probably go away
[12:40] <benjamn> wait, actually, if there's only one TabChildGlobal (TabChild::mTabChildGlobal), shouldn't that be what GetGlobalJSObject returns a wrapper for?
[12:40] <smaug_> there is only one TabchildGlobal
[12:41] <smaug_> but there is also the global object for the web page
[12:41] <benjamn> and it knows its JSContext, presumably?
[12:41] <smaug_> TabChild creates a JSContext yes
[12:41] <benjamn> hm
[12:41] <benjamn> creates it, interesting
[12:42] <smaug_> yes, that is really something different to non-E10s FF
[12:42] <smaug_> there is the new JSContext in content process
[12:42] <benjamn> do you think <browser>.crossProcessObjectWrapper should wrap the TabChildGlobal's JSContext's global object?
[12:42] <smaug_> could be
[12:43] <smaug_> since from TabChildGlobal you can always get the topmost web page global object using .content
[12:43] <benjamn> ok
[12:43] <benjamn> the new JSContext corresponds to chrome-controlled JS running in the child process?
[12:43] <smaug_> right
[12:43] <benjamn> I think that's really what I want to be using for CPOWs, then
[12:44] <benjamn> I'll investigate
[12:44] <smaug_> ok
[12:44] <smaug_> note, most of the tests are still in test.xul
[12:44] <smaug_> documentation is here https://wiki.mozilla.org/Content_Process_Event_Handlers
[12:44] <benjamn> yeah, I noticed that file's gotten a lot more interesting lately
[12:53] <benjamn> trying to understand how the .globalObject property of the new context differs from the global object of the content webpage
[12:56] <benjamn> where do you use TabChildGlobal as a nsIContentFrameMessageManager?
[13:04] <smaug_> TabChildGlobal is a nsIContentFrameMessageManager
[13:05] <smaug_> TabChild::InitTabChildGlobal() creates the JSContext and calls InitClassesWithNewWrappedGlobal where the scope is TabChildGlobal
[13:11] <benjamn> what is the "new wrapped global" (that becomes mRootGlobal)?
[13:11] <benjamn> that's not the top-level global object, apparently
[13:13] <smaug_> it is the global object for the JSContext where content process event listeners run
[13:13] <smaug_> or what you mean?
[13:20] <benjamn> so the content process event listeners run with a different global object from the content global object?
[13:21] <benjamn> do they see the same global properties as the content JS 'window'?
[13:22] <smaug_> no
[13:22] <benjamn> ah
[13:23] <benjamn> I guess that's the whole point, so there's no pollution of the chrome event handler global scope by the content page
[13:23] <smaug_> the TabChildGlobal has only sendSyncMessage, sendAsyncMessage, dump, addEventListener, removeEventListener
[13:23] <benjamn> got it
[13:23] <smaug_> oh, and addMessageListener, so that it can get messages from chrome
[13:24] <smaug_> and .content
[13:24] <smaug_> which is the top level content window
[13:25] <benjamn> so the new context/global is not what I want for CPOWs, since I actually want to manipulate the content global object
[13:25] <benjamn> well
[13:25] <benjamn> not what I want for <browser>.crossProcessObjectWrapper, I mean
[13:26] <benjamn> you should still be able to create a PContextWrapper for that new context, and create PObjectWrappers for objects that are available to event handlers
[13:27] <smaug_> ok
[13:27] <smaug_> but TabParent::GetGlobalJSObject will need still some tweaking I assume
[13:28] <benjamn> agreed
[13:29] <benjamn> oh, this is fascinating (and totally makes sense)…
[13:31] <benjamn> if I create a PContextWrapper and global PObjectWrapper using the new context, then, in the chrome process, I can get the .content property of that CPOW, and it has all the properties of the content global object, as expected
[13:31] <benjamn> so that's good
[13:31] <benjamn> I can rewrite GetGlobalJSObject to work that way, I think
[13:31] <smaug_> I can try this out first a bit
[13:31] <benjamn> ok
[13:32] <smaug_> and ask a review from you
[13:32] <benjamn> gladly
[13:34] <benjamn> once you decide how to store your PContextWrapper, I'll adapt GetGlobalJSObject to use the same context but return a CPOW for the .content property
[13:35] <benjamn> if that makes sense, great… if not, ignore :)
[13:35] <smaug_> :)
[13:35] <smaug_> you mean PContextWrapperParent?
[13:35] <benjamn> I mean the result of SendPContextWrapperConstructor
[13:36] <benjamn> which would be a PContextWrapperChild if sent from TabChild, I think?
[13:36] <smaug_> yeah
[13:36] <smaug_> could I just store ContextWrapperChild, which I then pass as a parameter to SendPContextWrapperConstructor?
[13:36] <benjamn> yes
[13:36] <benjamn> I would do that instead, actually
[13:36] <benjamn> eliminates the need for static_casting
[13:37] <smaug_> ok
[13:37] <smaug_> I hope I have something to review tomorrow
[13:37] <benjamn> great!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment