Re: Representing a pointer to static in XPConnected JS?
On 5/5/17 2:57 PM, Henri Sivonen wrote: I'm not sure what chrome JS runs on non-main threads and if there's non-main-thread chrome JS doing things like obtain an encoding name from a channel and pass it to the UTF8 converter service. There's nothing like that going on. This seems complicated enough that it's probably the best to have non-scriptable methods that are type-safe for C++ usage and scriptable overloads that deal with encoding names as strings for chrome JS. After all, Web Platform JS represents encodings as strings, too. OK. This does seem like the path of least resistance for the moment... -Boris ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Fri, May 5, 2017 at 6:02 PM, Boris Zbarsky wrote: > I'm not sure this is going to work in this case. WebIDL interfaces that > don't require refcounting basically require that the JS object owns the C++ > thing; it will delete it when finalized. > > You could do non-virtual no-op refcounting. But you still have a problem > where ToJSValue only knows how to work with subclasses of either nsISupports > or nsWrapperCache, both of which involve virtual functions. Yeah, that's not OK for my case. > If I can take a step back, though, you have the following requirements: > > 1) The same Encoding* has to lead to the same JS object. I thought that == could be true when the objects aren't the same as with strings, but now that I look at the spec, it seems that I was wrong. But perhaps chrome JS could get away with not comparing these things: just passing them from one XPCOM API to another. > 2) The JS representation needs to be an object. This is probably good in > terms of typesafety (in that we can check whether the object is actually the > thing we were passed), but complicates the other bits. For example, if this > were not a requirement, we could conceivably use a JS PrivateValue to just > directly encode the Encoding* in a value that looks like a JS Number. This > does mean that on JS-to-C++ conversion we'd effectively reinterpret_cast a > double to an Encoding*, so if someone messed up and passed some random > double bad things would happen. I suppose compared to that it would be pretty tame to have a string-based API that MOZ_CRASHes if the string argument isn't an encoding name. (Previously, we couldn't do that, since XPCOM extension bugs could then crash the browser, but maybe we could have higher expectations for our own chrome JS.) > One thing that is not clear to me: do you need support for this on worker > threads, or just mainthread? I'm not sure what chrome JS runs on non-main threads and if there's non-main-thread chrome JS doing things like obtain an encoding name from a channel and pass it to the UTF8 converter service. > This would be a bit of work, but not too insane, I think. This seems complicated enough that it's probably the best to have non-scriptable methods that are type-safe for C++ usage and scriptable overloads that deal with encoding names as strings for chrome JS. After all, Web Platform JS represents encodings as strings, too. -- Henri Sivonen hsivo...@hsivonen.fi https://hsivonen.fi/ ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On 5/5/17 4:09 AM, Henri Sivonen wrote: On Thu, May 4, 2017 at 7:39 PM, Nathan Froyd wrote: I think you could possibly make your things a WebIDL interface, which don't require refcounting, and magically make the WebIDL interfaces work with XPIDL, but I do not know the details there. I'll keep that in mind. Thanks. I'm not sure this is going to work in this case. WebIDL interfaces that don't require refcounting basically require that the JS object owns the C++ thing; it will delete it when finalized. You could do non-virtual no-op refcounting. But you still have a problem where ToJSValue only knows how to work with subclasses of either nsISupports or nsWrapperCache, both of which involve virtual functions. If I can take a step back, though, you have the following requirements: 1) The same Encoding* has to lead to the same JS object. This means you need either a global or a per-compartment (depending on how your object behaves in terms of cross-compartment wrappers) mapping from Encoding* to JS object. We have automated machinery for both versions of that, but it depends on either nsWrapperCache (for the global mapping) or nsISupports (pretty sure on that) for the cross-compartment mapping. We would have to add extra machinery of one sort of the other to handle not inheriting from either one. 2) The JS representation needs to be an object. This is probably good in terms of typesafety (in that we can check whether the object is actually the thing we were passed), but complicates the other bits. For example, if this were not a requirement, we could conceivably use a JS PrivateValue to just directly encode the Encoding* in a value that looks like a JS Number. This does mean that on JS-to-C++ conversion we'd effectively reinterpret_cast a double to an Encoding*, so if someone messed up and passed some random double bad things would happen. One thing that is not clear to me: do you need support for this on worker threads, or just mainthread? Because if this is not needed on workers, one thing we _could_ conceivably do is have some sort of setup where we define a new type that looks like void* on the C++ side and a JS object on the JS side, allocate the objects in the privileged junk scope, give them a recognizable JSClass to typesafety and a PrivateValue reserved slot for JS-to-C++ mapping, have a xpconnect-wide hashtable for C++-to-JS mapping. We could either have a finalizer that removes from the xpconnect-wide hashtable or trace that hashtable and thereby keep the objects alive forever or whatever; that mostly depends on how you want them to behave as weakmap keys. This would be a bit of work, but not too insane, I think. -Boris ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Thu, May 4, 2017 at 7:39 PM, Nathan Froyd wrote: > On Thu, May 4, 2017 at 12:32 PM, Henri Sivonen wrote: >> On Thu, May 4, 2017 at 4:27 PM, Nathan Froyd wrote: >>> On Thu, May 4, 2017 at 3:08 AM, Henri Sivonen wrote: Is it feasible (with reasonably low effort) to introduce a new XPIDL type that is a pointer to a non-refcounted immutable static object in C++ and still gets bridged to JS? >>> >>> You can certainly have static objects with what amount to dummy >>> AddRef/Release methods passed through XPIDL (we do this in a couple of >>> places throughout Gecko), but I don't think you can get away with >>> having a non-refcounted object passed through XPIDL. >> >> Do the AddRef/Release need to be virtual? > > Yes. (I'm not sure how XPConnect would discover the refcounting > methods if they were non-virtual.) > > Please note that the static objects with dummy AddRef/Release methods > also implement XPConnect interfaces, i.e. QueryInterface, nsresult > virtual methods, etc. OK. That doesn't fit my case. There's nothing virtual on either the C++ or Rust side about mozilla::Encoding / encoding_rs::Encoding. All the instances come from the Rust side and the interpretation of the pointer just changes when crossing the FFI so that C++ thinks it's a pointer to mozilla::Encoding. On the C++ side, the (all non-virtual) methods take the "this" pointer and send it back to Rust as the first argument to FFI. > I think you could possibly make your things a WebIDL interface, which > don't require refcounting, and magically make the WebIDL interfaces > work with XPIDL, but I do not know the details there. I'll keep that in mind. Thanks. Another option is to have dual methods on objects that are accessed from both C++ and JS: A non-scriptable method that takes const mozilla::Encoding* and a scriptable method that takes something else: either a string containing a name or some kind of manually-applied XPCOM/XPIDL-ish wrapper for const mozilla::Encoding*. It just would be nice for the wrapping part to be automagic in the binding. -- Henri Sivonen hsivo...@hsivonen.fi https://hsivonen.fi/ ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Thu, May 4, 2017 at 12:32 PM, Henri Sivonen wrote: > On Thu, May 4, 2017 at 4:27 PM, Nathan Froyd wrote: >> On Thu, May 4, 2017 at 3:08 AM, Henri Sivonen wrote: >>> Is it feasible (with reasonably low effort) to introduce a new XPIDL >>> type that is a pointer to a non-refcounted immutable static object in >>> C++ and still gets bridged to JS? >> >> You can certainly have static objects with what amount to dummy >> AddRef/Release methods passed through XPIDL (we do this in a couple of >> places throughout Gecko), but I don't think you can get away with >> having a non-refcounted object passed through XPIDL. > > Do the AddRef/Release need to be virtual? Yes. (I'm not sure how XPConnect would discover the refcounting methods if they were non-virtual.) Please note that the static objects with dummy AddRef/Release methods also implement XPConnect interfaces, i.e. QueryInterface, nsresult virtual methods, etc. I think you could possibly make your things a WebIDL interface, which don't require refcounting, and magically make the WebIDL interfaces work with XPIDL, but I do not know the details there. -Nathan ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Thu, May 4, 2017 at 4:27 PM, Nathan Froyd wrote: > On Thu, May 4, 2017 at 3:08 AM, Henri Sivonen wrote: >> Is it feasible (with reasonably low effort) to introduce a new XPIDL >> type that is a pointer to a non-refcounted immutable static object in >> C++ and still gets bridged to JS? > > You can certainly have static objects with what amount to dummy > AddRef/Release methods passed through XPIDL (we do this in a couple of > places throughout Gecko), but I don't think you can get away with > having a non-refcounted object passed through XPIDL. Do the AddRef/Release need to be virtual? -- Henri Sivonen hsivo...@hsivonen.fi https://hsivonen.fi/ ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Thu, May 4, 2017 at 3:08 AM, Henri Sivonen wrote: > Is it feasible (with reasonably low effort) to introduce a new XPIDL > type that is a pointer to a non-refcounted immutable static object in > C++ and still gets bridged to JS? You can certainly have static objects with what amount to dummy AddRef/Release methods passed through XPIDL (we do this in a couple of places throughout Gecko), but I don't think you can get away with having a non-refcounted object passed through XPIDL. -Nathan ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform
Re: Representing a pointer to static in XPConnected JS?
On Thu, May 4, 2017 at 10:08 AM, Henri Sivonen wrote: > Is it feasible (with reasonably low effort) to introduce a new XPIDL > type that is a pointer to a non-refcounted immutable static object in > C++ and still gets bridged to JS? My question was underspecified. At minimum, the JS bridging should have these properties: 1) Returning a non-null const Encoding* from C++ materializes a JS object. 2) Passing the JS object back to C++ materializes the original pointer on the C++ side. 3) Returning a null const Encoding* from C++ materializes a JS null. 4) Passing a JS null to C++ materializes nullptr. 5) Comparing two JS objects materialized per point #1 with == is true iff they were materiazed from the same C++ pointer. Is that kind of thing doable with little effort? It would be a bonus if the JS objects could come with pre-defined methods, but that's not strictly necessary. -- Henri Sivonen hsivo...@hsivonen.fi https://hsivonen.fi/ ___ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform