Dictionaries having DISALLOW_NEW_EXCEPT_PLACEMENT_NEW is a restriction that causes problems.
Because you can't do "new DictionaryType()" you can't have Vectors, Maps or Maplikes with DictionaryType. You can't have Member<DictionaryType> and you're only able to copy and return by value. Why? Dictionaries are javascript objects, why not be able to reference them by their dictionary type like it is possible with interface?
This restriction isn't big problem when interpreting method arguments as dictionaries, but it's quite limiting when you want to return dictionary objects, especially as part of collections.
The only workaround I know of is to convert the dictionary to v8::Value.
Example:
- https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h
- https://codereview.chromium.org/2828563002/
Dictionaries having DISALLOW_NEW_EXCEPT_PLACEMENT_NEW is a restriction that causes problems.
Because you can't do "new DictionaryType()" you can't have Vectors, Maps or Maplikes with DictionaryType. You can't have Member<DictionaryType> and you're only able to copy and return by value. Why? Dictionaries are javascript objects, why not be able to reference them by their dictionary type like it is possible with interface?
This restriction isn't big problem when interpreting method arguments as dictionaries, but it's quite limiting when you want to return dictionary objects, especially as part of collections.
The only workaround I know of is to convert the dictionary to v8::Value.
Examples:
- RTCStatsReport being Maplike: https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h
- Trying to return FrozenArray of dictionary (RTCCertificate.fingerprints): https://codereview.chromium.org/2828563002/
Does the DISALLOW_NEW_EXCEPT_PLACEMENT_NEW design decision have anything to do with WebIDL and wanting to pretend dictionaries are "values" and not "references"?
> Does the DISALLOW_NEW_EXCEPT_PLACEMENT_NEW design decision have anything to do with WebIDL and wanting to pretend dictionaries are "values" and not "references"?
Yes.
Also IDL dictionaries are used only as method parameters and return values. So I think that restricting the usages to stack-allocated objects would be okay.
We intentionally added the restriction because we didn't have a way to create an object reference cycle between V8 and Blink (e.g., storing a dictionary object on a Blink object will cause memory leaks) when we introduced dictionaries. Now that we have the wrapper tracing, it's possible to get rid of the restriction.
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue.
Sorry for the inconvenience if the bug really should have been left as Available.
For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
As peria@ is working on the bindings code generator, he might be interested in this issue, too. Feel free to unassign yourself or reassign to someone else.
Just FYI, IDL dictionary is a value-ish object.
https://heycam.github.io/webidl/#es-dictionary
IDL interface type values need to convert back to the original ES objects. However, IDL dictionary type values do NOT need to convert back to the original ES objects. The Web IDL says that each conversion from IDL dictionary to ES object MUST create a new object.
Having said that, this difference doesn't necessarily justify STACK_ALLOCATED. We can still implement IDL dictionary as a heap object.
In addition to #c4, I vaguely guess that we wanted to avoid the allocation overhead to be faster?
The RTCStatsReport is Maplike<DOMString, object> per spec[1]. Where each mapped object is an RTCStats[2]-derived dictionary (one of the dictionaries in [3]). This not being defined as "Maplike<DOMString, RTCStats>" is a limitation of WebIDL, either because of not being able to express "RTCStats or descendant dictionary" or because of limitations of valid values of V for Maplike<K,V>.
Our implementation constructs a new v8 object each time you do report.get('id') or iterate, which means that report.get('foo') != report.get('foo'). This makes sense since dictionaries should be returned "by value". Unless you argue that "object" of "Maplike<DOMString, object>" is not "by value" and so the "value-copy" should only happen when the object is placed in the map, and not in subsequent retrievals. I'm not sure? But I think our implementation is right.
I filed this bug because I couldn't place .idl generated dictionaries in a map, but this does not matter anymore. The dictionaries are surfaced from lower layer code and generating the v8 objects upon retrieval[4]. Whether copied each time or returned by reference, they should be created by code like this and not with .idl generated dictionaries.
As such I personally don't need this bug to be fixed, but there could be other usages.
[1] https://w3c.github.io/webrtc-pc/#rtcstatsreport-object
[2] https://w3c.github.io/webrtc-pc/#dom-rtcstats
[3] https://w3c.github.io/webrtc-stats/
[4] https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc?sq=package:chromium&dr=CSs&l=190
Comment 1 by hbos@chromium.org
, Apr 24 2017