Maplike with WebIDL dictionary objects? |
|||||
Issue descriptionThe WebRTC spec uses maplike (http://heycam.github.io/webidl/#idl-maplike) for its RTCStatsReport interface (https://www.w3.org/TR/2016/WD-webrtc-20160531/#rtcstatsreport-object). interface RTCStatsReport { readonly maplike<DOMString, object>; // object = any RTCStats-derived dictionary }; When implementing Maplike<KeyType, ValueType> (https://cs.chromium.org/chromium/src/third_party/WebKit/Source/bindings/core/v8/Maplike.h?q=Maplike&sq=package:chromium&l=15&dr=CSs) the ValueType is required to be a subclass of ScriptWrappable. In C++, having RTCStatsReport inherit from Maplike<String, RTCStats*> does not compile if RTCStats is a dictionary, but it does if RTCStats is an interface. WebIDL dictionary objects are neither ScriptWrappable or garbage collected. According to the spec, RTCStats is a dictionary (https://www.w3.org/TR/2016/WD-webrtc-20160531/#idl-def-rtcstats). dictionary RTCStats { ... }; - Should it be possible to have Maplike with IDL-defined dictionaries? If YES: Maplike or dictionary objects might need to be updated. If NO: The WebRTC/stats spec might need to be updated.
,
Jul 22 2016
We think you can use maplike with dictionaries, but you'll need to #include a certain header explicitly.
Our understanding is that Maplike<Key, Value> works fine with arbitrary class that is supported with toV8() overloaded functions. Most of toV8() family are supported in bindings/core/v8/ToV8.h and bindings/modules/v8/ToV8ForModules.h, however, there are exceptions.
toV8() for dictionaries are declared in bindings/{core,modules}/v8/${DictName}.h because dictionaries are code-generated. So, you need to #include that header explicitly on your side.
For example, you can see toV8() for dictionary types in
out/Release/gen/blink/bindings/core/v8/CSSStyleValueOrCSSStyleValueSequence.h
out/Release/gen/blink/bindings/core/v8/V8CSSCalcDictionary.h
I admit this is inconvenient and there is room for improvement, but could you explicitly #include the header for your dictionary?
If this doesn't work for you, or something else is causing the issue, please let us know.
,
Jul 22 2016
Thanks.
By including the V8 header as you suggested, toV8(const RTCStats&) was defined. This means Maplike<String, RTCStats> will work, but still not Maplike<String, RTCStats*>.
This poses a problem in that when RTCStats-copies are made and returned only the RTCStats-part of the RTCStats-derived objects are copied (child class members are discarded).
However, by changing to Maplike<String, v8::Local<v8::Value>> I am be able to include and invoke the appropriate toV8 function myself and thus support the derived dictionaries as well. I'll explore this more and get back to this thread.
bool next(ScriptState* scriptState, String& key, v8::Local<v8::Value>& value, ExceptionState& exceptionState) override {
key = /* iterator key */;
RTCStats* stats = /* iterator value */;
v8::Local<v8::Object> creationContext = scriptState->context()->Global();
v8::Isolate* isolate = scriptState->isolate();
if (/* stats is of type RTCCertificateStats, this will be testable with a type enum */)
value = toV8(*static_cast<RTCCertificateStats*>(stats), creationContext, isolate);
return true;
}
Dictionary objects do have DISALLOW_NEW_EXCEPT_PLACEMENT_NEW() though so I have to do a workaround when allocating these objects, e.g:
uint8_t* mem = new uint8_t[sizeof(RTCCertificateStats)];
RTCCertificateStats* certificateStats = new(mem) RTCCertificateStats();
,
Jul 22 2016
I guess that dictionaries are NOT expected to be allocated in heap at all, and I doubt the workaround. bashi@, what do you think?
,
Jul 22 2016
Indeed they're not, they're not GC'd, have to be copied and toV8 constructs a new object from scratch and copies its member values. Dictionaries don't seem to have been designed for what I need to do. (Note about the workaround: I think I'm already forced to have a type enum due to having to translate webrtc stats into blink objects, two repos that don't have access to each others' classes, so the type check might not be super bad. Workaround for placement new is a bit hacky though.)
,
Jul 26 2016
Sorry I missed this. Chatted with yukishiino@ and he came up with a good solution for this problem. I'll implement the solution.
,
Jul 26 2016
Awesome!
,
Jul 27 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/190cffeadfe46c6419789d586551c877b24f082f commit 190cffeadfe46c6419789d586551c877b24f082f Author: bashi <bashi@chromium.org> Date: Wed Jul 27 11:04:42 2016 Add IDLDictionaryBase Before this CL, given an IDL dictionary (e.g. FooDictionary) the code generator generated ToV8() directly. This is problematic when Blink wants to pass a sub-dictionary of FooDictionary because generated ToV8() doesn't convert members defined in the sub-dictionary. To solve this problem, add a base class which provides toV8Impl() virtual function. The code generator overrides toV8Impl() and ToV8() uses them. ToV8() automatically calls appropriate toV8Impl(). BUG= 630210 Review-Url: https://codereview.chromium.org/2183623004 Cr-Commit-Position: refs/heads/master@{#408093} [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/LayoutTests/fast/dom/idl-dictionary-unittest-expected.txt [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/LayoutTests/fast/dom/idl-dictionary-unittest.html [add] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/core/v8/IDLDictionaryBase.cpp [add] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/core/v8/IDLDictionaryBase.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/core/v8/ToV8.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/core/v8/v8.gypi [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/scripts/v8_dictionary.py [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/templates/dictionary_impl.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/templates/dictionary_v8.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/templates/dictionary_v8.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestDictionary.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestDictionaryDerivedImplementedAs.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestInterfaceEventInit.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestPermissiveDictionary.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/TestPermissiveDictionary.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionary.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestDictionaryDerived.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInit.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterfaceEventInit.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestPermissiveDictionary.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/bindings/tests/results/core/V8TestPermissiveDictionary.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/BUILD.gn [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/core.gypi [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/core_generated.gypi [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/testing/DictionaryTest.cpp [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/testing/DictionaryTest.h [modify] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/testing/DictionaryTest.idl [add] https://crrev.com/190cffeadfe46c6419789d586551c877b24f082f/third_party/WebKit/Source/core/testing/InternalDictionaryDerivedDerived.idl
,
Jul 27 2016
#8: Much better, no need for type checking before doing toV8. Thanks.
,
Oct 11 2016
Maplike of dictionaries (maplike<DOMString, object>) is possible by implementing Maplike<String, v8::Local<v8::Value>>. In my case[1] I wound up creating the dictionary objects by looping through members, but for WebIDL-defined dictionaries the toV8 function can be used as well, thanks to [comment #8]. In either case, a maplike of dictionaries is possible, so I'm closing this issue. [1] https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/peerconnection/RTCStatsReport.h?sq=package:chromium&dr&l=20
,
Nov 15 2016
[bulk-edit : please ignore if not applicable] Could you please set the correct milestone for this issue?
,
Nov 16 2016
|
|||||
►
Sign in to add a comment |
|||||
Comment 1 by hbos@chromium.org
, Jul 21 2016