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 add_includes_for_operation(operation): v8_types.add_includes_for_type(operation.idl_type) for argument in operation.arguments: v8_types.add_includes_for_type(argument.idl_type)
def generate_attribute(interface, attribute): idl_type = attribute.idl_type extended_attributes = attribute.extended_attributes v8_types.add_includes_for_type(idl_type) # [CheckSecurity] is_check_security_for_node = 'CheckSecurity' in extended_attributes if is_check_security_for_node: includes.add('bindings/v8/BindingSecurity.h') # [Custom] has_custom_getter = ('Custom' in extended_attributes and extended_attributes['Custom'] in [None, 'Getter']) has_custom_setter = (not attribute.is_read_only and 'Custom' in extended_attributes and extended_attributes['Custom'] in [None, 'Setter']) # [RaisesException] is_getter_raises_exception = ( 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in [None, 'Getter']) if is_check_security_for_node or is_getter_raises_exception: includes.add('bindings/v8/ExceptionMessages.h') # [Reflect] is_reflect = 'Reflect' in extended_attributes if is_reflect: includes.add('core/dom/custom/CustomElementCallbackDispatcher.h') if (idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') contents = { 'access_control_list': access_control_list(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] 'cached_attribute_validation_method': extended_attributes.get('CachedAttribute'), 'conditional_string': v8_utilities.conditional_string(attribute), 'constructor_type': v8_types.constructor_type(idl_type) if is_constructor_attribute(attribute) else None, 'cpp_name': cpp_name(attribute), 'cpp_type': v8_types.cpp_type(idl_type), 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs] 'enum_validation_expression': v8_utilities.enum_validation_expression(idl_type), 'has_custom_getter': has_custom_getter, 'has_custom_setter': has_custom_setter, 'has_strict_type_checking': ( 'StrictTypeChecking' in extended_attributes and v8_types.is_interface_type(idl_type)), 'idl_type': idl_type, 'is_call_with_execution_context': v8_utilities.has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'), 'is_check_security_for_node': is_check_security_for_node, 'is_expose_js_accessors': 'ExposeJSAccessors' in extended_attributes, 'is_getter_raises_exception': ( 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in [None, 'Getter']), 'is_initialized_by_event_constructor': 'InitializedByEventConstructor' in extended_attributes, 'is_keep_alive_for_gc': is_keep_alive_for_gc(attribute), 'is_nullable': attribute.is_nullable, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_read_only': attribute.is_read_only, 'is_reflect': is_reflect, 'is_replaceable': 'Replaceable' in attribute.extended_attributes, 'is_setter_raises_exception': ( 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in [None, 'Setter']), 'is_static': attribute.is_static, 'is_unforgeable': 'Unforgeable' in extended_attributes, 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs] 'name': attribute.name, 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name(attribute), # [PerContextEnabled] 'property_attributes': property_attributes(attribute), 'setter_callback': setter_callback_name(interface, attribute), 'v8_type': v8_types.v8_type(idl_type), 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(attribute), # [RuntimeEnabled] 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] } if is_constructor_attribute(attribute): return contents if not has_custom_getter: generate_getter(interface, attribute, contents) if not(attribute.is_read_only or has_custom_setter): contents.update({ 'cpp_setter': setter_expression(interface, attribute, contents), 'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value( idl_type, extended_attributes, 'jsValue', 'cppValue'), }) return contents
def generate_interface(interface): includes.clear() includes.update(INTERFACE_CPP_INCLUDES) header_includes = INTERFACE_H_INCLUDES parent_interface = interface.parent if parent_interface: header_includes.update(v8_types.includes_for_type(parent_interface)) extended_attributes = interface.extended_attributes # [CheckSecurity] is_check_security = 'CheckSecurity' in extended_attributes if is_check_security: includes.update(['bindings/v8/BindingSecurity.h', 'bindings/v8/ExceptionState.h']) # [GenerateVisitDOMWrapper] generate_visit_dom_wrapper_function = extended_attributes.get('GenerateVisitDOMWrapper') if generate_visit_dom_wrapper_function: includes.update(['bindings/v8/V8GCController.h', 'core/dom/Element.h']) # [MeasureAs] is_measure_as = 'MeasureAs' in extended_attributes if is_measure_as: includes.add('core/frame/UseCounter.h') # [RaisesException=Constructor] is_constructor_raises_exception = extended_attributes.get('RaisesException') == 'Constructor' if is_constructor_raises_exception: includes.add('bindings/v8/ExceptionState.h') # [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_type(special_wrap_interface) # Constructors # [Constructor] has_constructor = 'Constructor' in extended_attributes if has_constructor: includes.add('bindings/v8/V8ObjectConstructor.h') # [EventConstructor] has_event_constructor = 'EventConstructor' in extended_attributes has_any_type_attributes = any(attribute for attribute in interface.attributes if attribute.idl_type == 'any') if has_event_constructor: includes.update(['bindings/v8/Dictionary.h', 'bindings/v8/V8ObjectConstructor.h']) if has_any_type_attributes: includes.add('bindings/v8/SerializedScriptValue.h') template_contents = { 'conditional_string': conditional_string(interface), # [Conditional] 'constructor_arguments': constructor_arguments(interface), 'cpp_class': cpp_name(interface), 'generate_visit_dom_wrapper_function': generate_visit_dom_wrapper_function, 'has_constructor': has_constructor, '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_event_constructor': has_event_constructor, 'has_any_type_attributes': has_any_type_attributes, 'has_visit_dom_wrapper': ( # [Custom=Wrap], [GenerateVisitDOMWrapper] has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or 'GenerateVisitDOMWrapper' in extended_attributes), 'header_includes': header_includes, 'interface_name': interface.name, 'is_active_dom_object': 'ActiveDOMObject' in extended_attributes, # [ActiveDOMObject] 'is_check_security': is_check_security, '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': is_constructor_raises_exception, 'is_dependent_lifetime': 'DependentLifetime' in extended_attributes, # [DependentLifetime] 'length': 1 if has_event_constructor else 0, # FIXME: more complex in general, see discussion of length in http://heycam.github.io/webidl/#es-interface-call 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] 'parent_interface': parent_interface, 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled] 'special_wrap_for': special_wrap_for, 'v8_class': v8_utilities.v8_class_name(interface), } template_contents.update({ 'constants': [generate_constant(constant) for constant in interface.constants], 'do_not_check_constants': 'DoNotCheckConstants' in extended_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_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 = [v8_methods.generate_method(interface, method) for method in interface.operations] generate_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, }) return template_contents
def generate_attribute(interface, attribute): idl_type = attribute.idl_type extended_attributes = attribute.extended_attributes v8_types.add_includes_for_type(idl_type) # [CheckSecurity] is_check_security_for_node = 'CheckSecurity' in extended_attributes if is_check_security_for_node: includes.add('bindings/v8/BindingSecurity.h') # [Custom] has_custom_getter = ('Custom' in extended_attributes and extended_attributes['Custom'] in [None, 'Getter']) has_custom_setter = (not attribute.is_read_only and 'Custom' in extended_attributes and extended_attributes['Custom'] in [None, 'Setter']) # [Reflect] is_reflect = 'Reflect' in extended_attributes if is_reflect: includes.add('core/dom/custom/CustomElementCallbackDispatcher.h') if (idl_type == 'EventHandler' and interface.name in ['Window', 'WorkerGlobalScope'] and attribute.name == 'onerror'): includes.add('bindings/v8/V8ErrorHandler.h') contents = { 'access_control_list': access_control_list(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] 'cached_attribute_validation_method': extended_attributes.get('CachedAttribute'), 'conditional_string': v8_utilities.conditional_string(attribute), 'constructor_type': v8_types.constructor_type(idl_type) if is_constructor_attribute(attribute) else None, 'cpp_name': cpp_name(attribute), 'cpp_type': v8_types.cpp_type(idl_type), 'deprecate_as': v8_utilities.deprecate_as(attribute), # [DeprecateAs] 'enum_validation_expression': v8_utilities.enum_validation_expression(idl_type), 'has_custom_getter': has_custom_getter, 'has_custom_setter': has_custom_setter, 'has_strict_type_checking': ('StrictTypeChecking' in extended_attributes and v8_types.is_interface_type(idl_type)), 'idl_type': idl_type, 'is_call_with_execution_context': v8_utilities.has_extended_attribute_value(attribute, 'CallWith', 'ExecutionContext'), 'is_check_security_for_node': is_check_security_for_node, 'is_expose_js_accessors': 'ExposeJSAccessors' in extended_attributes, 'is_getter_raises_exception': ( # [RaisesException] 'RaisesException' in extended_attributes and extended_attributes['RaisesException'] in [None, 'Getter']), 'is_initialized_by_event_constructor': 'InitializedByEventConstructor' in extended_attributes, 'is_keep_alive_for_gc': is_keep_alive_for_gc(attribute), 'is_nullable': attribute.is_nullable, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_read_only': attribute.is_read_only, 'is_reflect': is_reflect, 'is_replaceable': 'Replaceable' in attribute.extended_attributes, 'is_setter_raises_exception': ('RaisesException' in extended_attributes and extended_attributes['RaisesException'] in [None, 'Setter']), 'is_static': attribute.is_static, 'is_unforgeable': 'Unforgeable' in extended_attributes, 'measure_as': v8_utilities.measure_as(attribute), # [MeasureAs] 'name': attribute.name, 'per_context_enabled_function': v8_utilities.per_context_enabled_function_name( attribute), # [PerContextEnabled] 'property_attributes': property_attributes(attribute), 'setter_callback': setter_callback_name(interface, attribute), 'v8_type': v8_types.v8_type(idl_type), 'runtime_enabled_function': v8_utilities.runtime_enabled_function_name( attribute), # [RuntimeEnabled] 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] } if is_constructor_attribute(attribute): return contents if not has_custom_getter: generate_getter(interface, attribute, contents) if not (attribute.is_read_only or has_custom_setter): contents.update({ 'cpp_setter': setter_expression(interface, attribute, contents), 'v8_value_to_local_cpp_value': v8_types.v8_value_to_local_cpp_value(idl_type, extended_attributes, 'jsValue', 'cppValue'), }) return contents
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 v8_types.add_includes_for_type(idl_type) this_cpp_value = cpp_value(interface, method, len(arguments)) def function_template(): if is_static: return 'functionTemplate' if 'Unforgeable' in extended_attributes: return 'instanceTemplate' return 'prototypeTemplate' 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') is_check_security_for_frame = ( 'CheckSecurity' in interface.extended_attributes and 'DoNotCheckSecurity' not in extended_attributes) is_raises_exception = 'RaisesException' in extended_attributes return { '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, 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs] 'do_not_check_signature': not(is_static or v8_utilities.has_extended_attribute(method, ['DoNotCheckSecurity', 'DoNotCheckSignature', 'NotEnumerable', 'ReadOnly', 'RuntimeEnabled', 'Unforgeable'])), 'function_template': function_template(), 'idl_type': idl_type, 'has_exception_state': is_raises_exception or is_check_security_for_frame or any(argument for argument in arguments if argument.idl_type == 'SerializedScriptValue' or v8_types.is_integer_type(argument.idl_type)) or name in ['addEventListener', 'removeEventListener'], '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': is_check_security_for_frame, '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_do_not_check_signature': 'DoNotCheckSignature' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_raises_exception': is_raises_exception, 'is_read_only': 'ReadOnly' in extended_attributes, 'is_static': is_static, 'is_strict_type_checking': 'StrictTypeChecking' in extended_attributes or 'StrictTypeChecking' in interface.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': 'v8::Local<v8::Signature>()' if is_static or 'DoNotCheckSignature' in extended_attributes else 'defaultSignature', 'union_arguments': union_arguments(idl_type), 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True), 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value), 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] }
def add_includes_for_operation(operation): add_includes_for_type(operation.idl_type) for argument in operation.arguments: add_includes_for_type(argument.idl_type)
def generate_interface(interface): includes.clear() includes.update(INTERFACE_CPP_INCLUDES) header_includes = INTERFACE_H_INCLUDES parent_interface = interface.parent if parent_interface: header_includes.update(v8_types.includes_for_type(parent_interface)) extended_attributes = interface.extended_attributes # [CheckSecurity] is_check_security = 'CheckSecurity' in extended_attributes if is_check_security: includes.add('bindings/v8/BindingSecurity.h') # [GenerateVisitDOMWrapper] generate_visit_dom_wrapper_function = extended_attributes.get( 'GenerateVisitDOMWrapper') if generate_visit_dom_wrapper_function: includes.update(['bindings/v8/V8GCController.h', 'core/dom/Element.h']) # [MeasureAs] is_measure_as = 'MeasureAs' in extended_attributes if is_measure_as: includes.add('core/frame/UseCounter.h') # [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_type(special_wrap_interface) # 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' ] generate_constructor_overloads(constructors) # [CustomConstructor] has_custom_constructor = 'CustomConstructor' in extended_attributes # [EventConstructor] has_event_constructor = 'EventConstructor' in extended_attributes any_type_attributes = [ attribute for attribute in interface.attributes if attribute.idl_type == 'any' ] if has_event_constructor: includes.add('bindings/v8/Dictionary.h') if any_type_attributes: includes.add('bindings/v8/SerializedScriptValue.h') # [NamedConstructor] if 'NamedConstructor' in extended_attributes: # FIXME: parser should return named constructor separately; # included in constructors (and only name stored in extended attribute) # for Perl compatibility named_constructor = {'name': extended_attributes['NamedConstructor']} else: named_constructor = None if (constructors or has_custom_constructor or has_event_constructor or named_constructor): includes.add('bindings/v8/V8ObjectConstructor.h') template_contents = { 'any_type_attributes': any_type_attributes, 'conditional_string': conditional_string(interface), # [Conditional] 'constructors': constructors, 'cpp_class': cpp_name(interface), 'generate_visit_dom_wrapper_function': generate_visit_dom_wrapper_function, 'has_custom_constructor': has_custom_constructor, '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_event_constructor': has_event_constructor, 'has_visit_dom_wrapper': ( # [Custom=Wrap], [GenerateVisitDOMWrapper] has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or 'GenerateVisitDOMWrapper' in extended_attributes), 'header_includes': header_includes, 'interface_length': interface_length(interface, constructors), 'interface_name': interface.name, 'is_active_dom_object': 'ActiveDOMObject' in extended_attributes, # [ActiveDOMObject] 'is_check_security': is_check_security, '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] 'is_dependent_lifetime': 'DependentLifetime' in extended_attributes, # [DependentLifetime] 'is_event_target': inherits_interface(interface, 'EventTarget'), 'is_node': inherits_interface(interface, 'Node'), 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] 'named_constructor': named_constructor, 'parent_interface': parent_interface, 'runtime_enabled_function': runtime_enabled_function_name(interface), # [RuntimeEnabled] 'special_wrap_for': special_wrap_for, 'v8_class': v8_utilities.v8_class_name(interface), } template_contents.update({ 'constants': [generate_constant(constant) for constant in interface.constants], 'do_not_check_constants': 'DoNotCheckConstants' in extended_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_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 = [ v8_methods.generate_method(interface, method) for method in interface.operations ] generate_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, }) return template_contents
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 v8_types.add_includes_for_type(idl_type) this_cpp_value = cpp_value(interface, method, len(arguments)) def function_template(): if is_static: return 'functionTemplate' if 'Unforgeable' in extended_attributes: return 'instanceTemplate' return 'prototypeTemplate' 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') is_check_security_for_frame = ( 'CheckSecurity' in interface.extended_attributes and 'DoNotCheckSecurity' not in extended_attributes) is_raises_exception = 'RaisesException' in extended_attributes return { '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, 'deprecate_as': v8_utilities.deprecate_as(method), # [DeprecateAs] 'do_not_check_signature': not (is_static or v8_utilities.has_extended_attribute(method, [ 'DoNotCheckSecurity', 'DoNotCheckSignature', 'NotEnumerable', 'ReadOnly', 'RuntimeEnabled', 'Unforgeable' ])), 'function_template': function_template(), 'idl_type': idl_type, 'has_exception_state': is_raises_exception or is_check_security_for_frame or any(argument for argument in arguments if argument.idl_type == 'SerializedScriptValue' or v8_types.is_integer_type(argument.idl_type)) or name in ['addEventListener', 'removeEventListener', 'dispatchEvent'], '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': is_check_security_for_frame, '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_do_not_check_signature': 'DoNotCheckSignature' in extended_attributes, 'is_per_world_bindings': 'PerWorldBindings' in extended_attributes, 'is_raises_exception': is_raises_exception, 'is_read_only': 'ReadOnly' in extended_attributes, 'is_static': is_static, 'is_strict_type_checking': 'StrictTypeChecking' in extended_attributes or 'StrictTypeChecking' in interface.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': 'v8::Local<v8::Signature>()' if is_static or 'DoNotCheckSignature' in extended_attributes else 'defaultSignature', 'union_arguments': union_arguments(idl_type), 'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True), 'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value), 'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''], # [PerWorldBindings] }
def generate_interface(interface): includes.clear() includes.update(INTERFACE_CPP_INCLUDES) header_includes = INTERFACE_H_INCLUDES parent_interface = interface.parent if parent_interface: header_includes.update(v8_types.includes_for_type(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/Frame.h']) # [CheckSecurity] is_check_security = 'CheckSecurity' in extended_attributes if is_check_security: includes.add('bindings/v8/BindingSecurity.h') # [SetWrapperReferenceFrom] reachable_node_function = extended_attributes.get('SetWrapperReferenceFrom') if reachable_node_function: includes.update(['bindings/v8/V8GCController.h', 'core/dom/Element.h']) # [MeasureAs] is_measure_as = 'MeasureAs' in extended_attributes if is_measure_as: includes.add('core/frame/UseCounter.h') # [SetWrapperReferenceTo] set_wrapper_reference_to_list = [{ 'name': argument.name, 'idl_type': argument.idl_type, 'v8_type': v8_types.v8_type(argument.idl_type), } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] for set_wrapper_reference_to in set_wrapper_reference_to_list: v8_types.add_includes_for_type(set_wrapper_reference_to['idl_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_type(special_wrap_interface) template_contents = { 'conditional_string': conditional_string(interface), # [Conditional] 'cpp_class': cpp_name(interface), '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': ( # [Custom=Wrap], [SetWrapperReferenceFrom] has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or reachable_node_function or set_wrapper_reference_to_list), 'header_includes': header_includes, 'interface_name': interface.name, 'is_active_dom_object': 'ActiveDOMObject' in extended_attributes, # [ActiveDOMObject] 'is_audio_buffer': is_audio_buffer, 'is_check_security': is_check_security, 'is_dependent_lifetime': 'DependentLifetime' in extended_attributes, # [DependentLifetime] '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, '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), } # 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'] generate_constructor_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 == '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') 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_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] generate_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, }) return template_contents
def generate_interface(interface): includes.clear() includes.update(INTERFACE_CPP_INCLUDES) header_includes = INTERFACE_H_INCLUDES parent_interface = interface.parent if parent_interface: header_includes.update(v8_types.includes_for_type(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/Frame.h']) # [CheckSecurity] is_check_security = 'CheckSecurity' in extended_attributes if is_check_security: includes.add('bindings/v8/BindingSecurity.h') # [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, 'idl_type': argument.idl_type, 'v8_type': v8_types.v8_type(argument.idl_type), } for argument in extended_attributes.get('SetWrapperReferenceTo', [])] for set_wrapper_reference_to in set_wrapper_reference_to_list: v8_types.add_includes_for_type(set_wrapper_reference_to['idl_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_type(special_wrap_interface) # [WillBeGarbageCollected] is_will_be_garbage_collected = 'WillBeGarbageCollected' in extended_attributes template_contents = { 'conditional_string': conditional_string(interface), # [Conditional] 'cpp_class': cpp_name(interface), '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': ( # [Custom=Wrap], [SetWrapperReferenceFrom] has_extended_attribute_value(interface, 'Custom', 'VisitDOMWrapper') or reachable_node_function or set_wrapper_reference_to_list), 'header_includes': header_includes, 'interface_name': interface.name, 'is_active_dom_object': 'ActiveDOMObject' in extended_attributes, # [ActiveDOMObject] 'is_audio_buffer': is_audio_buffer, 'is_check_security': is_check_security, 'is_dependent_lifetime': 'DependentLifetime' in extended_attributes, # [DependentLifetime] 'is_document': is_document, 'is_event_target': inherits_interface(interface.name, 'EventTarget'), 'is_exception': interface.is_exception, 'is_will_be_garbage_collected': is_will_be_garbage_collected, 'is_node': inherits_interface(interface.name, 'Node'), 'measure_as': v8_utilities.measure_as(interface), # [MeasureAs] 'parent_interface': parent_interface, 'pass_ref_ptr': 'PassRefPtrWillBeRawPtr' if is_will_be_garbage_collected else 'PassRefPtr', 'reachable_node_function': reachable_node_function, 'ref_ptr': 'RefPtrWillBeRawPtr' if is_will_be_garbage_collected else 'RefPtr', '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), } # 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'] generate_constructor_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 == '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') 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_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