Commit 0a7d5573 authored by Yuki Shiino's avatar Yuki Shiino Committed by Commit Bot

bind-gen: Implement exposed interfaces and namespaces

Bug: 839389
Change-Id: Icb07d31a622bca16b70dea9e9a4e1ac5c83fb411
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1984791Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Commit-Queue: Yuki Shiino <yukishiino@chromium.org>
Cr-Commit-Position: refs/heads/master@{#728153}
parent 7b2ee5b3
...@@ -51,6 +51,7 @@ class CodeGenContext(object): ...@@ -51,6 +51,7 @@ class CodeGenContext(object):
"constructor": None, "constructor": None,
"constructor_group": None, "constructor_group": None,
"dict_member": None, "dict_member": None,
"exposed_construct": None,
"operation": None, "operation": None,
"operation_group": None, "operation_group": None,
...@@ -224,7 +225,8 @@ class CodeGenContext(object): ...@@ -224,7 +225,8 @@ class CodeGenContext(object):
@property @property
def property_(self): def property_(self):
return (self.attribute or self.constant or self.constructor_group return (self.attribute or self.constant or self.constructor_group
or self.dict_member or self.operation_group) or self.dict_member or self.exposed_construct
or self.operation_group)
@property @property
def return_type(self): def return_type(self):
......
...@@ -147,9 +147,9 @@ def expr_uniq(terms): ...@@ -147,9 +147,9 @@ def expr_uniq(terms):
def expr_from_exposure(exposure, global_names=None): def expr_from_exposure(exposure, global_names=None):
""" """
Args: Args:
exposure: web_idl.Exposure exposure: web_idl.Exposure of the target construct.
in_global: A global name of [Exposed] that the ExecutionContext is global_names: When specified, it's taken into account that the global
supposed to be / represent. object implements |global_names|.
""" """
assert isinstance(exposure, web_idl.Exposure) assert isinstance(exposure, web_idl.Exposure)
assert (global_names is None assert (global_names is None
...@@ -157,7 +157,9 @@ def expr_from_exposure(exposure, global_names=None): ...@@ -157,7 +157,9 @@ def expr_from_exposure(exposure, global_names=None):
and all(isinstance(name, str) for name in global_names))) and all(isinstance(name, str) for name in global_names)))
def ref_enabled(feature): def ref_enabled(feature):
return _Expr("RuntimeEnabledFeatures::{}Enabled()".format(feature)) arg = "${execution_context}" if feature.is_context_dependent else ""
return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format(
feature, arg))
top_terms = [_Expr(True)] top_terms = [_Expr(True)]
...@@ -175,15 +177,25 @@ def expr_from_exposure(exposure, global_names=None): ...@@ -175,15 +177,25 @@ def expr_from_exposure(exposure, global_names=None):
"Worklet": "IsWorkletGlobalScope", "Worklet": "IsWorkletGlobalScope",
} }
exposed_terms = [] exposed_terms = []
for entry in exposure.global_names_and_features: if global_names is None:
terms = [] for entry in exposure.global_names_and_features:
if entry.global_name not in (global_names or []): terms = []
pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name] pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name]
terms.append(_Expr("${{execution_context}}->{}()".format(pred))) terms.append(_Expr("${{execution_context}}->{}()".format(pred)))
if entry.feature: if entry.feature:
terms.append(ref_enabled(entry.feature)) terms.append(ref_enabled(entry.feature))
if terms: if terms:
exposed_terms.append(expr_and(terms)) exposed_terms.append(expr_and(terms))
else:
matched_global_count = 0
for entry in exposure.global_names_and_features:
if entry.global_name not in global_names:
continue
matched_global_count += 1
if entry.feature:
exposed_terms.append(ref_enabled(entry.feature))
assert (not exposure.global_names_and_features
or matched_global_count > 0)
if exposed_terms: if exposed_terms:
top_terms.append(expr_or(exposed_terms)) top_terms.append(expr_or(exposed_terms))
......
...@@ -78,14 +78,16 @@ def callback_function_name(cg_context, overload_index=None): ...@@ -78,14 +78,16 @@ def callback_function_name(cg_context, overload_index=None):
if cg_context.attribute_get: if cg_context.attribute_get:
kind = "AttributeGet" kind = "AttributeGet"
if cg_context.attribute_set: elif cg_context.attribute_set:
kind = "AttributeSet" kind = "AttributeSet"
if cg_context.constant: elif cg_context.constant:
kind = "Constant" kind = "Constant"
if cg_context.constructor_group: elif cg_context.constructor_group:
property_name = "" property_name = ""
kind = "Constructor" kind = "Constructor"
if cg_context.operation_group: elif cg_context.exposed_construct:
kind = "ExposedConstruct"
elif cg_context.operation_group:
kind = "Operation" kind = "Operation"
if overload_index is None: if overload_index is None:
...@@ -95,9 +97,9 @@ def callback_function_name(cg_context, overload_index=None): ...@@ -95,9 +97,9 @@ def callback_function_name(cg_context, overload_index=None):
if cg_context.for_world == CodeGenContext.MAIN_WORLD: if cg_context.for_world == CodeGenContext.MAIN_WORLD:
world_suffix = "ForMainWorld" world_suffix = "ForMainWorld"
if cg_context.for_world == CodeGenContext.NON_MAIN_WORLDS: elif cg_context.for_world == CodeGenContext.NON_MAIN_WORLDS:
world_suffix = "ForNonMainWorlds" world_suffix = "ForNonMainWorlds"
if cg_context.for_world == CodeGenContext.ALL_WORLDS: elif cg_context.for_world == CodeGenContext.ALL_WORLDS:
world_suffix = "" world_suffix = ""
return name_style.func(property_name, kind, callback_suffix, world_suffix) return name_style.func(property_name, kind, callback_suffix, world_suffix)
...@@ -107,7 +109,7 @@ def constant_name(cg_context): ...@@ -107,7 +109,7 @@ def constant_name(cg_context):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
assert cg_context.constant assert cg_context.constant
property_name = cg_context.property_.identifier property_name = cg_context.property_.identifier.lower()
kind = "Constant" kind = "Constant"
...@@ -643,7 +645,8 @@ def make_cooperative_scheduling_safepoint(cg_context): ...@@ -643,7 +645,8 @@ def make_cooperative_scheduling_safepoint(cg_context):
def make_log_activity(cg_context): def make_log_activity(cg_context):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
ext_attrs = cg_context.member_like.extended_attributes target = cg_context.member_like or cg_context.property_
ext_attrs = target.extended_attributes
if "LogActivity" not in ext_attrs: if "LogActivity" not in ext_attrs:
return None return None
target = ext_attrs.value_of("LogActivity") target = ext_attrs.value_of("LogActivity")
...@@ -669,10 +672,10 @@ def make_log_activity(cg_context): ...@@ -669,10 +672,10 @@ def make_log_activity(cg_context):
if cg_context.attribute_get: if cg_context.attribute_get:
_1 = "LogGetter" _1 = "LogGetter"
_4 = "" _4 = ""
if cg_context.attribute_set: elif cg_context.attribute_set:
_1 = "LogSetter" _1 = "LogSetter"
_4 = ", ${info}[0]" _4 = ", ${info}[0]"
if cg_context.operation_group: elif cg_context.operation_group:
_1 = "LogMethod" _1 = "LogMethod"
_4 = ", ${info}" _4 = ", ${info}"
body = _format(pattern, _1=_1, _2=_2, _3=_3, _4=_4) body = _format(pattern, _1=_1, _2=_2, _3=_3, _4=_4)
...@@ -936,7 +939,8 @@ def make_overload_dispatcher(cg_context): ...@@ -936,7 +939,8 @@ def make_overload_dispatcher(cg_context):
def make_report_deprecate_as(cg_context): def make_report_deprecate_as(cg_context):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
name = cg_context.member_like.extended_attributes.value_of("DeprecateAs") target = cg_context.member_like or cg_context.property_
name = target.extended_attributes.value_of("DeprecateAs")
if not name: if not name:
return None return None
...@@ -954,7 +958,8 @@ def make_report_deprecate_as(cg_context): ...@@ -954,7 +958,8 @@ def make_report_deprecate_as(cg_context):
def make_report_measure_as(cg_context): def make_report_measure_as(cg_context):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
ext_attrs = cg_context.member_like.extended_attributes target = cg_context.member_like or cg_context.property_
ext_attrs = target.extended_attributes
if not ("Measure" in ext_attrs or "MeasureAs" in ext_attrs): if not ("Measure" in ext_attrs or "MeasureAs" in ext_attrs):
assert "HighEntropy" not in ext_attrs, "{}: {}".format( assert "HighEntropy" not in ext_attrs, "{}: {}".format(
cg_context.idl_location_and_name, cg_context.idl_location_and_name,
...@@ -969,9 +974,11 @@ def make_report_measure_as(cg_context): ...@@ -969,9 +974,11 @@ def make_report_measure_as(cg_context):
suffix = "_AttributeSetter" suffix = "_AttributeSetter"
elif cg_context.constructor: elif cg_context.constructor:
suffix = "_Constructor" suffix = "_Constructor"
elif cg_context.exposed_construct:
suffix = "_ConstructorGetter"
elif cg_context.operation: elif cg_context.operation:
suffix = "_Method" suffix = "_Method"
name = cg_context.member_like.extended_attributes.value_of("MeasureAs") name = target.extended_attributes.value_of("MeasureAs")
if name: if name:
name = "k{}".format(name) name = "k{}".format(name)
elif cg_context.constructor: elif cg_context.constructor:
...@@ -979,8 +986,7 @@ def make_report_measure_as(cg_context): ...@@ -979,8 +986,7 @@ def make_report_measure_as(cg_context):
else: else:
name = "kV8{}_{}{}".format( name = "kV8{}_{}{}".format(
cg_context.class_like.identifier, cg_context.class_like.identifier,
name_style.raw.upper_camel_case(cg_context.member_like.identifier), name_style.raw.upper_camel_case(target.identifier), suffix)
suffix)
node = SequenceNode() node = SequenceNode()
...@@ -1062,22 +1068,30 @@ def make_return_value_cache_update_value(cg_context): ...@@ -1062,22 +1068,30 @@ def make_return_value_cache_update_value(cg_context):
def make_runtime_call_timer_scope(cg_context): def make_runtime_call_timer_scope(cg_context):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
pattern = "RUNTIME_CALL_TIMER_SCOPE{_1}(${isolate}, {_2});" target = cg_context.member_like or cg_context.property_
_1 = "_DISABLED_BY_DEFAULT"
suffix = "" suffix = ""
if cg_context.attribute_get: if cg_context.attribute_get:
suffix = "_Getter" suffix = "_Getter"
elif cg_context.attribute_set: elif cg_context.attribute_set:
suffix = "_Setter" suffix = "_Setter"
counter = cg_context.member_like.extended_attributes.value_of( elif cg_context.exposed_construct:
"RuntimeCallStatsCounter") suffix = "_ConstructorGetterCallback"
counter = target.extended_attributes.value_of("RuntimeCallStatsCounter")
if counter: if counter:
_2 = "k{}{}".format(counter, suffix) macro_name = "RUNTIME_CALL_TIMER_SCOPE"
counter_name = "k{}{}".format(counter, suffix)
else: else:
_2 = "\"Blink_{}_{}{}\"".format( macro_name = "RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT"
blink_class_name(cg_context.class_like), counter_name = "\"Blink_{}_{}{}\"".format(
cg_context.member_like.identifier, suffix) blink_class_name(cg_context.class_like), target.identifier, suffix)
node = TextNode(_format(pattern, _1=_1, _2=_2))
node = TextNode(
_format(
"{macro_name}(${isolate}, {counter_name})",
macro_name=macro_name,
counter_name=counter_name))
node.accumulate( node.accumulate(
CodeGenAccumulator.require_include_headers([ CodeGenAccumulator.require_include_headers([
"third_party/blink/renderer/platform/bindings/runtime_call_stats.h", "third_party/blink/renderer/platform/bindings/runtime_call_stats.h",
...@@ -1394,6 +1408,34 @@ def make_constructor_callback_def(cg_context, function_name): ...@@ -1394,6 +1408,34 @@ def make_constructor_callback_def(cg_context, function_name):
return node return node
def make_exposed_construct_callback_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str)
func_def = _make_empty_callback_def(
cg_context,
function_name,
arg_decls=[
"v8::Local<v8::Name> property",
"const v8::PropertyCallbackInfo<v8::Value>& info",
])
body = func_def.body
v8_set_return_value = _format(
"V8SetReturnValueInterfaceObject(${info}, {}::GetWrapperTypeInfo());",
v8_bridge_class_name(cg_context.exposed_construct))
body.extend([
make_runtime_call_timer_scope(cg_context),
make_report_deprecate_as(cg_context),
make_report_measure_as(cg_context),
make_log_activity(cg_context),
TextNode(""),
TextNode(v8_set_return_value),
])
return func_def
def make_operation_function_def(cg_context, function_name): def make_operation_function_def(cg_context, function_name):
assert isinstance(cg_context, CodeGenContext) assert isinstance(cg_context, CodeGenContext)
assert isinstance(function_name, str) assert isinstance(function_name, str)
...@@ -1690,6 +1732,44 @@ def _make_constant_value_registration_table(table_name, constant_entries): ...@@ -1690,6 +1732,44 @@ def _make_constant_value_registration_table(table_name, constant_entries):
]) ])
def _make_exposed_construct_registration_table(table_name,
exposed_construct_entries):
assert isinstance(table_name, str)
assert isinstance(exposed_construct_entries, (list, tuple))
assert all(
isinstance(entry, _PropEntryExposedConstruct)
for entry in exposed_construct_entries)
T = TextNode
entry_nodes = []
for entry in exposed_construct_entries:
pattern = ("{{"
"\"{property_name}\", "
"{exposed_construct_callback}, "
"nullptr, "
"static_cast<v8::PropertyAttribute>(v8::DontEnum), "
"V8DOMConfiguration::kOnInstance, "
"V8DOMConfiguration::kDoNotCheckHolder, "
"V8DOMConfiguration::kHasNoSideEffect, "
"V8DOMConfiguration::kAlwaysCallGetter, "
"{world}"
"}}, ")
text = _format(
pattern,
property_name=entry.member.identifier,
exposed_construct_callback=entry.prop_callback_name,
world=_make_property_entry_world(entry.world))
entry_nodes.append(T(text))
return ListNode([
T("static constexpr V8DOMConfiguration::AttributeConfiguration " +
table_name + "[] = {"),
ListNode(entry_nodes),
T("};"),
])
def _make_operation_registration_table(table_name, operation_entries): def _make_operation_registration_table(table_name, operation_entries):
assert isinstance(table_name, str) assert isinstance(table_name, str)
assert isinstance(operation_entries, (list, tuple)) assert isinstance(operation_entries, (list, tuple))
...@@ -1785,6 +1865,17 @@ class _PropEntryConstructorGroup(_PropEntryMember): ...@@ -1785,6 +1865,17 @@ class _PropEntryConstructorGroup(_PropEntryMember):
self.ctor_func_length = ctor_func_length self.ctor_func_length = ctor_func_length
class _PropEntryExposedConstruct(_PropEntryMember):
def __init__(self, is_context_dependent, exposure_conditional, world,
exposed_construct, prop_callback_name):
assert isinstance(prop_callback_name, str)
_PropEntryMember.__init__(self, is_context_dependent,
exposure_conditional, world,
exposed_construct)
self.prop_callback_name = prop_callback_name
class _PropEntryOperationGroup(_PropEntryMember): class _PropEntryOperationGroup(_PropEntryMember):
def __init__(self, is_context_dependent, exposure_conditional, world, def __init__(self, is_context_dependent, exposure_conditional, world,
operation_group, op_callback_name, op_func_length): operation_group, op_callback_name, op_func_length):
...@@ -1800,7 +1891,7 @@ class _PropEntryOperationGroup(_PropEntryMember): ...@@ -1800,7 +1891,7 @@ class _PropEntryOperationGroup(_PropEntryMember):
def _make_property_entries_and_callback_defs( def _make_property_entries_and_callback_defs(
cg_context, attribute_entries, constant_entries, constructor_entries, cg_context, attribute_entries, constant_entries, constructor_entries,
operation_entries): exposed_construct_entries, operation_entries):
""" """
Creates intermediate objects to help property installation and also makes Creates intermediate objects to help property installation and also makes
code nodes of callback functions. code nodes of callback functions.
...@@ -1808,6 +1899,7 @@ def _make_property_entries_and_callback_defs( ...@@ -1808,6 +1899,7 @@ def _make_property_entries_and_callback_defs(
Args: Args:
attribute_entries: attribute_entries:
constructor_entries: constructor_entries:
exposed_construct_entries:
operation_entries: operation_entries:
Output parameters to store the intermediate objects. Output parameters to store the intermediate objects.
""" """
...@@ -1815,6 +1907,7 @@ def _make_property_entries_and_callback_defs( ...@@ -1815,6 +1907,7 @@ def _make_property_entries_and_callback_defs(
assert isinstance(attribute_entries, list) assert isinstance(attribute_entries, list)
assert isinstance(constant_entries, list) assert isinstance(constant_entries, list)
assert isinstance(constructor_entries, list) assert isinstance(constructor_entries, list)
assert isinstance(exposed_construct_entries, list)
assert isinstance(operation_entries, list) assert isinstance(operation_entries, list)
interface = cg_context.interface interface = cg_context.interface
...@@ -1824,7 +1917,8 @@ def _make_property_entries_and_callback_defs( ...@@ -1824,7 +1917,8 @@ def _make_property_entries_and_callback_defs(
def iterate(members, callback): def iterate(members, callback):
for member in members: for member in members:
is_context_dependent = member.exposure.is_context_dependent is_context_dependent = member.exposure.is_context_dependent(
global_names)
exposure_conditional = expr_from_exposure(member.exposure, exposure_conditional = expr_from_exposure(member.exposure,
global_names) global_names)
...@@ -1916,6 +2010,27 @@ def _make_property_entries_and_callback_defs( ...@@ -1916,6 +2010,27 @@ def _make_property_entries_and_callback_defs(
ctor_func_length=( ctor_func_length=(
constructor_group.min_num_of_required_arguments))) constructor_group.min_num_of_required_arguments)))
def process_exposed_construct(exposed_construct, is_context_dependent,
exposure_conditional, world):
cgc = cg_context.make_copy(
exposed_construct=exposed_construct, for_world=world)
prop_callback_name = callback_function_name(cgc)
prop_callback_node = make_exposed_construct_callback_def(
cgc, prop_callback_name)
callback_def_nodes.extend([
prop_callback_node,
TextNode(""),
])
exposed_construct_entries.append(
_PropEntryExposedConstruct(
is_context_dependent=is_context_dependent,
exposure_conditional=exposure_conditional,
world=world,
exposed_construct=exposed_construct,
prop_callback_name=prop_callback_name))
def process_operation_group(operation_group, is_context_dependent, def process_operation_group(operation_group, is_context_dependent,
exposure_conditional, world): exposure_conditional, world):
cgc = cg_context.make_copy( cgc = cg_context.make_copy(
...@@ -1940,6 +2055,7 @@ def _make_property_entries_and_callback_defs( ...@@ -1940,6 +2055,7 @@ def _make_property_entries_and_callback_defs(
iterate(interface.attributes, process_attribute) iterate(interface.attributes, process_attribute)
iterate(interface.constants, process_constant) iterate(interface.constants, process_constant)
iterate(interface.constructor_groups, process_constructor_group) iterate(interface.constructor_groups, process_constructor_group)
iterate(interface.exposed_constructs, process_exposed_construct)
iterate(interface.operation_groups, process_operation_group) iterate(interface.operation_groups, process_operation_group)
return callback_def_nodes return callback_def_nodes
...@@ -2068,7 +2184,7 @@ def make_install_interface_template(cg_context, function_name, class_name, ...@@ -2068,7 +2184,7 @@ def make_install_interface_template(cg_context, function_name, class_name,
def make_install_properties(cg_context, function_name, class_name, def make_install_properties(cg_context, function_name, class_name,
trampoline_var_name, is_context_dependent, trampoline_var_name, is_context_dependent,
attribute_entries, constant_entries, attribute_entries, constant_entries,
operation_entries): exposed_construct_entries, operation_entries):
""" """
Returns: Returns:
A triplet of CodeNode of: A triplet of CodeNode of:
...@@ -2088,12 +2204,17 @@ def make_install_properties(cg_context, function_name, class_name, ...@@ -2088,12 +2204,17 @@ def make_install_properties(cg_context, function_name, class_name,
assert isinstance(constant_entries, (list, tuple)) assert isinstance(constant_entries, (list, tuple))
assert all( assert all(
isinstance(entry, _PropEntryConstant) for entry in constant_entries) isinstance(entry, _PropEntryConstant) for entry in constant_entries)
assert isinstance(exposed_construct_entries, (list, tuple))
assert all(
isinstance(entry, _PropEntryExposedConstruct)
for entry in exposed_construct_entries)
assert isinstance(operation_entries, (list, tuple)) assert isinstance(operation_entries, (list, tuple))
assert all( assert all(
isinstance(entry, _PropEntryOperationGroup) isinstance(entry, _PropEntryOperationGroup)
for entry in operation_entries) for entry in operation_entries)
if not (attribute_entries or constant_entries or operation_entries): if not (attribute_entries or constant_entries or exposed_construct_entries
or operation_entries):
return None, None, None return None, None, None
if is_context_dependent: if is_context_dependent:
...@@ -2258,6 +2379,21 @@ def make_install_properties(cg_context, function_name, class_name, ...@@ -2258,6 +2379,21 @@ def make_install_properties(cg_context, function_name, class_name,
_make_constant_value_registration_table, _make_constant_value_registration_table,
installer_call_text) installer_call_text)
table_name = "kExposedConstructTable"
if is_context_dependent:
installer_call_text = (
"V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
"${instance_object}, ${prototype_object}, "
"kExposedConstructTable, base::size(kExposedConstructTable));")
else:
installer_call_text = (
"V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, "
"${instance_template}, ${prototype_template}, "
"kExposedConstructTable, base::size(kExposedConstructTable));")
install_properties(table_name, exposed_construct_entries,
_make_exposed_construct_registration_table,
installer_call_text)
table_name = "kOperationTable" table_name = "kOperationTable"
if is_context_dependent: if is_context_dependent:
installer_call_text = ( installer_call_text = (
...@@ -2340,7 +2476,7 @@ def generate_interface(interface): ...@@ -2340,7 +2476,7 @@ def generate_interface(interface):
is_cross_components = path_manager.is_cross_components is_cross_components = path_manager.is_cross_components
# Class names # Class names
api_class_name = name_style.class_("v8", interface.identifier) api_class_name = v8_bridge_class_name(interface)
if is_cross_components: if is_cross_components:
impl_class_name = name_style.class_(api_class_name, "impl") impl_class_name = name_style.class_(api_class_name, "impl")
else: else:
...@@ -2437,12 +2573,14 @@ def generate_interface(interface): ...@@ -2437,12 +2573,14 @@ def generate_interface(interface):
attribute_entries = [] attribute_entries = []
constant_entries = [] constant_entries = []
constructor_entries = [] constructor_entries = []
exposed_construct_entries = []
operation_entries = [] operation_entries = []
callback_defs = _make_property_entries_and_callback_defs( callback_defs = _make_property_entries_and_callback_defs(
cg_context, cg_context,
attribute_entries=attribute_entries, attribute_entries=attribute_entries,
constant_entries=constant_entries, constant_entries=constant_entries,
constructor_entries=constructor_entries, constructor_entries=constructor_entries,
exposed_construct_entries=exposed_construct_entries,
operation_entries=operation_entries) operation_entries=operation_entries)
# Installer functions # Installer functions
...@@ -2459,6 +2597,8 @@ def generate_interface(interface): ...@@ -2459,6 +2597,8 @@ def generate_interface(interface):
is_context_dependent=False, is_context_dependent=False,
attribute_entries=filter(is_unconditional, attribute_entries), attribute_entries=filter(is_unconditional, attribute_entries),
constant_entries=filter(is_unconditional, constant_entries), constant_entries=filter(is_unconditional, constant_entries),
exposed_construct_entries=filter(is_unconditional,
exposed_construct_entries),
operation_entries=filter(is_unconditional, operation_entries)) operation_entries=filter(is_unconditional, operation_entries))
(install_context_independent_props_decl, (install_context_independent_props_decl,
install_context_independent_props_def, install_context_independent_props_def,
...@@ -2470,6 +2610,8 @@ def generate_interface(interface): ...@@ -2470,6 +2610,8 @@ def generate_interface(interface):
is_context_dependent=False, is_context_dependent=False,
attribute_entries=filter(is_context_independent, attribute_entries), attribute_entries=filter(is_context_independent, attribute_entries),
constant_entries=filter(is_context_independent, constant_entries), constant_entries=filter(is_context_independent, constant_entries),
exposed_construct_entries=filter(is_context_independent,
exposed_construct_entries),
operation_entries=filter(is_context_independent, operation_entries)) operation_entries=filter(is_context_independent, operation_entries))
(install_context_dependent_props_decl, install_context_dependent_props_def, (install_context_dependent_props_decl, install_context_dependent_props_def,
install_context_dependent_props_trampoline) = make_install_properties( install_context_dependent_props_trampoline) = make_install_properties(
...@@ -2480,6 +2622,8 @@ def generate_interface(interface): ...@@ -2480,6 +2622,8 @@ def generate_interface(interface):
is_context_dependent=True, is_context_dependent=True,
attribute_entries=filter(is_context_dependent, attribute_entries), attribute_entries=filter(is_context_dependent, attribute_entries),
constant_entries=filter(is_context_dependent, constant_entries), constant_entries=filter(is_context_dependent, constant_entries),
exposed_construct_entries=filter(is_context_dependent,
exposed_construct_entries),
operation_entries=filter(is_context_dependent, operation_entries)) operation_entries=filter(is_context_dependent, operation_entries))
(install_interface_template_decl, install_interface_template_def, (install_interface_template_decl, install_interface_template_def,
install_interface_template_trampoline) = make_install_interface_template( install_interface_template_trampoline) = make_install_interface_template(
...@@ -2620,5 +2764,5 @@ def generate_interface(interface): ...@@ -2620,5 +2764,5 @@ def generate_interface(interface):
def generate_interfaces(web_idl_database): def generate_interfaces(web_idl_database):
interface = web_idl_database.find("Node") interface = web_idl_database.find("Window")
generate_interface(interface) generate_interface(interface)
...@@ -5,13 +5,29 @@ ...@@ -5,13 +5,29 @@
from .runtime_enabled_features import RuntimeEnabledFeatures from .runtime_enabled_features import RuntimeEnabledFeatures
class _Feature(str):
"""Represents a runtime-enabled feature."""
def __init__(self, value):
str.__init__(self, value)
self._is_context_dependent = (
RuntimeEnabledFeatures.is_context_dependent(self))
@property
def is_context_dependent(self):
return self._is_context_dependent
class _GlobalNameAndFeature(object): class _GlobalNameAndFeature(object):
def __init__(self, global_name, feature=None): def __init__(self, global_name, feature=None):
assert isinstance(global_name, str) assert isinstance(global_name, str)
assert feature is None or isinstance(feature, str) assert feature is None or isinstance(feature, str)
self._global_name = global_name self._global_name = global_name
self._feature = feature if feature is None:
self._feature = None
else:
self._feature = _Feature(feature)
@property @property
def global_name(self): def global_name(self):
...@@ -23,6 +39,8 @@ class _GlobalNameAndFeature(object): ...@@ -23,6 +39,8 @@ class _GlobalNameAndFeature(object):
class Exposure(object): class Exposure(object):
"""Represents a set of conditions under which the construct is exposed."""
def __init__(self, other=None): def __init__(self, other=None):
assert other is None or isinstance(other, Exposure) assert other is None or isinstance(other, Exposure)
...@@ -94,15 +112,33 @@ class Exposure(object): ...@@ -94,15 +112,33 @@ class Exposure(object):
return False return False
return self._only_in_secure_contexts return self._only_in_secure_contexts
@property def is_context_dependent(self, global_names=None):
def is_context_dependent(self):
""" """
Returns True if the exposure of this construct depends on a context. Returns True if the exposure of this construct depends on a context.
Args:
global_names: When specified, it's taken into account that the
global object implements |global_names|.
""" """
return bool(self.global_names_and_features assert (global_names is None
or self.context_dependent_runtime_enabled_features or (isinstance(global_names, (list, tuple))
or self.context_enabled_features and all(isinstance(name, str) for name in global_names)))
or self.only_in_secure_contexts)
if (self.context_dependent_runtime_enabled_features
or self.context_enabled_features
or self.only_in_secure_contexts):
return True
if not global_names:
return bool(self.global_names_and_features)
is_context_dependent = False
for entry in self.global_names_and_features:
if entry.global_name not in global_names:
continue
if entry.feature and entry.feature.is_context_dependent:
is_context_dependent = True
return is_context_dependent
class ExposureMutable(Exposure): class ExposureMutable(Exposure):
...@@ -128,11 +164,12 @@ class ExposureMutable(Exposure): ...@@ -128,11 +164,12 @@ class ExposureMutable(Exposure):
def add_runtime_enabled_feature(self, name): def add_runtime_enabled_feature(self, name):
assert isinstance(name, str) assert isinstance(name, str)
if RuntimeEnabledFeatures.is_context_dependent(name): feature = _Feature(name)
self._context_dependent_runtime_enabled_features.append(name) if feature.is_context_dependent:
self._context_dependent_runtime_enabled_features.append(feature)
else: else:
self._context_independent_runtime_enabled_features.append(name) self._context_independent_runtime_enabled_features.append(feature)
self._runtime_enabled_features.append(name) self._runtime_enabled_features.append(feature)
def add_context_enabled_feature(self, name): def add_context_enabled_feature(self, name):
assert isinstance(name, str) assert isinstance(name, str)
...@@ -146,6 +183,6 @@ class ExposureMutable(Exposure): ...@@ -146,6 +183,6 @@ class ExposureMutable(Exposure):
if isinstance(value, bool): if isinstance(value, bool):
self._only_in_secure_contexts = value self._only_in_secure_contexts = value
elif isinstance(value, str): elif isinstance(value, str):
self._only_in_secure_contexts = (value, ) self._only_in_secure_contexts = (_Feature(value), )
else: else:
self._only_in_secure_contexts = tuple(value) self._only_in_secure_contexts = tuple(map(_Feature, value))
...@@ -280,5 +280,11 @@ class ExtendedAttributes(object): ...@@ -280,5 +280,11 @@ class ExtendedAttributes(object):
class ExtendedAttributesMutable(ExtendedAttributes): class ExtendedAttributesMutable(ExtendedAttributes):
def __getstate__(self):
assert False, "ExtendedAttributesMutable must not be pickled."
def __setstate__(self, state):
assert False, "ExtendedAttributesMutable must not be pickled."
def append(self, ext_attr): def append(self, ext_attr):
self._append(ext_attr) self._append(ext_attr)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment