Re: Representing a pointer to static in XPConnected JS?

2017-05-05 Thread Boris Zbarsky

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?

2017-05-05 Thread Henri Sivonen
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?

2017-05-05 Thread Boris Zbarsky

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?

2017-05-05 Thread Henri Sivonen
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?

2017-05-04 Thread Nathan Froyd
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?

2017-05-04 Thread Henri Sivonen
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?

2017-05-04 Thread Nathan Froyd
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?

2017-05-04 Thread Henri Sivonen
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