IDL bindings generator applies the attributes of the alphabetically first partial interface to the entire interface |
|||||
Issue description
Version: 52
OS: All
What steps will reproduce the problem?
(1) Add a new API to "navigator". Call it something that comes alphabetically before "Battery". Say, "NavigatorActions".
(2) Create a partial interface, NavigatorActions.idl.
(3) Give the new partial interface a RuntimeEnabled condition with status=experimental:
[
RuntimeEnabled=Ballista,
] partial interface Navigator {
readonly attribute Actions actions;
};
(see: https://codereview.chromium.org/1806253002/#ps240001)
What is the expected output?
New attribute navigator.actions is present only when --enable-experimental-web-platform-features is on. When that flag is off, navigator.actions is undefined.
What do you see instead?
When --enable-experimental-web-platform-features is off, MOST OF THE ATTRIBUTES IN navigator ARE UNDEFINED!!!
For example:
> navigator.getBattery()
Uncaught TypeError: navigator.getBattery is not a function(…)
This is the generated code in V8NavigatorPartial.cpp; V8NavigatorPartial::installV8NavigatorTemplate:
// Register DOM constants, attributes and operations.
if (RuntimeEnabledFeatures::ballistaEnabled()) {
V8DOMConfiguration::installAccessors(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8NavigatorAccessors, WTF_ARRAY_LENGTH(V8NavigatorAccessors));
V8DOMConfiguration::installMethods(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8NavigatorMethods, WTF_ARRAY_LENGTH(V8NavigatorMethods));
} // if (RuntimeEnabledFeatures::ballistaEnabled())
if (RuntimeEnabledFeatures::ballistaEnabled()) {
const V8DOMConfiguration::AccessorConfiguration accessoractionsConfiguration = \
{"actions", NavigatorPartialV8Internal::actionsAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::ReadOnly), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder};
V8DOMConfiguration::installAccessor(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, accessoractionsConfiguration);
}
....
All of the accessors and methods in the default set (V8NavigatorAccessors and V8NavigatorMethods) are conditional on ballistaEnabled() for some reason. The RuntimeEnabled=Ballista flag is now controlling ALL the features in navigator.
So it turns out that whichever partial interface comes first alphabetically will have its extended attributes (such as the RuntimeEnabled attribute) applied to the entire interface. Currently, the Navigator interface is getting its extended attributes from the NavigatorBattery partial interface, which fortunately has no extended attributes so everything is "fine". If you try to add a new partial interface that alphabetically precedes "Battery", you're gonna have a bad time.
Some debug logging of interfaces ("x of y" refers to the interface name and idl_name) and extended attributes to show the problem:
1) DEBUG:root:generate_code(['NavigatorActions'], 'Navigator')
2) DEBUG:root:interface_context(<IdlInterface: Navigator of NavigatorActions>)
3) DEBUG:root:runtime_feature_name(<IdlInterface: Navigator of NavigatorActions> => extended_attributes = {'RuntimeEnabled': 'Ballista', 'GarbageCollected': None})
4) DEBUG:root:runtime_enabled_function_name(<IdlInterface: Navigator of NavigatorActions> => 'RuntimeEnabledFeatures::ballistaEnabled')
5) DEBUG:root:runtime_enabled_function_name(<IdlAttribute: actions of NavigatorActions> => 'RuntimeEnabledFeatures::ballistaEnabled')
6) DEBUG:root:runtime_enabled_function_name(<IdlAttribute: bluetooth of NavigatorBluetooth> => None)
....
Note: Lines 5 onwards are correctly getting the extended attributes of the specific IDL attributes ("actions of NavigatorActions" is correct). But Lines 1--4 show that the main IdlInterface keyed by "Navigator" is in fact the NavigatorActions partial interface, and so it incorrectly inherits NavigatorActions' extended attributes.
,
Apr 15 2016
CL to fix this issue: https://codereview.chromium.org/1884423002/ Note, it doesn't address the root cause (which is that all of the partial interfaces are being piled onto the alphabetically first partial interface), but it does address the immediate problem by removing the extended attributes from the merged interface (which have been transferred onto the individual attributes).
,
Apr 18 2016
,
Apr 18 2016
Actually, while fixing this, I found that this bug is affecting real Chrome APIs right now: WorkerNavigator is inheriting the extended attributes of WorkerNavigatorGeofencing.idl which is experimental only, so some attributes of WorkerNavigator are actually undefined (apparently not any that anyone cares about). Issue 604292 .
,
Apr 19 2016
,
Apr 19 2016
,
Apr 20 2016
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43 commit 4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43 Author: mgiuca <mgiuca@chromium.org> Date: Wed Apr 20 02:48:56 2016 IDL bindings: Avoid extended attributes leaking onto merged interface. Some extended attributes from dependency interface definitions are transferred onto the definition's attributes before being merged. However, the merged interfaces still retain the extended attributes from the definition that comes first alphabetically, which can result in extended attributes from one partial interface "leaking" onto all of the others. The transferred extended attributes are now deleted from the dependency interface so that they do not leak onto the merged interface. Fixes a bug where adding a new RuntimeEnabled condition in a partial interface can apply the condition to all members of the final interface. BUG= 603782 , 604292 Review URL: https://codereview.chromium.org/1884423002 Cr-Commit-Position: refs/heads/master@{#388409} [modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py [add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/idls/modules/TestInterface2Partial.idl [add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/idls/modules/TestInterface2Partial2.idl [modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp [modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h [add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.cpp [add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h [modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Tools/Scripts/webkitpy/bindings/main.py
,
Apr 20 2016
|
|||||
►
Sign in to add a comment |
|||||
Comment 1 by bashi@chromium.org
, Apr 15 2016