On 4/22/2014 12:46 AM, Boris Zbarsky wrote:
On 4/22/14, 12:24 AM, Joshua Cranmer 🐧 wrote:
I consider Promise more like a generic platform feature (considering
that the specification is moving to ES6 instead of DOM)

ES assumes you always have a global. In fact, until ES6 it assumed that there was only one global around, so of course you could always get access to this singleton global. ES6 is introducing Realms (read globals), but still assumes that any time any code is running that code is associated with a realm and knows what realm that is....

(except maybe insofar as things like
realms/compartments/etc. are concerned)

That's a pretty huge exception.

I'm giving to thinking in terms of all of the magic hiding that XPIDL/XPCOM/xpconnect does, so things like "what is my global object" being intrinsically important are annoying to me. Now, clearly, I don't expect to be able to create a DOM element without a reference to a Window or an XHR without one since their concerns are clearly tied to specific window properties, but something like Promises or TextEncoder which is more or less like "syntactic sugar for code I could write but don't want to" (excluding Promise's dependence on "run this on the next event tick," I suppose).

I think there are proposals to
add it to XPCOM JS component/module scopes, which to me is the
definition of "should be usable outside of web platform APIs."

"web platform APIs" would include ES6 Realms.

Component/module scopes have an nsIGlobalObject... and a Promise constructor, for that matter.

When I create an nsIJSImplementedInterfaceMagicObject from C++, I don't have to worry about global objects. Perhaps xpconnect should just expose the "here's a dummy global if you need one" more easily?

But that's only true if it's an actual Promise.

OK. Why is the thing you have not an actual Promise? Where did this thing come from?

I've heard that Promises.jsm are still better to use than DOM Promises...

For more specific explanation then:
I have a (non-negotiably) JS-implemented XPCOM service called the Folder
Lookup Service. I want to add an API to it called getOrCreateFolder that
returns a Promise<nsIMsgFolder>. I have non-negotiable C++ code that
wants to call this method, and do something when the promise is resolved
or rejected.

Thank you for explaining what you're trying to do.

The JS implemented XPCOM service can call |new Promise| (or any of the Promis static methods) to create an actual DOM Promise object, since we install that constructor on all XPConnect globals.

You can have getOrCreateFolder return "jsval" in the xpidl, then manually unwrap to a dom::Promise in the C++ like so:

  if (!value.isObject()) {
    // Throw
  }

  Promise* promise;
  nsresult rv = UNWRAP_OBJECT(Promise, &value.toObject(), promise);
  if (NS_FAILED(rv)) {
    // Throw
  }

Then you can call promise->AppendNativeHandler() with a handler you implement. At least assuming your code is in libxul. If not, we may need to add some symbol exported from libxul or a virtual function on Promise that lets you make this call.

That leaves the problem of extracting the nsIMsgFolder from the value you'll get resolved with, of course... nsIXPConnect has some methods for doing that sort of thing, like getNativeOfWrapper(), but they're a bit of an annoyance, I agree. I'd try harder to solve this problem if any solution were not going to be jettisoned when Promise moves into SpiderMonkey. :(

ToJSValue I think makes some of the pain of converting from T (for almost any xpidl-usable type, at least) much less painful. A corresponding FromJSValue could probably work well too. With something like those methods, I can probably do C++ magic that autogenerates the PromiseNativeHandler stuff for a generic nsresult nsFoo::DoX(U, V&);-ish method. When I have some more time, I can try playing with some magic prototype implementations and suggest which methods would be sufficient to be useful for my needs.

WebIDL is totally happy letting C++ call into JS. You just declare a callback interface, and get a generated C++ class that you can call into.

The missing piece is that this C++ class needs to be created with a JSObject* pointing to the JS thing it needs to actually talk to.

We've considered factoring out the "hunt down the object" thing from XPConnect's JS component loader so it's easier to reuse here, but for now used the "createInstance an nsISupports, then dig out the JSObject* from it" thing that dom::ConstructJSImplementation does.

We could add some IDL annotation that would let you get a C++ callback interface representation for a JS-implemented XPCOM service or some such, basically by running code like ConstructJSImplementation, but with getService instead of createInstance, if this is something people will want reasonably often. Note that unlike XPCOM services this would NOT give you the same pointer identity every time you call it; doing that would involve more annoying machinery that I'd like to not add unless it's really required.

The IDL annotation I think I'd want first is not defining these in the mozilla::dom namespace. ^_^ I don't think I care about pointer equality for services (just that services aren't created more than once), although if getting the service is kind of expensive, it may make sense to cache the service. For most of the new code I'm adding and/or rewriting, I'm largely sticking the access of these resources behind custom C++ methods instead of using the xpidl directly anyways (xpidl and arrays simply do not get along at all).


It might help if you ping me on IRC instead of trying to go back and
forth on the newsgroup...

Sure, if I had time today for in more than 15-minute snippets. But I'm technically on PTO, so I don't. I could have waited a few more days until I got back before responding at all, I guess.... ;)

Heh, I didn't realize you were on PTO, having better response times than I do when I'm not on vacation :-P

--
Joshua Cranmer
Thunderbird and DXR developer
Source code archæologist

_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to