def dictionary_context(dictionary, interfaces_info): includes.clear() includes.update(DICTIONARY_CPP_INCLUDES) members = [member_context(dictionary, member) for member in sorted(dictionary.members, key=operator.attrgetter('name'))] for member in members: if member['runtime_enabled_function']: includes.add('platform/RuntimeEnabledFeatures.h') break cpp_class = v8_utilities.cpp_name(dictionary) context = { 'cpp_class': cpp_class, 'header_includes': set(DICTIONARY_H_INCLUDES), 'members': members, 'required_member_names': sorted([member.name for member in dictionary.members if member.is_required]), 'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in dictionary.extended_attributes, 'v8_class': v8_types.v8_type(cpp_class), 'v8_original_class': v8_types.v8_type(dictionary.name), } if dictionary.parent: IdlType(dictionary.parent).add_includes_for_type() parent_cpp_class = v8_utilities.cpp_name_from_interfaces_info( dictionary.parent, interfaces_info) context.update({ 'parent_cpp_class': parent_cpp_class, 'parent_v8_class': v8_types.v8_type(parent_cpp_class), }) return context
def setter_expression(interface, attribute, contents): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments(attribute, extended_attributes.get('SetterCallWith')) this_setter_base_name = setter_base_name(attribute, arguments) setter_name = v8_utilities.scoped_name(interface, attribute, this_setter_base_name) if ('ImplementedBy' in extended_attributes and not attribute.is_static): arguments.append('imp') idl_type = attribute.idl_type if idl_type == 'EventHandler': getter_name = v8_utilities.scoped_name(interface, attribute, cpp_name(attribute)) contents['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') arguments.append('V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(jsValue, true, info.GetIsolate())') else: arguments.append('V8EventListenerList::getEventListener(jsValue, true, ListenerFindOrCreate)') elif v8_types.is_interface_type(idl_type) and not v8_types.array_type(idl_type): # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append('WTF::getPtr(cppValue)') else: arguments.append('cppValue') if contents['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def setter_expression(interface, attribute, contents): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments(attribute, extended_attributes.get('SetterCallWith')) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ('PartialInterfaceImplementedAs' in extended_attributes and not attribute.is_static): arguments.append('*impl') idl_type = attribute.idl_type if idl_type.base_type == 'EventHandler': getter_name = scoped_name(interface, attribute, cpp_name(attribute)) contents['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') arguments.append('V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(v8Value, true, info.GetIsolate())') else: arguments.append('V8EventListenerList::getEventListener(v8Value, true, ListenerFindOrCreate)') elif idl_type.is_interface_type and not idl_type.array_type: # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append('WTF::getPtr(cppValue)') else: arguments.append('cppValue') if contents['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def origin_trial_enabled_function_name(definition_or_member, interface): """Returns the name of the OriginTrials enabled function. An exception is raised if both the OriginTrialEnabled and RuntimeEnabled extended attributes are applied to the same IDL member. Only one of the two attributes can be applied to any member - they are mutually exclusive. The returned function checks if the IDL member should be enabled. Given extended attribute OriginTrialEnabled=FeatureName, return: OriginTrials::{featureName}Enabled If the OriginTrialEnabled extended attribute is found, the includes are also updated as a side-effect. """ extended_attributes = definition_or_member.extended_attributes is_origin_trial_enabled = 'OriginTrialEnabled' in extended_attributes if (is_origin_trial_enabled and 'RuntimeEnabled' in extended_attributes): raise Exception('[OriginTrialEnabled] and [RuntimeEnabled] must ' 'not be specified on the same definition: ' '%s.%s' % (definition_or_member.idl_name, definition_or_member.name)) if is_origin_trial_enabled: includes.add('core/inspector/ConsoleMessage.h') includes.add('core/origin_trials/OriginTrials.h') trial_name = extended_attributes['OriginTrialEnabled'] return 'OriginTrials::%sEnabled' % uncapitalize(trial_name) return None
def generate_getter(interface, attribute, contents): idl_type = attribute.idl_type extended_attributes = attribute.extended_attributes cpp_value = getter_expression(interface, attribute, contents) # Normally we can inline the function call into the return statement to # avoid the overhead of using a Ref<> temporary, but for some cases # (nullable types, EventHandler, [CachedAttribute], or if there are # exceptions), we need to use a local variable. # FIXME: check if compilers are smart enough to inline this, and if so, # always use a local variable (for readability and CG simplicity). if (attribute.is_nullable or idl_type == 'EventHandler' or 'CachedAttribute' in extended_attributes or contents['is_getter_raises_exception']): contents['cpp_value_original'] = cpp_value cpp_value = 'jsValue' if contents['is_keep_alive_for_gc']: v8_set_return_value_statement = 'v8SetReturnValue(info, wrapper)' includes.add('bindings/v8/V8HiddenPropertyName.h') else: v8_set_return_value_statement = v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp') contents.update({ 'cpp_value': cpp_value, 'v8_set_return_value': v8_set_return_value_statement, })
def scoped_content_attribute_name(interface, attribute): content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower() if interface.name.startswith('SVG'): namespace = 'SVGNames' else: namespace = 'HTMLNames' includes.add('core/%s.h' % namespace) return '%s::%sAttr' % (namespace, content_attribute_name)
def scoped_content_attribute_name(interface, attribute): content_attribute_name = attribute.extended_attributes["Reflect"] or attribute.name.lower() if interface.name.startswith("SVG"): namespace = "SVGNames" else: namespace = "HTMLNames" includes.add("core/%s.h" % namespace) return "%s::%sAttr" % (namespace, content_attribute_name)
def runtime_call_stats_context(interface, method): includes.add('platform/bindings/RuntimeCallStats.h') generic_counter_name = 'Blink_' + v8_utilities.cpp_name(interface) + '_' + method.name (method_counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(method, generic_counter_name) return { 'extended_attribute_defined': extended_attribute_defined, 'method_counter': method_counter, 'origin_safe_method_getter_counter': generic_counter_name + '_OriginSafeMethodGetter' }
def method_context(interface, method): context = v8_methods.method_context(interface, method) arguments = method.arguments extended_attributes = method.extended_attributes idl_type = method.idl_type # idl_type.add_includes_for_type() this_cpp_value = cpp_value(interface, method, len(arguments)) if context['is_call_with_script_state']: includes.add('bindings/core/dart/DartScriptState.h') if idl_type.union_arguments and len(idl_type.union_arguments) > 0: this_cpp_type = [] for cpp_type in idl_type.member_types: this_cpp_type.append("RefPtr<%s>" % cpp_type) else: this_cpp_type = idl_type.cpp_type is_auto_scope = not 'DartNoAutoScope' in extended_attributes arguments_data = [argument_context(interface, method, argument, index) for index, argument in enumerate(arguments)] union_arguments = [] if idl_type.union_arguments: union_arguments.extend([union_arg['cpp_value'] for union_arg in idl_type.union_arguments]) is_custom = 'Custom' in extended_attributes or 'DartCustom' in extended_attributes context.update({ 'arguments': arguments_data, 'cpp_type': this_cpp_type, 'cpp_value': this_cpp_value, 'dart_type': dart_types.idl_type_to_dart_type(idl_type), 'dart_name': extended_attributes.get('DartName'), 'has_exception_state': context['is_raises_exception'] or any(argument for argument in arguments if argument.idl_type.name == 'SerializedScriptValue' or argument.idl_type.is_integer_type), 'is_auto_scope': is_auto_scope, 'auto_scope': DartUtilities.bool_to_cpp(is_auto_scope), 'is_custom': is_custom, 'is_custom_dart': 'DartCustom' in extended_attributes, 'is_custom_dart_new': DartUtilities.has_extended_attribute_value(method, 'DartCustom', 'New'), # FIXME(terry): DartStrictTypeChecking no longer supported; TypeChecking is # new extended attribute. 'is_strict_type_checking': 'DartStrictTypeChecking' in extended_attributes or 'DartStrictTypeChecking' in interface.extended_attributes, 'union_arguments': union_arguments, 'dart_set_return_value': dart_set_return_value(interface.name, method, this_cpp_value), }) return context
def scoped_content_attribute_name(interface, attribute): content_attribute_name = attribute.extended_attributes[ 'Reflect'] or attribute.name.lower() symbol_name = 'k' + NameStyleConverter( content_attribute_name).to_upper_camel_case() if interface.name.startswith('SVG'): namespace = 'svg_names' includes.add('core/svg_names.h') else: namespace = 'html_names' includes.add('core/html_names.h') return '%s::%sAttr' % (namespace, symbol_name)
def measure_as(definition_or_member, interface): extended_attributes = definition_or_member.extended_attributes if 'MeasureAs' in extended_attributes: includes.add('core/frame/UseCounter.h') return lambda suffix: extended_attributes['MeasureAs'] if 'Measure' in extended_attributes: includes.add('core/frame/UseCounter.h') measure_as_name = capitalize(definition_or_member.name) if interface is not None: measure_as_name = '%s_%s' % (capitalize(interface.name), measure_as_name) return lambda suffix: 'V8%s_%s' % (measure_as_name, suffix) return None
def measure_as(definition_or_member, interface): extended_attributes = definition_or_member.extended_attributes if "MeasureAs" in extended_attributes: includes.add("core/frame/UseCounter.h") return lambda suffix: extended_attributes["MeasureAs"] if "Measure" in extended_attributes: includes.add("core/frame/UseCounter.h") measure_as_name = capitalize(definition_or_member.name) if interface is not None: measure_as_name = "%s_%s" % (capitalize(interface.name), measure_as_name) return lambda suffix: "V8%s_%s" % (measure_as_name, suffix) return None
def runtime_call_stats_context(interface, attribute, context): includes.add('platform/bindings/runtime_call_stats.h') generic_counter_name = 'Blink_' + v8_utilities.cpp_name(interface) + '_' + attribute.name (counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(attribute, generic_counter_name) runtime_call_stats = { 'extended_attribute_defined': extended_attribute_defined, 'getter_counter': '%s_Getter' % counter, 'setter_counter': '%s_Setter' % counter, 'constructor_getter_callback_counter': '%s_ConstructorGetterCallback' % generic_counter_name, } context.update({ 'runtime_call_stats': runtime_call_stats })
def high_entropy(definition_or_member): extended_attributes = definition_or_member.extended_attributes if 'HighEntropy' in extended_attributes: includes.add('core/frame/dactyloscoper.h') if not ('Measure' in extended_attributes or 'MeasureAs' in extended_attributes): raise Exception( '%s specified [HighEntropy], but does not include ' 'either [Measure] or [MeasureAs]' % definition_or_member.name) if extended_attributes['HighEntropy'] == 'Direct': return 'Direct' return True return False
def runtime_call_stats_context(interface, attribute, context): includes.add('platform/bindings/RuntimeCallStats.h') generic_counter_name = 'Blink_' + v8_utilities.cpp_name(interface) + '_' + attribute.name (counter, extended_attribute_defined) = v8_utilities.rcs_counter_name(attribute, generic_counter_name) runtime_call_stats = { 'extended_attribute_defined': extended_attribute_defined, 'getter_counter': '%s_Getter' % counter, 'setter_counter': '%s_Setter' % counter, 'constructor_getter_callback_counter': '%s_ConstructorGetterCallback' % generic_counter_name, } context.update({ 'runtime_call_stats': runtime_call_stats })
def scoped_content_attribute_name(interface, attribute): content_attribute_name = attribute.extended_attributes['Reflect'] or attribute.name.lower() if interface.name.startswith('SVG'): # SVG's xmlbase/xmlspace/xmllang need special behavior, i.e. # it is in XMLNames namespace and the generated attribute has no xml prefix. if attribute.name.startswith('xml'): namespace = 'XMLNames' content_attribute_name = content_attribute_name[3:] else: namespace = 'SVGNames' else: namespace = 'HTMLNames' includes.add('core/%s.h' % namespace) return '%s::%sAttr' % (namespace, content_attribute_name)
def scoped_content_attribute_name(interface, attribute): content_attribute_name = attribute.extended_attributes["Reflect"] or attribute.name.lower() if interface.name.startswith("SVG"): # SVG's xmlbase/xmlspace/xmllang need special behavior, i.e. # it is in XMLNames namespace and the generated attribute has no xml prefix. if attribute.name.startswith("xml"): namespace = "XMLNames" content_attribute_name = content_attribute_name[3:] else: namespace = "SVGNames" else: namespace = "HTMLNames" includes.add("core/%s.h" % namespace) return "%s::%sAttr" % (namespace, content_attribute_name)
def runtime_call_stats_context(interface, method): includes.add('platform/bindings/runtime_call_stats.h') generic_counter_name = ('Blink_' + v8_utilities.cpp_name(interface) + '_' + method.name) (method_counter, extended_attribute_defined) = \ v8_utilities.rcs_counter_name(method, generic_counter_name) trace_event_name = interface.name + '.' + method.name return { 'extended_attribute_defined': extended_attribute_defined, 'method_counter': method_counter, 'origin_safe_method_getter_counter': generic_counter_name + '_OriginSafeMethodGetter', 'trace_event_name': trace_event_name, }
def v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index): # Index is None for setters, index (starting at 0) for method arguments, # and is used to provide a human-readable exception message if index is None: index = 0 # special case, meaning "setter" else: index += 1 # human-readable index if is_interface_type(this_array_or_sequence_type): this_cpp_type = None expression_format = '(toRefPtrNativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))' includes.add('V8%s.h' % this_array_or_sequence_type) else: this_cpp_type = cpp_type(this_array_or_sequence_type) expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())' expression = expression_format.format(array_or_sequence_type=this_array_or_sequence_type, cpp_type=this_cpp_type, index=index, v8_value=v8_value) return expression
def activity_logging_world_list(member, access_type=''): """Returns a set of world suffixes for which a definition member has activity logging, for specified access type. access_type can be 'Getter' or 'Setter' if only checking getting or setting. """ extended_attributes = member.extended_attributes if 'LogActivity' not in extended_attributes: return set() log_activity = extended_attributes['LogActivity'] if log_activity and not log_activity.startswith(access_type): return set() includes.add('bindings/core/v8/V8DOMActivityLogger.h') if 'LogAllWorlds' in extended_attributes: return set(['', 'ForMainWorld']) return set(['']) # At minimum, include isolated worlds.
def dictionary_context(dictionary, interfaces_info): includes.clear() includes.update(DICTIONARY_CPP_INCLUDES) if 'RuntimeEnabled' in dictionary.extended_attributes: raise Exception('Dictionary cannot be RuntimeEnabled: %s' % dictionary.name) members = [ member_context(dictionary, member) for member in sorted(dictionary.members, key=operator.attrgetter('name')) ] for member in members: if member['runtime_enabled_function']: includes.add('platform/RuntimeEnabledFeatures.h') break cpp_class = v8_utilities.cpp_name(dictionary) context = { 'cpp_class': cpp_class, 'header_includes': set(DICTIONARY_H_INCLUDES), 'members': members, 'required_member_names': sorted([ member.name for member in dictionary.members if member.is_required ]), 'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in dictionary.extended_attributes, 'v8_class': v8_types.v8_type(cpp_class), 'v8_original_class': v8_types.v8_type(dictionary.name), } if dictionary.parent: IdlType(dictionary.parent).add_includes_for_type() parent_cpp_class = v8_utilities.cpp_name_from_interfaces_info( dictionary.parent, interfaces_info) context.update({ 'parent_cpp_class': parent_cpp_class, 'parent_v8_class': v8_types.v8_type(parent_cpp_class), }) return context
def origin_trial_enabled_function_name(definition_or_member): """Returns the name of the OriginTrials enabled function. An exception is raised if OriginTrialEnabled is used in conjunction with any of the following (which must be mutually exclusive with origin trials): - RuntimeEnabled The returned function checks if the IDL member should be enabled. Given extended attribute OriginTrialEnabled=FeatureName, return: OriginTrials::{featureName}Enabled If the OriginTrialEnabled extended attribute is found, the includes are also updated as a side-effect. """ extended_attributes = definition_or_member.extended_attributes is_origin_trial_enabled = 'OriginTrialEnabled' in extended_attributes if is_origin_trial_enabled and 'RuntimeEnabled' in extended_attributes: raise Exception('[OriginTrialEnabled] and [RuntimeEnabled] must ' 'not be specified on the same definition: %s' % definition_or_member.name) if is_origin_trial_enabled: trial_name = extended_attributes['OriginTrialEnabled'] return 'OriginTrials::%sEnabled' % uncapitalize(trial_name) is_feature_policy_enabled = 'FeaturePolicy' in extended_attributes if is_feature_policy_enabled and 'RuntimeEnabled' in extended_attributes: raise Exception('[FeaturePolicy] and [RuntimeEnabled] must ' 'not be specified on the same definition: %s' % definition_or_member.name) if is_feature_policy_enabled and 'SecureContext' in extended_attributes: raise Exception('[FeaturePolicy] and [SecureContext] must ' 'not be specified on the same definition ' '(see https://crbug.com/695123 for workaround): %s' % definition_or_member.name) if is_feature_policy_enabled: includes.add('platform/bindings/ScriptState.h') includes.add('platform/feature_policy/FeaturePolicy.h') trial_name = extended_attributes['FeaturePolicy'] return 'FeaturePolicy::%sEnabled' % uncapitalize(trial_name) return None
def runtime_enabled_function_name(definition_or_member): """Returns the name of the RuntimeEnabledFeatures function. The returned function checks if a method/attribute is enabled. Given extended attribute RuntimeEnabled=FeatureName, return: RuntimeEnabledFeatures::{featureName}Enabled If the RuntimeEnabled extended attribute is found, the includes are also updated as a side-effect. """ feature_name = runtime_feature_name(definition_or_member) if not feature_name: return includes.add('platform/RuntimeEnabledFeatures.h') return 'RuntimeEnabledFeatures::%sEnabled' % uncapitalize(feature_name)
def setter_expression(interface, attribute, context): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( extended_attributes.get('SetterCallWith') or extended_attributes.get('CallWith')) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ('PartialInterfaceImplementedAs' in extended_attributes and not 'ImplementedInPrivateScript' in extended_attributes and not attribute.is_static): arguments.append('*impl') idl_type = attribute.idl_type if 'ImplementedInPrivateScript' in extended_attributes: arguments.append( 'toLocalFrame(toFrameIfNotDetached(info.GetIsolate()->GetCurrentContext()))' ) arguments.append('impl') arguments.append('cppValue') elif idl_type.base_type == 'EventHandler': getter_name = scoped_name(interface, attribute, cpp_name(attribute)) context['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/V8ErrorHandler.h') arguments.append( 'V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(v8Value, true, ScriptState::current(info.GetIsolate()))' ) else: arguments.append( 'V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), v8Value, true, ListenerFindOrCreate)' ) elif idl_type.is_interface_type: # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append('WTF::getPtr(cppValue)') else: arguments.append('cppValue') if context['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def origin_trial_enabled_function_name(definition_or_member): """Returns the name of the OriginTrials enabled function. An exception is raised if both the OriginTrialEnabled and RuntimeEnabled extended attributes are applied to the same IDL member. Only one of the two attributes can be applied to any member - they are mutually exclusive. The returned function checks if the IDL member should be enabled. Given extended attribute OriginTrialEnabled=FeatureName, return: OriginTrials::{featureName}Enabled If the OriginTrialEnabled extended attribute is found, the includes are also updated as a side-effect. """ extended_attributes = definition_or_member.extended_attributes is_origin_trial_enabled = 'OriginTrialEnabled' in extended_attributes if is_origin_trial_enabled and 'RuntimeEnabled' in extended_attributes: raise Exception( '[OriginTrialEnabled] and [RuntimeEnabled] must ' 'not be specified on the same definition: ' '%s.%s' % (definition_or_member.idl_name, definition_or_member.name)) if is_origin_trial_enabled: trial_name = extended_attributes['OriginTrialEnabled'] return 'OriginTrials::%sEnabled' % uncapitalize(trial_name) is_feature_policy_enabled = 'FeaturePolicy' in extended_attributes if is_feature_policy_enabled and 'RuntimeEnabled' in extended_attributes: raise Exception( '[FeaturePolicy] and [RuntimeEnabled] must ' 'not be specified on the same definition: ' '%s.%s' % (definition_or_member.idl_name, definition_or_member.name)) if is_feature_policy_enabled: includes.add('bindings/core/v8/ScriptState.h') includes.add('platform/feature_policy/FeaturePolicy.h') trial_name = extended_attributes['FeaturePolicy'] return 'FeaturePolicy::%sEnabled' % uncapitalize(trial_name) return None
def origin_trial_enabled_function_name(definition_or_member): """Returns the name of the OriginTrials enabled function. An exception is raised if both the OriginTrialEnabled and RuntimeEnabled extended attributes are applied to the same IDL member. Only one of the two attributes can be applied to any member - they are mutually exclusive. The returned function checks if the IDL member should be enabled. Given extended attribute OriginTrialEnabled=FeatureName, return: OriginTrials::{featureName}Enabled If the OriginTrialEnabled extended attribute is found, the includes are also updated as a side-effect. """ extended_attributes = definition_or_member.extended_attributes is_origin_trial_enabled = "OriginTrialEnabled" in extended_attributes if is_origin_trial_enabled and "RuntimeEnabled" in extended_attributes: raise Exception( "[OriginTrialEnabled] and [RuntimeEnabled] must " "not be specified on the same definition: " "%s.%s" % (definition_or_member.idl_name, definition_or_member.name) ) if is_origin_trial_enabled: trial_name = extended_attributes["OriginTrialEnabled"] return "OriginTrials::%sEnabled" % uncapitalize(trial_name) is_feature_policy_enabled = "FeaturePolicy" in extended_attributes if is_feature_policy_enabled and "RuntimeEnabled" in extended_attributes: raise Exception( "[FeaturePolicy] and [RuntimeEnabled] must " "not be specified on the same definition: " "%s.%s" % (definition_or_member.idl_name, definition_or_member.name) ) if is_feature_policy_enabled: includes.add("bindings/core/v8/ScriptState.h") includes.add("platform/feature_policy/FeaturePolicy.h") trial_name = extended_attributes["FeaturePolicy"] return "FeaturePolicy::%sEnabled" % uncapitalize(trial_name) return None
def generate_setter(interface, attribute, contents): idl_type = attribute.idl_type extended_attributes = attribute.extended_attributes if v8_types.is_interface_type(idl_type) and not v8_types.array_type(idl_type): cpp_value = 'WTF::getPtr(cppValue)' else: cpp_value = 'cppValue' is_reflect = 'Reflect' in extended_attributes if is_reflect: includes.add('core/dom/custom/CustomElementCallbackDispatcher.h') contents.update({ 'cpp_setter': setter_expression(interface, attribute, contents), 'enum_validation_expression': v8_utilities.enum_validation_expression(idl_type), 'has_strict_type_checking': 'StrictTypeChecking' in extended_attributes and v8_types.is_interface_type(idl_type), 'is_reflect': is_reflect, 'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value( idl_type, extended_attributes, 'jsValue', 'cppValue'), })
def activity_logging_world_list(member, access_type=None): """Returns a set of world suffixes for which a definition member has activity logging, for specified access type. access_type can be 'Getter' or 'Setter' if only checking getting or setting. """ if "ActivityLogging" not in member.extended_attributes: return set() activity_logging = member.extended_attributes["ActivityLogging"] # [ActivityLogging=For*] (no prefix, starts with the worlds suffix) means # "log for all use (method)/access (attribute)", otherwise check that value # agrees with specified access_type (Getter/Setter). has_logging = activity_logging.startswith("For") or (access_type and activity_logging.startswith(access_type)) if not has_logging: return set() includes.add("bindings/v8/V8DOMActivityLogger.h") if activity_logging.endswith("ForIsolatedWorlds"): return set([""]) return set(["", "ForMainWorld"]) # endswith('ForAllWorlds')
def render_templates(self, include_paths, header_template, cpp_template, context, component=None): context['code_generator'] = self.generator_name # Add includes for any dependencies for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) cpp_includes = set(context.get('cpp_includes', [])) context['cpp_includes'] = normalize_and_sort_includes(cpp_includes | includes) context['header_includes'] = normalize_and_sort_includes(context['header_includes']) header_text = render_template(header_template, context) cpp_text = render_template(cpp_template, context) return header_text, cpp_text
def setter_expression(interface, attribute, context): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( extended_attributes.get("SetterCallWith") or extended_attributes.get("CallWith") ) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ( "PartialInterfaceImplementedAs" in extended_attributes and not "ImplementedInPrivateScript" in extended_attributes and not attribute.is_static ): arguments.append("*impl") idl_type = attribute.idl_type if "ImplementedInPrivateScript" in extended_attributes: arguments.append("toLocalFrame(toFrameIfNotDetached(info.GetIsolate()->GetCurrentContext()))") arguments.append("impl") arguments.append("cppValue") elif idl_type.base_type == "EventHandler": getter_name = scoped_name(interface, attribute, cpp_name(attribute)) context["event_handler_getter_expression"] = "%s(%s)" % (getter_name, ", ".join(arguments)) if interface.name in ["Window", "WorkerGlobalScope"] and attribute.name == "onerror": includes.add("bindings/core/v8/V8ErrorHandler.h") arguments.append( "V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(v8Value, true, ScriptState::current(info.GetIsolate()))" ) else: arguments.append( "V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), v8Value, true, ListenerFindOrCreate)" ) elif idl_type.is_interface_type: # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append("WTF::getPtr(cppValue)") else: arguments.append("cppValue") if context["is_setter_raises_exception"]: arguments.append("exceptionState") return "%s(%s)" % (setter_name, ", ".join(arguments))
def render_template(self, include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = self.generator_name # Add includes for any dependencies template_context['header_includes'] = normalize_and_sort_includes( template_context['header_includes']) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = normalize_and_sort_includes(includes) header_text = render_template(header_template, template_context) cpp_text = render_template(cpp_template, template_context) return header_text, cpp_text
def render_template(self, include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = self.generator_name # Add includes for any dependencies template_context['header_includes'] = normalize_and_sort_includes( template_context['header_includes'], self.snake_case_generated_files) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = normalize_and_sort_includes(includes, self.snake_case_generated_files) header_text = render_template(header_template, template_context) cpp_text = render_template(cpp_template, template_context) return header_text, cpp_text
def render_template(include_paths, header_template, cpp_template, template_context, component=None): template_context['code_generator'] = module_pyname # Add includes for any dependencies template_context['header_includes'] = sorted( template_context['header_includes']) for include_path in include_paths: if component: dependency = idl_filename_to_component(include_path) assert is_valid_component_dependency(component, dependency) includes.add(include_path) template_context['cpp_includes'] = sorted(includes) header_text = header_template.render(template_context) cpp_text = cpp_template.render(template_context) return header_text, cpp_text
def activity_logging_world_list(member, access_type=None): """Returns a set of world suffixes for which a definition member has activity logging, for specified access type. access_type can be 'Getter' or 'Setter' if only checking getting or setting. """ if 'ActivityLogging' not in member.extended_attributes: return set() activity_logging = member.extended_attributes['ActivityLogging'] # [ActivityLogging=For*] (no prefix, starts with the worlds suffix) means # "log for all use (method)/access (attribute)", otherwise check that value # agrees with specified access_type (Getter/Setter). has_logging = (activity_logging.startswith('For') or (access_type and activity_logging.startswith(access_type))) if not has_logging: return set() includes.add('bindings/v8/V8DOMActivityLogger.h') if activity_logging.endswith('ForIsolatedWorlds'): return set(['']) return set(['', 'ForMainWorld']) # endswith('ForAllWorlds')
def setter_expression(interface, attribute, context): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( extended_attributes.get('SetterCallWith') or extended_attributes.get('CallWith')) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ('PartialInterfaceImplementedAs' in extended_attributes and 'ImplementedInPrivateScript' not in extended_attributes and not attribute.is_static): arguments.append('*impl') idl_type = attribute.idl_type if 'ImplementedInPrivateScript' in extended_attributes: arguments.append('toLocalFrame(toFrameIfNotDetached(info.GetIsolate()->GetCurrentContext()))') arguments.append('impl') arguments.append('cppValue') elif idl_type.base_type == 'EventHandler': getter_name = scoped_name(interface, attribute, cpp_name(attribute)) context['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/V8ErrorHandler.h') arguments.append( 'V8EventListenerHelper::ensureEventListener<V8ErrorHandler>(' + 'v8Value, true, ScriptState::forReceiverObject(info))') else: arguments.append( 'V8EventListenerHelper::getEventListener(' + 'ScriptState::forReceiverObject(info), v8Value, true, ' + 'ListenerFindOrCreate)') else: arguments.append('cppValue') if context['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def activity_logging_world_list(member, access_type=None): """Returns a set of world suffixes for which a definition member has activity logging, for specified access type. access_type can be 'Getter' or 'Setter' if only checking getting or setting. """ if 'ActivityLogging' not in member.extended_attributes: return set() activity_logging = member.extended_attributes['ActivityLogging'] # [ActivityLogging=Access*] means log for all access, otherwise check that # value agrees with specified access_type. has_logging = (activity_logging.startswith('Access') or (access_type and activity_logging.startswith(access_type))) if not has_logging: return set() includes.add('bindings/v8/V8DOMActivityLogger.h') if activity_logging.endswith('ForIsolatedWorlds'): return set(['']) if activity_logging.endswith('ForAllWorlds'): return set(['', 'ForMainWorld']) raise 'Unrecognized [ActivityLogging] value: "%s"' % activity_logging
def v8_conversion_type(idl_type, extended_attributes): """Returns V8 conversion type, adding any additional includes. The V8 conversion type is used to select the C++ -> V8 conversion function or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a separate name for the type of conversion (e.g., 'DOMWrapper'). """ extended_attributes = extended_attributes or {} # Basic types, without additional includes if idl_type in CPP_INT_TYPES: return 'int' if idl_type in CPP_UNSIGNED_TYPES: return 'unsigned' if idl_type == 'DOMString': if 'TreatReturnedNullStringAs' not in extended_attributes: return 'DOMString' treat_returned_null_string_as = extended_attributes[ 'TreatReturnedNullStringAs'] if treat_returned_null_string_as == 'Null': return 'StringOrNull' if treat_returned_null_string_as == 'Undefined': return 'StringOrUndefined' raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as if is_basic_type(idl_type) or idl_type == 'ScriptValue': return idl_type # Data type with potential additional includes this_array_or_sequence_type = array_or_sequence_type(idl_type) if this_array_or_sequence_type: if is_interface_type(this_array_or_sequence_type): add_includes_for_type(this_array_or_sequence_type) return 'array' add_includes_for_type(idl_type) if idl_type in INCLUDES_FOR_TYPE: return idl_type # Pointer type includes.add('wtf/GetPtr.h') # FIXME: remove if can eliminate WTF::getPtr includes.add('wtf/RefPtr.h') return 'DOMWrapper'
def setter_expression(interface, attribute, context): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( extended_attributes.get('SetterCallWith') or extended_attributes.get('CallWith')) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ('PartialInterfaceImplementedAs' in extended_attributes and not attribute.is_static): arguments.append('*impl') idl_type = attribute.idl_type if idl_type.base_type == 'EventHandler': getter_name = scoped_name(interface, attribute, cpp_name(attribute)) context['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/v8_error_handler.h') arguments.append( 'V8EventListenerHelper::EnsureErrorHandler(' + 'ScriptState::ForRelevantRealm(info), v8Value)') else: arguments.append( 'V8EventListenerHelper::GetEventListener(' + 'ScriptState::ForRelevantRealm(info), v8Value, true, ' + 'kListenerFindOrCreate)') elif idl_type.base_type == 'SerializedScriptValue': arguments.append('std::move(cppValue)') else: arguments.append('cppValue') if idl_type.is_explicit_nullable: arguments.append('isNull') if context['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def v8_value_to_cpp_value_array_or_sequence(this_array_or_sequence_type, v8_value, index): # Index is None for setters, index (starting at 0) for method arguments, # and is used to provide a human-readable exception message if index is None: index = 0 # special case, meaning "setter" else: index += 1 # human-readable index if is_interface_type(this_array_or_sequence_type): this_cpp_type = None expression_format = '(toRefPtrNativeArray<{array_or_sequence_type}, V8{array_or_sequence_type}>({v8_value}, {index}, info.GetIsolate()))' includes.add('V8%s.h' % this_array_or_sequence_type) else: this_cpp_type = cpp_type(this_array_or_sequence_type) expression_format = 'toNativeArray<{cpp_type}>({v8_value}, {index}, info.GetIsolate())' expression = expression_format.format( array_or_sequence_type=this_array_or_sequence_type, cpp_type=this_cpp_type, index=index, v8_value=v8_value) return expression
def v8_conversion_type(idl_type, extended_attributes): """Returns V8 conversion type, adding any additional includes. The V8 conversion type is used to select the C++ -> V8 conversion function or v8SetReturnValue* function; it can be an idl_type, a cpp_type, or a separate name for the type of conversion (e.g., 'DOMWrapper'). """ extended_attributes = extended_attributes or {} # Basic types, without additional includes if idl_type in CPP_INT_TYPES: return 'int' if idl_type in CPP_UNSIGNED_TYPES: return 'unsigned' if idl_type == 'DOMString': if 'TreatReturnedNullStringAs' not in extended_attributes: return 'DOMString' treat_returned_null_string_as = extended_attributes['TreatReturnedNullStringAs'] if treat_returned_null_string_as == 'Null': return 'StringOrNull' if treat_returned_null_string_as == 'Undefined': return 'StringOrUndefined' raise 'Unrecognized TreatReturnNullStringAs value: "%s"' % treat_returned_null_string_as if is_basic_type(idl_type) or idl_type == 'ScriptValue': return idl_type # Data type with potential additional includes this_array_or_sequence_type = array_or_sequence_type(idl_type) if this_array_or_sequence_type: if is_interface_type(this_array_or_sequence_type): add_includes_for_type(this_array_or_sequence_type) return 'array' add_includes_for_type(idl_type) if idl_type in V8_SET_RETURN_VALUE: # Special v8SetReturnValue treatment return idl_type # Pointer type includes.add('wtf/GetPtr.h') # FIXME: remove if can eliminate WTF::getPtr includes.add('wtf/RefPtr.h') return 'DOMWrapper'
def setter_expression(interface, attribute, context): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( extended_attributes.get('SetterCallWith') or extended_attributes.get('CallWith')) this_setter_base_name = setter_base_name(interface, attribute, arguments) setter_name = scoped_name(interface, attribute, this_setter_base_name) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument if ('PartialInterfaceImplementedAs' in extended_attributes and not attribute.is_static): arguments.append('*impl') idl_type = attribute.idl_type if idl_type.base_type == 'EventHandler': getter_name = scoped_name(interface, attribute, cpp_name(attribute)) context['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/V8ErrorHandler.h') arguments.append( 'V8EventListenerHelper::EnsureErrorHandler(' + 'ScriptState::ForRelevantRealm(info), v8Value)') else: arguments.append( 'V8EventListenerHelper::GetEventListener(' + 'ScriptState::ForRelevantRealm(info), v8Value, true, ' + 'kListenerFindOrCreate)') else: arguments.append('cppValue') if idl_type.is_explicit_nullable: arguments.append('isNull') if context['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def setter_expression(interface, attribute, contents): arguments = v8_utilities.call_with_arguments(attribute, attribute.extended_attributes.get('SetterCallWith')) this_setter_base_name = setter_base_name(attribute, arguments) setter_name = v8_utilities.scoped_name(interface, attribute, this_setter_base_name) idl_type = attribute.idl_type if idl_type == 'EventHandler': # FIXME: move V8EventListenerList.h to INCLUDES_FOR_TYPE includes.add('bindings/v8/V8EventListenerList.h') # FIXME: pass the isolate instead of the isolated world isolated_world = 'isolatedWorldForIsolate(info.GetIsolate())' arguments.extend(['V8EventListenerList::getEventListener(jsValue, true, ListenerFindOrCreate)', isolated_world]) contents['event_handler_getter_expression'] = 'imp->%s(%s)' % (cpp_name(attribute), isolated_world) elif v8_types.is_interface_type(idl_type) and not v8_types.array_type(idl_type): # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append('WTF::getPtr(cppValue)') else: arguments.append('cppValue') if contents['is_setter_raises_exception']: arguments.append('es') return '%s(%s)' % (setter_name, ', '.join(arguments))
def setter_expression(interface, attribute, contents): extended_attributes = attribute.extended_attributes arguments = v8_utilities.call_with_arguments( attribute, extended_attributes.get('SetterCallWith')) this_setter_base_name = setter_base_name(attribute, arguments) setter_name = v8_utilities.scoped_name(interface, attribute, this_setter_base_name) if ('ImplementedBy' in extended_attributes and not attribute.is_static): arguments.append('imp') idl_type = attribute.idl_type if idl_type == 'EventHandler': getter_name = v8_utilities.scoped_name(interface, attribute, cpp_name(attribute)) contents['event_handler_getter_expression'] = '%s(%s)' % ( getter_name, ', '.join(arguments)) if (interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') arguments.append( 'V8EventListenerList::findOrCreateWrapper<V8ErrorHandler>(jsValue, true, info.GetIsolate())' ) else: arguments.append( 'V8EventListenerList::getEventListener(jsValue, true, ListenerFindOrCreate)' ) elif v8_types.is_interface_type( idl_type) and not v8_types.array_type(idl_type): # FIXME: should be able to eliminate WTF::getPtr in most or all cases arguments.append('WTF::getPtr(cppValue)') else: arguments.append('cppValue') if contents['is_setter_raises_exception']: arguments.append('exceptionState') return '%s(%s)' % (setter_name, ', '.join(arguments))
def generate_getter(interface, attribute, contents): idl_type = attribute.idl_type v8_types.add_includes_for_type(idl_type) extended_attributes = attribute.extended_attributes cpp_value = getter_expression(interface, attribute, contents) # Normally we can inline the function call into the return statement to # avoid the overhead of using a Ref<> temporary, but for some cases # (nullable types, EventHandler, [CachedAttribute], or if there are # exceptions), we need to use a local variable. # FIXME: check if compilers are smart enough to inline this, and if so, # always use a local variable (for readability and CG simplicity). if (attribute.is_nullable or idl_type == 'EventHandler' or 'CachedAttribute' in extended_attributes or contents['is_getter_raises_exception']): contents['cpp_value_original'] = cpp_value cpp_value = 'jsValue' contents['cpp_value'] = cpp_value if contents['is_keep_alive_for_gc']: v8_set_return_value_statement = 'v8SetReturnValue(info, wrapper)' includes.add('bindings/v8/V8HiddenPropertyName.h') else: v8_set_return_value_statement = v8_types.v8_set_return_value( idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp') contents['v8_set_return_value'] = v8_set_return_value_statement if (idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') # [CheckSecurityForNode] is_check_security_for_node = 'CheckSecurityForNode' in extended_attributes if is_check_security_for_node: includes.add('bindings/v8/BindingSecurity.h') if is_check_security_for_node or contents['is_getter_raises_exception']: includes.update( set([ 'bindings/v8/ExceptionMessages.h', 'bindings/v8/ExceptionState.h' ])) v8_utilities.generate_deprecate_as(attribute, contents) # [DeprecateAs] v8_utilities.generate_measure_as(attribute, contents) # [MeasureAs] contents.update({ 'is_check_security_for_node': is_check_security_for_node, 'is_unforgeable': 'Unforgeable' in extended_attributes, })
def generate_getter(interface, attribute, contents): idl_type = attribute.idl_type v8_types.add_includes_for_type(idl_type) extended_attributes = attribute.extended_attributes cpp_value = getter_expression(interface, attribute, contents) # Normally we can inline the function call into the return statement to # avoid the overhead of using a Ref<> temporary, but for some cases # (nullable types, EventHandler, [CachedAttribute], or if there are # exceptions), we need to use a local variable. # FIXME: check if compilers are smart enough to inline this, and if so, # always use a local variable (for readability and CG simplicity). if (attribute.is_nullable or idl_type == 'EventHandler' or 'CachedAttribute' in extended_attributes or contents['is_getter_raises_exception']): contents['cpp_value_original'] = cpp_value cpp_value = 'jsValue' contents['cpp_value'] = cpp_value if contents['is_keep_alive_for_gc']: v8_set_return_value_statement = 'v8SetReturnValue(info, wrapper)' includes.add('bindings/v8/V8HiddenPropertyName.h') else: v8_set_return_value_statement = v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp') contents['v8_set_return_value'] = v8_set_return_value_statement if (idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') # [CheckSecurityForNode] is_check_security_for_node = 'CheckSecurityForNode' in extended_attributes if is_check_security_for_node: includes.add('bindings/v8/BindingSecurity.h') if is_check_security_for_node or contents['is_getter_raises_exception']: includes.update(set(['bindings/v8/ExceptionMessages.h', 'bindings/v8/ExceptionState.h'])) contents.update({ 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs] 'is_check_security_for_node': is_check_security_for_node, 'is_unforgeable': 'Unforgeable' in extended_attributes, 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs] })
def attribute_context(interface, attribute, interfaces): """Creates a Jinja template context for an attribute of an interface. Args: interface: An interface which |attribute| belongs to attribute: An attribute to create the context for interfaces: A dict which maps an interface name to the definition which can be referred if needed Returns: A Jinja template context for |attribute| """ idl_type = attribute.idl_type base_idl_type = idl_type.base_type extended_attributes = attribute.extended_attributes idl_type.add_includes_for_type(extended_attributes) if idl_type.enum_values: includes.add('core/inspector/ConsoleMessage.h') # [CheckSecurity] is_cross_origin = 'CrossOrigin' in extended_attributes is_check_security_for_receiver = (has_extended_attribute_value( interface, 'CheckSecurity', 'Receiver') and is_cross_origin) is_check_security_for_return_value = (has_extended_attribute_value( attribute, 'CheckSecurity', 'ReturnValue')) if is_check_security_for_receiver or is_check_security_for_return_value: includes.add('bindings/core/v8/BindingSecurity.h') # [CrossOrigin] if has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'): includes.add('bindings/core/v8/V8CrossOriginSetterInfo.h') # [Constructor] # TODO(yukishiino): Constructors are much like methods although constructors # are not methods. Constructors must be data-type properties, and we can # support them as a kind of methods. constructor_type = idl_type.constructor_type_name if is_constructor_attribute( attribute) else None # [CEReactions] is_ce_reactions = 'CEReactions' in extended_attributes if is_ce_reactions: includes.add('core/dom/custom/CEReactionsScope.h') # [CustomElementCallbacks], [Reflect] is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes is_reflect = 'Reflect' in extended_attributes if is_custom_element_callbacks or is_reflect: includes.add('core/dom/custom/V0CustomElementProcessingStack.h') # [PerWorldBindings] if 'PerWorldBindings' in extended_attributes: assert idl_type.is_wrapper_type or 'LogActivity' in extended_attributes, '[PerWorldBindings] should only be used with wrapper types: %s.%s' % ( interface.name, attribute.name) # [SaveSameObject] is_save_same_object = ('SameObject' in attribute.extended_attributes and 'SaveSameObject' in attribute.extended_attributes) if is_save_same_object: includes.add('bindings/core/v8/V8PrivateProperty.h') if (base_idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/V8ErrorHandler.h') cached_attribute_validation_method = extended_attributes.get( 'CachedAttribute') keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute) if cached_attribute_validation_method or keep_alive_for_gc: includes.add('bindings/core/v8/V8HiddenValue.h') # [CachedAccessor] is_cached_accessor = 'CachedAccessor' in extended_attributes if is_cached_accessor: includes.add('bindings/core/v8/V8PrivateProperty.h') context = { 'access_control_list': access_control_list(interface, attribute), 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging] 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging] 'activity_logging_world_check': v8_utilities.activity_logging_world_check(attribute), # [ActivityLogging] 'cached_attribute_validation_method': cached_attribute_validation_method, 'constructor_type': constructor_type, 'cpp_name': cpp_name(attribute), 'cpp_type': idl_type.cpp_type, 'cpp_type_initializer': idl_type.cpp_type_initializer, 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs] 'enum_type': idl_type.enum_type, 'enum_values': idl_type.enum_values, 'exposed_test': v8_utilities.exposed(attribute, interface), # [Exposed] 'has_cross_origin_getter': has_extended_attribute_value(attribute, 'CrossOrigin', None) or has_extended_attribute_value(attribute, 'CrossOrigin', 'Getter'), 'has_cross_origin_setter': has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'), 'has_custom_getter': has_custom_getter(attribute), 'has_custom_setter': has_custom_setter(attribute), 'has_setter': has_setter(interface, attribute), 'idl_type': str(idl_type), # need trailing [] on array for Dictionary::ConversionContext::setConversionType 'is_cached_accessor': is_cached_accessor, 'is_call_with_execution_context': has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'), 'is_call_with_script_state': has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'), 'is_ce_reactions': is_ce_reactions, 'is_check_security_for_receiver': is_check_security_for_receiver, 'is_check_security_for_return_value': is_check_security_for_return_value, 'is_custom_element_callbacks': is_custom_element_callbacks, # TODO(yukishiino): Make all DOM attributes accessor-type properties. 'is_data_type_property': is_data_type_property(interface, attribute), 'is_getter_raises_exception': # [RaisesException] 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in (None, 'Getter'), 'is_keep_alive_for_gc': keep_alive_for_gc, 'is_lenient_this': 'LenientThis' in extended_attributes, 'is_nullable': idl_type.is_nullable, 'is_explicit_nullable': idl_type.is_explicit_nullable, 'is_partial_interface_member': 'PartialInterfaceImplementedAs' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_put_forwards': 'PutForwards' in extended_attributes, 'is_read_only': attribute.is_read_only, 'is_reflect': is_reflect, 'is_replaceable': 'Replaceable' in attribute.extended_attributes, 'is_save_same_object': is_save_same_object, 'is_static': attribute.is_static, 'is_url': 'URL' in extended_attributes, 'is_unforgeable': is_unforgeable(interface, attribute), 'on_instance': v8_utilities.on_instance(interface, attribute), 'on_interface': v8_utilities.on_interface(interface, attribute), 'on_prototype': v8_utilities.on_prototype(interface, attribute), 'origin_trial_enabled_function': v8_utilities.origin_trial_enabled_function_name(attribute), # [OriginTrialEnabled] 'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(attribute), # [OriginTrialEnabled] 'use_output_parameter_for_result': idl_type.use_output_parameter_for_result, 'measure_as': v8_utilities.measure_as(attribute, interface), # [MeasureAs] 'name': attribute.name, 'property_attributes': property_attributes(interface, attribute), 'reflect_empty': extended_attributes.get('ReflectEmpty'), 'reflect_invalid': extended_attributes.get('ReflectInvalid', ''), 'reflect_missing': extended_attributes.get('ReflectMissing'), 'reflect_only': extended_attribute_value_as_list(attribute, 'ReflectOnly'), 'runtime_enabled_feature_name': v8_utilities.runtime_enabled_feature_name(attribute), # [RuntimeEnabled] 'secure_context_test': v8_utilities.secure_context(attribute, interface), # [SecureContext] 'cached_accessor_name': '%s%sCachedAccessor' % (interface.name, attribute.name.capitalize()), 'world_suffixes': ( ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else ['']), # [PerWorldBindings] } if is_constructor_attribute(attribute): update_constructor_attribute_context(interface, attribute, context) if not has_custom_getter(attribute): getter_context(interface, attribute, context) if not has_custom_setter(attribute) and has_setter(interface, attribute): setter_context(interface, attribute, interfaces, context) # [CrossOrigin] is incompatible with a number of other attributes, so check # for them here. if is_cross_origin: if context['has_cross_origin_getter'] and context['has_custom_getter']: raise Exception( '[CrossOrigin] and [Custom] are incompatible on the same getter: %s.%s', interface.name, attribute.name) if context['has_cross_origin_setter'] and context['has_custom_setter']: raise Exception( '[CrossOrigin] and [Custom] are incompatible on the same setter: %s.%s', interface.name, attribute.name) if context['is_per_world_bindings']: raise Exception( '[CrossOrigin] and [PerWorldBindings] are incompatible: %s.%s', interface.name, attribute.name) if context['constructor_type']: raise Exception( '[CrossOrigin] cannot be used for constructors: %s.%s', interface.name, attribute.name) return context
def method_context(interface, method, is_visible=True): arguments = method.arguments extended_attributes = method.extended_attributes idl_type = method.idl_type is_static = method.is_static name = method.name if is_visible: idl_type.add_includes_for_type(extended_attributes) this_cpp_value = cpp_value(interface, method, len(arguments)) is_call_with_script_arguments = has_extended_attribute_value(method, 'CallWith', 'ScriptArguments') if is_call_with_script_arguments: includes.update(['bindings/core/v8/ScriptCallStack.h', 'core/inspector/ScriptArguments.h']) is_call_with_script_state = has_extended_attribute_value(method, 'CallWith', 'ScriptState') is_call_with_this_value = has_extended_attribute_value(method, 'CallWith', 'ThisValue') if is_call_with_script_state or is_call_with_this_value: includes.add('platform/bindings/ScriptState.h') # [CheckSecurity] is_cross_origin = 'CrossOrigin' in extended_attributes is_check_security_for_receiver = ( has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and not is_cross_origin) is_check_security_for_return_value = ( has_extended_attribute_value(method, 'CheckSecurity', 'ReturnValue')) if is_check_security_for_receiver or is_check_security_for_return_value: includes.add('bindings/core/v8/BindingSecurity.h') is_ce_reactions = 'CEReactions' in extended_attributes if is_ce_reactions: includes.add('core/html/custom/CEReactionsScope.h') is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes if is_custom_element_callbacks: includes.add('core/html/custom/V0CustomElementProcessingStack.h') is_raises_exception = 'RaisesException' in extended_attributes is_custom_call_prologue = has_extended_attribute_value(method, 'Custom', 'CallPrologue') is_custom_call_epilogue = has_extended_attribute_value(method, 'Custom', 'CallEpilogue') is_post_message = 'PostMessage' in extended_attributes if is_post_message: includes.add('bindings/core/v8/serialization/SerializedScriptValueFactory.h') includes.add('bindings/core/v8/serialization/Transferables.h') includes.add('core/typed_arrays/DOMArrayBufferBase.h') includes.add('core/imagebitmap/ImageBitmap.h') if 'LenientThis' in extended_attributes: raise Exception('[LenientThis] is not supported for operations.') argument_contexts = [ argument_context(interface, method, argument, index, is_visible=is_visible) for index, argument in enumerate(arguments)] return { 'activity_logging_world_list': v8_utilities.activity_logging_world_list(method), # [ActivityLogging] 'arguments': argument_contexts, 'cpp_type': (v8_types.cpp_template_type('Nullable', idl_type.cpp_type) if idl_type.is_explicit_nullable else idl_type.cpp_type), 'cpp_value': this_cpp_value, 'cpp_type_initializer': idl_type.cpp_type_initializer, 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs] 'do_not_test_new_object': 'DoNotTestNewObject' in extended_attributes, 'exposed_test': v8_utilities.exposed(method, interface), # [Exposed] 'has_exception_state': is_raises_exception or is_check_security_for_receiver or any(argument for argument in arguments if (argument.idl_type.name == 'SerializedScriptValue' or argument_conversion_needs_exception_state(method, argument))), 'has_optional_argument_without_default_value': any(True for argument_context in argument_contexts if argument_context['is_optional_without_default_value']), 'idl_type': idl_type.base_type, 'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'), 'is_call_with_script_arguments': is_call_with_script_arguments, 'is_call_with_script_state': is_call_with_script_state, 'is_call_with_this_value': is_call_with_this_value, 'is_ce_reactions': is_ce_reactions, 'is_check_security_for_receiver': is_check_security_for_receiver, 'is_check_security_for_return_value': is_check_security_for_return_value, 'is_cross_origin': 'CrossOrigin' in extended_attributes, 'is_custom': 'Custom' in extended_attributes and not (is_custom_call_prologue or is_custom_call_epilogue), 'is_custom_call_prologue': is_custom_call_prologue, 'is_custom_call_epilogue': is_custom_call_epilogue, 'is_custom_element_callbacks': is_custom_element_callbacks, 'is_explicit_nullable': idl_type.is_explicit_nullable, 'is_new_object': 'NewObject' in extended_attributes, 'is_partial_interface_member': 'PartialInterfaceImplementedAs' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_post_message': is_post_message, 'is_raises_exception': is_raises_exception, 'is_static': is_static, 'is_unforgeable': is_unforgeable(interface, method), 'is_variadic': arguments and arguments[-1].is_variadic, 'measure_as': v8_utilities.measure_as(method, interface), # [MeasureAs] 'name': name, 'number_of_arguments': len(arguments), 'number_of_required_arguments': len([ argument for argument in arguments if not (argument.is_optional or argument.is_variadic)]), 'number_of_required_or_variadic_arguments': len([ argument for argument in arguments if not argument.is_optional]), 'on_instance': v8_utilities.on_instance(interface, method), 'on_interface': v8_utilities.on_interface(interface, method), 'on_prototype': v8_utilities.on_prototype(interface, method), 'origin_trial_enabled_function': v8_utilities.origin_trial_enabled_function_name(method), # [OriginTrialEnabled] 'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(method), # [OriginTrialEnabled] 'property_attributes': property_attributes(interface, method), 'returns_promise': method.returns_promise, 'runtime_call_stats': runtime_call_stats_context(interface, method), 'runtime_enabled_feature_name': v8_utilities.runtime_enabled_feature_name(method), # [RuntimeEnabled] 'secure_context_test': v8_utilities.secure_context(method, interface), # [SecureContext] 'use_output_parameter_for_result': idl_type.use_output_parameter_for_result, 'use_local_result': use_local_result(method), 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value), 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True), 'visible': is_visible, 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings], }
def runtime_enabled_feature_name(definition_or_member): extended_attributes = definition_or_member.extended_attributes if 'RuntimeEnabled' not in extended_attributes: return None includes.add('platform/RuntimeEnabledFeatures.h') return extended_attributes['RuntimeEnabled']
def generate_method(interface, method): arguments = method.arguments extended_attributes = method.extended_attributes idl_type = method.idl_type is_static = method.is_static name = method.name this_cpp_value = cpp_value(interface, method, len(arguments)) this_custom_signature = custom_signature(method, arguments) def function_template(): if is_static: return 'functionTemplate' if 'Unforgeable' in extended_attributes: return 'instanceTemplate' return 'prototypeTemplate' def signature(): if this_custom_signature: return name + 'Signature' if is_static or 'DoNotCheckSignature' in extended_attributes: return 'v8::Local<v8::Signature>()' return 'defaultSignature' is_call_with_script_arguments = has_extended_attribute_value( method, 'CallWith', 'ScriptArguments') if is_call_with_script_arguments: includes.update([ 'bindings/v8/ScriptCallStackFactory.h', 'core/inspector/ScriptArguments.h' ]) is_call_with_script_state = has_extended_attribute_value( method, 'CallWith', 'ScriptState') if is_call_with_script_state: includes.add('bindings/v8/ScriptState.h') is_check_security_for_node = 'CheckSecurity' in extended_attributes if is_check_security_for_node: includes.add('bindings/v8/BindingSecurity.h') is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes if is_custom_element_callbacks: includes.add('core/dom/custom/CustomElementCallbackDispatcher.h') contents = { 'activity_logging_world_list': v8_utilities.activity_logging_world_list(method), # [ActivityLogging] 'arguments': [ generate_argument(interface, method, argument, index) for index, argument in enumerate(arguments) ], 'conditional_string': v8_utilities.conditional_string(method), 'cpp_type': v8_types.cpp_type(idl_type), 'cpp_value': this_cpp_value, 'custom_signature': this_custom_signature, 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs] 'do_not_check_signature': not (this_custom_signature or is_static or v8_utilities.has_extended_attribute(method, [ 'DoNotCheckSecurity', 'DoNotCheckSignature', 'NotEnumerable', 'ReadOnly', 'RuntimeEnabled', 'Unforgeable' ])), 'function_template': function_template(), 'idl_type': idl_type, 'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'), 'is_call_with_script_arguments': is_call_with_script_arguments, 'is_call_with_script_state': is_call_with_script_state, 'is_check_security_for_frame': ('CheckSecurity' in interface.extended_attributes and 'DoNotCheckSecurity' not in extended_attributes), 'is_check_security_for_node': is_check_security_for_node, 'is_custom': 'Custom' in extended_attributes, 'is_custom_element_callbacks': is_custom_element_callbacks, 'is_do_not_check_security': 'DoNotCheckSecurity' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_raises_exception': 'RaisesException' in extended_attributes, 'is_read_only': 'ReadOnly' in extended_attributes, 'is_static': is_static, 'is_strict_type_checking': 'StrictTypeChecking' in extended_attributes, 'is_variadic': arguments and arguments[-1].is_variadic, 'measure_as': v8_utilities.measure_as(method), # [MeasureAs] 'name': name, 'number_of_arguments': len(arguments), 'number_of_required_arguments': len([ argument for argument in arguments if not (argument.is_optional or argument.is_variadic) ]), 'number_of_required_or_variadic_arguments': len([argument for argument in arguments if not argument.is_optional]), 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name( method), # [PerContextEnabled] 'property_attributes': property_attributes(method), 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(method), # [RuntimeEnabled] 'signature': signature(), 'v8_set_return_value': v8_set_return_value(method, this_cpp_value), 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] } return contents
def deprecate_as(member): extended_attributes = member.extended_attributes if 'DeprecateAs' not in extended_attributes: return None includes.add('core/frame/Deprecation.h') return extended_attributes['DeprecateAs']
def generate_interface(interface): includes.clear() includes.update(INTERFACE_CPP_INCLUDES) header_includes = set(INTERFACE_H_INCLUDES) parent_interface = interface.parent if parent_interface: header_includes.update( v8_types.includes_for_interface(parent_interface)) extended_attributes = interface.extended_attributes is_audio_buffer = inherits_interface(interface.name, 'AudioBuffer') if is_audio_buffer: includes.add('modules/webaudio/AudioBuffer.h') is_document = inherits_interface(interface.name, 'Document') if is_document: includes.update([ 'bindings/v8/ScriptController.h', 'bindings/v8/V8WindowShell.h', 'core/frame/LocalFrame.h' ]) # [ActiveDOMObject] is_active_dom_object = 'ActiveDOMObject' in extended_attributes # [CheckSecurity] is_check_security = 'CheckSecurity' in extended_attributes if is_check_security: includes.add('bindings/v8/BindingSecurity.h') # [DependentLifetime] is_dependent_lifetime = 'DependentLifetime' in extended_attributes # [MeasureAs] is_measure_as = 'MeasureAs' in extended_attributes if is_measure_as: includes.add('core/frame/UseCounter.h') # [SetWrapperReferenceFrom] reachable_node_function = extended_attributes.get( 'SetWrapperReferenceFrom') if reachable_node_function: includes.update(['bindings/v8/V8GCController.h', 'core/dom/Element.h']) # [SetWrapperReferenceTo] set_wrapper_reference_to_list = [ { 'name': argument.name, # FIXME: properly should be: # 'cpp_type': argument.idl_type.cpp_type_args(used_as_argument=True), # (if type is non-wrapper type like NodeFilter, normally RefPtr) # Raw pointers faster though, and NodeFilter hacky anyway. 'cpp_type': argument.idl_type.implemented_as + '*', 'idl_type': argument.idl_type, 'v8_type': v8_types.v8_type(argument.idl_type.name), } for argument in extended_attributes.get('SetWrapperReferenceTo', []) ] for set_wrapper_reference_to in set_wrapper_reference_to_list: set_wrapper_reference_to['idl_type'].add_includes_for_type() # [SpecialWrapFor] if 'SpecialWrapFor' in extended_attributes: special_wrap_for = extended_attributes['SpecialWrapFor'].split('|') else: special_wrap_for = [] for special_wrap_interface in special_wrap_for: v8_types.add_includes_for_interface(special_wrap_interface) # [Custom=Wrap], [SetWrapperReferenceFrom] has_visit_dom_wrapper = (has_extended_attribute_value( interface, 'Custom', 'VisitDOMWrapper') or reachable_node_function or set_wrapper_reference_to_list) this_gc_type = gc_type(interface) template_contents = { 'conditional_string': conditional_string(interface), # [Conditional] 'cpp_class': cpp_name(interface), 'gc_type': this_gc_type, 'has_custom_legacy_call_as_function': has_extended_attribute_value( interface, 'Custom', 'LegacyCallAsFunction'), # [Custom=LegacyCallAsFunction] 'has_custom_to_v8': has_extended_attribute_value(interface, 'Custom', 'ToV8'), # [Custom=ToV8] 'has_custom_wrap': has_extended_attribute_value(interface, 'Custom', 'Wrap'), # [Custom=Wrap] 'has_visit_dom_wrapper': has_visit_dom_wrapper, 'header_includes': header_includes, 'interface_name': interface.name, 'is_active_dom_object': is_active_dom_object, 'is_audio_buffer': is_audio_buffer, 'is_check_security': is_check_security, 'is_dependent_lifetime': is_dependent_lifetime, 'is_document': is_document, 'is_event_target': inherits_interface(interface.name, 'EventTarget'), 'is_exception': interface.is_exception, 'is_node': inherits_interface(interface.name, 'Node'), 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] 'parent_interface': parent_interface, 'pass_cpp_type': cpp_template_type(cpp_ptr_type('PassRefPtr', 'RawPtr', this_gc_type), cpp_name(interface)), 'reachable_node_function': reachable_node_function, 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled] 'set_wrapper_reference_to_list': set_wrapper_reference_to_list, 'special_wrap_for': special_wrap_for, 'v8_class': v8_utilities.v8_class_name(interface), 'wrapper_configuration': 'WrapperConfiguration::Dependent' if (has_visit_dom_wrapper or is_active_dom_object or is_dependent_lifetime) else 'WrapperConfiguration::Independent', } # Constructors constructors = [ generate_constructor(interface, constructor) for constructor in interface.constructors # FIXME: shouldn't put named constructors with constructors # (currently needed for Perl compatibility) # Handle named constructors separately if constructor.name == 'Constructor' ] if len(constructors) > 1: template_contents['constructor_overloads'] = generate_overloads( constructors) # [CustomConstructor] custom_constructors = [{ # Only needed for computing interface length 'number_of_required_arguments': number_of_required_arguments(constructor), } for constructor in interface.custom_constructors] # [EventConstructor] has_event_constructor = 'EventConstructor' in extended_attributes any_type_attributes = [ attribute for attribute in interface.attributes if attribute.idl_type.name == 'Any' ] if has_event_constructor: includes.add('bindings/v8/Dictionary.h') if any_type_attributes: includes.add('bindings/v8/SerializedScriptValue.h') # [NamedConstructor] named_constructor = generate_named_constructor(interface) if (constructors or custom_constructors or has_event_constructor or named_constructor): includes.add('bindings/v8/V8ObjectConstructor.h') includes.add('core/frame/DOMWindow.h') template_contents.update({ 'any_type_attributes': any_type_attributes, 'constructors': constructors, 'has_custom_constructor': bool(custom_constructors), 'has_event_constructor': has_event_constructor, 'interface_length': interface_length(interface, constructors + custom_constructors), 'is_constructor_call_with_document': has_extended_attribute_value( interface, 'ConstructorCallWith', 'Document'), # [ConstructorCallWith=Document] 'is_constructor_call_with_execution_context': has_extended_attribute_value( interface, 'ConstructorCallWith', 'ExecutionContext'), # [ConstructorCallWith=ExeuctionContext] 'is_constructor_raises_exception': extended_attributes.get('RaisesException') == 'Constructor', # [RaisesException=Constructor] 'named_constructor': named_constructor, }) # Constants template_contents.update({ 'constants': [generate_constant(constant) for constant in interface.constants], 'do_not_check_constants': 'DoNotCheckConstants' in extended_attributes, }) # Attributes attributes = [ v8_attributes.generate_attribute(interface, attribute) for attribute in interface.attributes ] template_contents.update({ 'attributes': attributes, 'has_accessors': any(attribute['is_expose_js_accessors'] for attribute in attributes), 'has_attribute_configuration': any(not (attribute['is_expose_js_accessors'] or attribute['is_static'] or attribute['runtime_enabled_function'] or attribute['per_context_enabled_function']) for attribute in attributes), 'has_constructor_attributes': any(attribute['constructor_type'] for attribute in attributes), 'has_per_context_enabled_attributes': any(attribute['per_context_enabled_function'] for attribute in attributes), 'has_replaceable_attributes': any(attribute['is_replaceable'] for attribute in attributes), }) # Methods methods = [ v8_methods.generate_method(interface, method) for method in interface.operations if method.name ] # Skip anonymous special operations (methods) generate_method_overloads(methods) for method in methods: method['do_generate_method_configuration'] = ( method['do_not_check_signature'] and not method['per_context_enabled_function'] and # For overloaded methods, only generate one accessor ('overload_index' not in method or method['overload_index'] == 1)) template_contents.update({ 'has_origin_safe_method_setter': any(method['is_check_security_for_frame'] and not method['is_read_only'] for method in methods), 'has_method_configuration': any(method['do_generate_method_configuration'] for method in methods), 'has_per_context_enabled_methods': any(method['per_context_enabled_function'] for method in methods), 'methods': methods, }) template_contents.update({ 'indexed_property_getter': indexed_property_getter(interface), 'indexed_property_setter': indexed_property_setter(interface), 'indexed_property_deleter': indexed_property_deleter(interface), 'is_override_builtins': 'OverrideBuiltins' in extended_attributes, 'named_property_getter': named_property_getter(interface), 'named_property_setter': named_property_setter(interface), 'named_property_deleter': named_property_deleter(interface), }) return template_contents
def attribute_context(interface, attribute, interfaces, component_info): """Creates a Jinja template context for an attribute of an interface. Args: interface: An interface which |attribute| belongs to attribute: An attribute to create the context for interfaces: A dict which maps an interface name to the definition which can be referred if needed component_info: A dict containing component wide information Returns: A Jinja template context for |attribute| """ idl_type = attribute.idl_type base_idl_type = idl_type.base_type extended_attributes = attribute.extended_attributes idl_type.add_includes_for_type(extended_attributes) if idl_type.enum_values: includes.add('core/inspector/console_message.h') includes.add('platform/heap/heap.h') # [CheckSecurity] is_cross_origin = 'CrossOrigin' in extended_attributes is_check_security_for_receiver = (has_extended_attribute_value( interface, 'CheckSecurity', 'Receiver') and is_cross_origin) is_check_security_for_return_value = (has_extended_attribute_value( attribute, 'CheckSecurity', 'ReturnValue')) if is_check_security_for_receiver or is_check_security_for_return_value: includes.add('bindings/core/v8/binding_security.h') if is_check_security_for_return_value: includes.add('core/frame/web_feature.h') includes.add('platform/instrumentation/use_counter.h') # [CrossOrigin] if has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'): includes.add('platform/bindings/v8_cross_origin_callback_info.h') # [Constructor] # TODO(yukishiino): Constructors are much like methods although constructors # are not methods. Constructors must be data-type properties, and we can # support them as a kind of methods. constructor_type = idl_type.constructor_type_name if is_constructor_attribute( attribute) else None # [CEReactions] is_ce_reactions = 'CEReactions' in extended_attributes if is_ce_reactions: includes.add('core/html/custom/ce_reactions_scope.h') # [CustomElementCallbacks], [Reflect] is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes is_reflect = 'Reflect' in extended_attributes # [ReflectOnly] reflect_only = extended_attribute_value_as_list(attribute, 'ReflectOnly') if reflect_only: reflect_only = map( lambda v: cpp_content_attribute_value_name(interface, v), reflect_only) if is_custom_element_callbacks or is_reflect: includes.add('core/html/custom/v0_custom_element_processing_stack.h') # [PerWorldBindings] if 'PerWorldBindings' in extended_attributes: assert idl_type.is_wrapper_type or 'LogActivity' in \ extended_attributes, \ '[PerWorldBindings] should only be used with wrapper types: %s.%s' % \ (interface.name, attribute.name) # [SaveSameObject] is_save_same_object = ('SameObject' in attribute.extended_attributes and 'SaveSameObject' in attribute.extended_attributes) # [StringContext] if idl_type.has_string_context: includes.add('bindings/core/v8/generated_code_helper.h') # [CachedAccessor] is_cached_accessor = 'CachedAccessor' in extended_attributes # [LenientSetter] is_lenient_setter = 'LenientSetter' in extended_attributes # [CachedAttribute] cached_attribute_validation_method = extended_attributes.get( 'CachedAttribute') keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute) does_generate_getter = (not has_custom_getter(attribute) and not constructor_type) does_generate_setter = ( has_setter(interface, attribute) and not (has_custom_setter(attribute) or is_lenient_setter)) use_private_property_in_getter = (does_generate_getter and (cached_attribute_validation_method or is_save_same_object or keep_alive_for_gc)) use_private_property_in_setter = (does_generate_setter and cached_attribute_validation_method) private_property_is_shared_between_getter_and_setter = ( use_private_property_in_getter and use_private_property_in_setter) does_use_private_property = (use_private_property_in_getter or use_private_property_in_setter or is_cached_accessor) if does_use_private_property: includes.add('platform/bindings/v8_private_property.h') # [LogActivity] if 'LogActivity' in extended_attributes: includes.add('platform/bindings/v8_per_context_data.h') # [DeprecateAs], [MeasureAs] deprecate_as = v8_utilities.deprecate_as(attribute) measure_as = v8_utilities.measure_as(attribute, interface) # [HighEntropy] high_entropy = v8_utilities.high_entropy(attribute) is_lazy_data_attribute = \ (constructor_type and not (measure_as or deprecate_as)) or \ (str(idl_type) == 'Window' and attribute.name in ('frames', 'self', 'window')) runtime_features = component_info['runtime_enabled_features'] internal_name = cpp_encoded_property_name(attribute) cpp_type = idl_type.cpp_type if idl_type.is_explicit_nullable: cpp_type = v8_types.cpp_template_type('base::Optional', cpp_type) context = { # [ActivityLogging] 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging] 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging] 'activity_logging_world_check': v8_utilities.activity_logging_world_check(attribute), 'cached_accessor_name': 'k%s%s' % (interface.name, attribute.name.capitalize()), 'cached_attribute_validation_method': cached_attribute_validation_method, 'camel_case_name': NameStyleConverter(internal_name).to_upper_camel_case(), 'constructor_type': constructor_type, 'context_enabled_feature_name': v8_utilities.context_enabled_feature_name(attribute), 'cpp_name': cpp_name(attribute), 'cpp_type': cpp_type, 'cpp_type_initializer': idl_type.cpp_type_initializer, 'deprecate_as': deprecate_as, 'does_generate_getter': does_generate_getter, 'does_generate_setter': does_generate_setter, 'enum_type': idl_type.enum_type, 'enum_values': idl_type.enum_values, # [Exposed] 'exposed_test': v8_utilities.exposed(attribute, interface), 'getter_has_no_side_effect': has_extended_attribute_value(attribute, 'Affects', 'Nothing'), 'has_cross_origin_getter': has_extended_attribute_value(attribute, 'CrossOrigin', None) or has_extended_attribute_value(attribute, 'CrossOrigin', 'Getter'), 'has_cross_origin_setter': has_extended_attribute_value(attribute, 'CrossOrigin', 'Setter'), 'has_custom_getter': has_custom_getter(attribute), 'has_custom_setter': has_custom_setter(attribute), 'has_promise_type': idl_type.name == 'Promise', 'has_setter': has_setter(interface, attribute), 'high_entropy': high_entropy, 'idl_type': str(idl_type), 'is_cached_accessor': is_cached_accessor, 'is_call_with_execution_context': has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'), 'is_call_with_script_state': has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'), 'is_ce_reactions': is_ce_reactions, 'is_check_security_for_receiver': is_check_security_for_receiver, 'is_check_security_for_return_value': is_check_security_for_return_value, 'is_custom_element_callbacks': is_custom_element_callbacks, # TODO(yukishiino): Make all DOM attributes accessor-type properties. 'is_data_type_property': is_data_type_property(interface, attribute), 'is_getter_raises_exception': # [RaisesException] 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in (None, 'Getter'), 'is_keep_alive_for_gc': keep_alive_for_gc, 'is_lazy_data_attribute': is_lazy_data_attribute, 'is_lenient_setter': is_lenient_setter, 'is_lenient_this': 'LegacyLenientThis' in extended_attributes, 'is_nullable': idl_type.is_nullable, 'is_explicit_nullable': idl_type.is_explicit_nullable, 'is_named_constructor': is_named_constructor_attribute(attribute), 'is_partial_interface_member': 'PartialInterfaceImplementedAs' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_put_forwards': 'PutForwards' in extended_attributes, 'is_read_only': attribute.is_read_only, 'is_reflect': is_reflect, 'is_replaceable': 'Replaceable' in attribute.extended_attributes, 'is_save_same_object': is_save_same_object, 'is_static': attribute.is_static, 'is_url': 'URL' in extended_attributes, 'is_unforgeable': is_unforgeable(attribute), 'measure_as': measure_as, 'name': attribute.name, 'on_instance': v8_utilities.on_instance(interface, attribute), 'on_interface': v8_utilities.on_interface(interface, attribute), 'on_prototype': v8_utilities.on_prototype(interface, attribute), # [RuntimeEnabled] for origin trial 'origin_trial_feature_name': v8_utilities.origin_trial_feature_name(attribute, runtime_features), 'private_property_is_shared_between_getter_and_setter': private_property_is_shared_between_getter_and_setter, 'property_attributes': property_attributes(interface, attribute), 'reflect_empty': cpp_content_attribute_value_name( interface, extended_attributes.get('ReflectEmpty')), 'reflect_invalid': cpp_content_attribute_value_name( interface, extended_attributes.get('ReflectInvalid', '')), 'reflect_missing': cpp_content_attribute_value_name( interface, extended_attributes.get('ReflectMissing')), 'reflect_only': reflect_only, # [RuntimeEnabled] if not in origin trial 'runtime_enabled_feature_name': v8_utilities.runtime_enabled_feature_name(attribute, runtime_features), # [SecureContext] 'secure_context_test': v8_utilities.secure_context(attribute, interface), 'use_output_parameter_for_result': idl_type.use_output_parameter_for_result, 'world_suffixes': ( ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else ['']), # [PerWorldBindings] } if not has_custom_getter(attribute): getter_context(interface, attribute, context) if not has_custom_setter(attribute) and has_setter(interface, attribute): setter_context(interface, attribute, interfaces, context) # [RuntimeCallStatsCounter] runtime_call_stats_context(interface, attribute, context) # [CrossOrigin] is incompatible with a number of other attributes, so check # for them here. if is_cross_origin: if context['has_cross_origin_setter'] and context['has_custom_setter']: raise Exception( '[CrossOrigin] and [Custom] are incompatible on the same setter: %s.%s', interface.name, attribute.name) if context['is_per_world_bindings']: raise Exception( '[CrossOrigin] and [PerWorldBindings] are incompatible: %s.%s', interface.name, attribute.name) if context['constructor_type']: raise Exception( '[CrossOrigin] cannot be used for constructors: %s.%s', interface.name, attribute.name) return context
def attribute_context(interface, attribute): idl_type = attribute.idl_type base_idl_type = idl_type.base_type extended_attributes = attribute.extended_attributes idl_type.add_includes_for_type(extended_attributes) if idl_type.enum_values: includes.add('core/inspector/ConsoleMessage.h') # [CheckSecurity] is_do_not_check_security = 'DoNotCheckSecurity' in extended_attributes is_check_security_for_receiver = (has_extended_attribute_value( interface, 'CheckSecurity', 'Receiver') and not is_do_not_check_security) is_check_security_for_return_value = (has_extended_attribute_value( attribute, 'CheckSecurity', 'ReturnValue')) if is_check_security_for_receiver or is_check_security_for_return_value: includes.add('bindings/core/v8/BindingSecurity.h') # [Constructor] # TODO(yukishiino): Constructors are much like methods although constructors # are not methods. Constructors must be data-type properties, and we can # support them as a kind of methods. constructor_type = idl_type.constructor_type_name if is_constructor_attribute( attribute) else None # [CustomElementCallbacks], [Reflect] is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes is_reflect = 'Reflect' in extended_attributes if is_custom_element_callbacks or is_reflect: includes.add('core/dom/custom/CustomElementProcessingStack.h') # [ImplementedInPrivateScript] is_implemented_in_private_script = 'ImplementedInPrivateScript' in extended_attributes if is_implemented_in_private_script: includes.add('bindings/core/v8/PrivateScriptRunner.h') includes.add('core/frame/LocalFrame.h') includes.add('platform/ScriptForbiddenScope.h') # [OnlyExposedToPrivateScript] is_only_exposed_to_private_script = 'OnlyExposedToPrivateScript' in extended_attributes # [PerWorldBindings] if 'PerWorldBindings' in extended_attributes: assert idl_type.is_wrapper_type or 'LogActivity' in extended_attributes, '[PerWorldBindings] should only be used with wrapper types: %s.%s' % ( interface.name, attribute.name) if (base_idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/core/v8/V8ErrorHandler.h') cached_attribute_validation_method = extended_attributes.get( 'CachedAttribute') keep_alive_for_gc = is_keep_alive_for_gc(interface, attribute) if cached_attribute_validation_method or keep_alive_for_gc: includes.add('bindings/core/v8/V8HiddenValue.h') if 'RuntimeEnabled' in extended_attributes: includes.add('platform/RuntimeEnabledFeatures.h') if 'OriginTrialEnabled' in extended_attributes: includes.add('core/inspector/ConsoleMessage.h') includes.add('core/origin_trials/OriginTrials.h') context = { 'access_control_list': access_control_list(interface, attribute), 'activity_logging_world_list_for_getter': v8_utilities.activity_logging_world_list(attribute, 'Getter'), # [ActivityLogging] 'activity_logging_world_list_for_setter': v8_utilities.activity_logging_world_list(attribute, 'Setter'), # [ActivityLogging] 'activity_logging_world_check': v8_utilities.activity_logging_world_check(attribute), # [ActivityLogging] 'argument_cpp_type': idl_type.cpp_type_args(used_as_rvalue_type=True), 'cached_attribute_validation_method': cached_attribute_validation_method, 'constructor_type': constructor_type, 'cpp_name': cpp_name(attribute), 'cpp_type': idl_type.cpp_type, 'cpp_type_initializer': idl_type.cpp_type_initializer, 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs] 'enum_type': idl_type.enum_type, 'enum_values': idl_type.enum_values, 'exposed_test': v8_utilities.exposed(attribute, interface), # [Exposed] 'has_custom_getter': has_custom_getter(attribute), 'has_custom_setter': has_custom_setter(attribute), 'has_setter': has_setter(attribute), 'idl_type': str(idl_type), # need trailing [] on array for Dictionary::ConversionContext::setConversionType 'is_origin_trial_enabled': v8_utilities.origin_trial_enabled_function(attribute) or v8_utilities.origin_trial_enabled_function(interface), # [OriginTrialEnabled] 'is_call_with_execution_context': has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'), 'is_call_with_script_state': has_extended_attribute_value(attribute, 'CallWith', 'ScriptState'), 'is_check_security_for_receiver': is_check_security_for_receiver, 'is_check_security_for_return_value': is_check_security_for_return_value, 'is_custom_element_callbacks': is_custom_element_callbacks, # TODO(yukishiino): Make all DOM attributes accessor-type properties. 'is_data_type_property': constructor_type or interface.name == 'Window' or interface.name == 'Location', 'is_getter_raises_exception': # [RaisesException] 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in (None, 'Getter'), 'is_implemented_in_private_script': is_implemented_in_private_script, 'is_keep_alive_for_gc': keep_alive_for_gc, 'is_lenient_this': 'LenientThis' in extended_attributes, 'is_nullable': idl_type.is_nullable, 'is_explicit_nullable': idl_type.is_explicit_nullable, 'is_partial_interface_member': 'PartialInterfaceImplementedAs' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_put_forwards': 'PutForwards' in extended_attributes, 'is_read_only': attribute.is_read_only, 'is_reflect': is_reflect, 'is_replaceable': 'Replaceable' in attribute.extended_attributes, 'is_static': attribute.is_static, 'is_url': 'URL' in extended_attributes, 'is_unforgeable': is_unforgeable(interface, attribute), 'on_instance': v8_utilities.on_instance(interface, attribute), 'on_interface': v8_utilities.on_interface(interface, attribute), 'on_prototype': v8_utilities.on_prototype(interface, attribute), 'origin_trial_enabled': v8_utilities.origin_trial_enabled_function(attribute), # [OriginTrialEnabled] 'origin_trial_enabled_per_interface': v8_utilities.origin_trial_enabled_function(interface), # [OriginTrialEnabled] 'origin_trial_name': extended_attributes.get('OriginTrialEnabled'), # [OriginTrialEnabled] 'use_output_parameter_for_result': idl_type.use_output_parameter_for_result, 'measure_as': v8_utilities.measure_as(attribute, interface), # [MeasureAs] 'name': attribute.name, 'only_exposed_to_private_script': is_only_exposed_to_private_script, 'private_script_v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value( extended_attributes, 'v8Value', 'cppValue', bailout_return_value='false', isolate='scriptState->isolate()'), 'property_attributes': property_attributes(interface, attribute), 'reflect_empty': extended_attributes.get('ReflectEmpty'), 'reflect_invalid': extended_attributes.get('ReflectInvalid', ''), 'reflect_missing': extended_attributes.get('ReflectMissing'), 'reflect_only': extended_attribute_value_as_list(attribute, 'ReflectOnly'), 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(attribute), # [RuntimeEnabled] 'should_be_exposed_to_script': not (is_implemented_in_private_script and is_only_exposed_to_private_script), 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] } if is_constructor_attribute(attribute): update_constructor_attribute_context(interface, attribute, context) if not has_custom_getter(attribute): getter_context(interface, attribute, context) if not has_custom_setter(attribute) and has_setter(attribute): setter_context(interface, attribute, context) return context