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

Issue 630210 link

Starred by 3 users

Issue metadata

Status: Verified
Owner:
Closed: Oct 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 2
Type: Bug

Blocking:
issue 627816



Sign in to add a comment

Maplike with WebIDL dictionary objects?

Project Member Reported by hbos@chromium.org, Jul 21 2016

Issue description

The 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.
 

Comment 1 by hbos@chromium.org, Jul 21 2016

Description: Show this description
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.

Comment 3 by hbos@chromium.org, Jul 22 2016

Owner: hbos@chromium.org
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();
I guess that dictionaries are NOT expected to be allocated in heap at all, and I doubt the workaround.

bashi@, what do you think?

Comment 5 by hbos@chromium.org, 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.)

Comment 6 by bashi@chromium.org, 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.

Comment 7 by hbos@chromium.org, Jul 26 2016

Awesome!
Project Member

Comment 8 by bugdroid1@chromium.org, 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

Comment 9 by hbos@chromium.org, Jul 27 2016

Status: Started (was: Available)
#8: Much better, no need for type checking before doing toV8. Thanks.

Comment 10 by hbos@chromium.org, Oct 11 2016

Status: Verified (was: Started)
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

[bulk-edit : please ignore if not applicable]

Could you please set the correct milestone for this issue?

Comment 12 by hbos@chromium.org, Nov 16 2016

Labels: M-54

Sign in to add a comment