New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 700180 link

Starred by 7 users

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 3
Type: Feature

Blocking:
issue 622002
issue 704627
issue 740081



Sign in to add a comment

Support Mojo typemaps to IDL dictionaries

Project Member Reported by reillyg@chromium.org, Mar 9 2017

Issue description

There are many cases in Blink were we pass parameters that comes from script in the form of an autogenerated class (defined in WebIDL as a dictionary) to a Mojo method.

An example of this is the USB::requestDevice() method which takes an array of USBDeviceFilter objects and passes them to the device::usb::ChooserService::GetPermission() method. The definitions of USBDeviceFilter in USBDeviceFilter.idl and device::usb::DeviceFilter in device_manager.mojom are effectively identical and it would be useful if they could be typemapped together.

Unfortunately typemapping a Mojo struct to an IDL dictionary is not possible because the autogenerated Blink object is garbage collected and the Mojo code generator is unaware of the requirements of garbage collected objects, such as storing pointers to them in Persistent wrappers when they are fields of a non-GCed object or storing them in WTF::HeapVector instead of WTF::Vector.
 
Cc: roc...@chromium.org
I am not familiar with the requirements of garbage collected objects.

I remember we discussed a simple alternative is to typemap to Persistent<Foo>. Vectors will be WTF::Vector<Persistent<Foo>>. Is that acceptable? Do you mean you would like vectors mapped to WTF::HeapVector<Foo> instead?

That would require some extension to the current typemap configuration. I am not sure how important/urgent this is.
Cc: haraken@chromium.org
Adding haraken@ for an opinion on the best way to handle Mojo structs holding GCed objects. I think I was incorrect to suggest mapping to WTF::HeapVector<Foo>. WTF::Vector<Persistent<Foo>> is the correct option because it does not require the containing object to be traced.
I also remember now my objection to typemapping to Persistent<Foo>. I makes sense for struct members but not for Mojo function signatures, which should use raw pointers.
Vectors of Persistents are pretty high overhead. In this case this is just about taking inputs to an IPC, so mojo shouldn't need to store anything into a Persistent just serialize the data down into the pipe? It's only return values that would require vending GC'ed objects. If we're going to support that I think I'd prefer we just made the entire return value GC'ed and used HeapVector, etc.
Due to the way WebIDL works yes, we essentially only need to support the Blink to Mojo mapping path since data passing the other direction is usually in an IDL defined interface, not a dictionary. However since Mojo represents method calls as structs passed over a pipe we do need a way to have a valid struct containing a GCed object, at least temporarily.

It would be nice if Persistent<HeapVector<Foo>> were valid. Maybe it is?
We have PersistentHeapVector :D

https://cs.chromium.org/search/?q=persistentheapvector&sq=package:chromium&type=cs

Just to confirm: The vectors are guaranteed to be released in a finite time period, right? Otherwise, the persistent handle will cause memory leaks.

So for some examples:

The signature for the GetPermission() method defined in chooser_service.mojom we would be,

void GetPermission(WTF::HeapVector<blink::USBDeviceFilter> device_filters,
                   const GetPermissionCallback& callback);

The EnumerationOptions struct defined in device_manager.mojom would be (simplified),

class EnumerationOptions {
 public:
  WTF::Optional<WTF::PersistentHeapVector<blink::USBDeviceFilter>> filters;
 private:
  DISALLOW_COPY_AND_ASSIGN(EnumerationOptions);
};

The signature of the ControlTransferIn() method defined in device.mojom would be,

void ControlTransferIn(blink::USBControlTransferParameters* params, uint32_t length,
                       uint32_t timeout, const ControlTransferInCallback& callback);
Cc: kpaulhamus@chromium.org
Status: Available (was: Untriaged)
After discussing this with yzshen@ and rockot@ we agree that this work is worthwhile but there is no current owner. To implement this we need to add two features to the bindings generator:

1. Allow an annotation on a type mapping (such as [gc]) to select a different variant configuration than the default for that subsystem.
2. Allow a variant to define separate types to be used for struct members and function signatures. This way the blink_gc variant could use raw pointers and Heap* collections for function signatures and Persistent<> fields and PersistentHeap* collections for struct fields.
Cc: mcasas@chromium.org

Comment 12 by sa...@chromium.org, Mar 15 2017

Cc: w...@chromium.org
Blocking: 622002
Blocking: 704627
Blocking: 740081
Allowing a variant to specify separate types for struct members and method signatures would also allow the Chromium variant to accept base::StringPiece in function arguments which may reduce some copying of strings.

A note for bugs marked as blocked on this issue: A workaround is to use an old-style mojo::TypeConverter specialization instead of a typemap.
Cc: dcheng@chromium.org
Status: WontFix (was: Available)
Closing this as there is now consensus on taking a different approach, and it has been documented here:

https://chromium.googlesource.com/chromium/src/+/master/docs/security/mojo.md#do-not-write-one_off-functions-to-convert-to_from-mojo-types
Status: Untriaged (was: WontFix)
I was discussing with Ken the best way to typemap some IndexedDB mojom types to Blink GC'd types like IDBKeyRange which is based on ScriptWrappable.  After discussing, Ken pointed out this FR and said this might be worth re-opening, so marking it Untriaged for review.
Owner: peria@chromium.org
Status: Assigned (was: Untriaged)
peria, could you take a look? You've looked at IDLDictionary recently.
Yes, if I can help you from WebIDL bindings' point.

Sign in to add a comment