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 v8_set_return_value(interface_name, method, cpp_value, for_main_world=False): idl_type = method.idl_type extended_attributes = method.extended_attributes if idl_type == 'void': return None is_union_type = v8_types.is_union_type(idl_type) release = False # [CallWith=ScriptState], [RaisesException] if (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or 'RaisesException' in extended_attributes or is_union_type): # use local variable for value cpp_value = 'result' if is_union_type: release = [ v8_types.is_interface_type(union_member_type) for union_member_type in idl_type.union_member_types ] else: release = v8_types.is_interface_type(idl_type) script_wrappable = 'imp' if v8_types.inherits_interface( interface_name, 'Node') else '' return v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes, script_wrappable=script_wrappable, release=release, for_main_world=for_main_world)
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 v8_set_return_value(method, cpp_value): idl_type = method.idl_type if idl_type == 'void': return None # [CallWith=ScriptState] if has_extended_attribute_value(method, 'CallWith', 'ScriptState'): cpp_value = 'result' # use local variable for value return v8_types.v8_set_return_value(idl_type, cpp_value, method.extended_attributes)
def v8_set_return_value_statement(): if contents['is_keep_alive_for_gc']: return 'v8SetReturnValue(info, wrapper)' if attribute.is_nullable and v8_types.is_interface_type(idl_type): set_cpp_value = 'jsValue.release()' else: set_cpp_value = cpp_value return v8_types.v8_set_return_value(idl_type, set_cpp_value, extended_attributes=extended_attributes, script_wrappable='imp')
def v8_set_return_value_statement(for_main_world=False): if contents['is_keep_alive_for_gc']: return 'v8SetReturnValue(info, wrapper)' return v8_types.v8_set_return_value( idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp', release=release, for_main_world=for_main_world)
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 property_getter(getter, cpp_arguments): def is_null_expression(idl_type): if v8_types.is_union_type(idl_type): return ' && '.join('!result%sEnabled' % i for i, _ in enumerate(idl_type.union_member_types)) if idl_type == 'DOMString': return 'result.isNull()' if is_interface_type(idl_type): return '!result' return '' idl_type = getter.idl_type extended_attributes = getter.extended_attributes is_raises_exception = 'RaisesException' in extended_attributes if v8_types.is_union_type(idl_type): release = [v8_types.is_interface_type(union_member_type) for union_member_type in idl_type.union_member_types] else: release = v8_types.is_interface_type(idl_type) # FIXME: make more generic, so can use v8_methods.cpp_value cpp_method_name = 'imp->%s' % cpp_name(getter) if is_raises_exception: cpp_arguments.append('exceptionState') this_union_arguments = v8_methods.union_arguments(idl_type) if this_union_arguments: cpp_arguments.extend(this_union_arguments) cpp_value = '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments)) return { 'cpp_type': v8_types.cpp_type(idl_type), 'cpp_value': cpp_value, 'is_custom': 'Custom' in extended_attributes and (not extended_attributes['Custom'] or has_extended_attribute_value(getter, 'Custom', 'PropertyGetter')), 'is_custom_property_enumerator': has_extended_attribute_value( getter, 'Custom', 'PropertyEnumerator'), 'is_custom_property_query': has_extended_attribute_value( getter, 'Custom', 'PropertyQuery'), 'is_enumerable': 'NotEnumerable' not in extended_attributes, 'is_null_expression': is_null_expression(idl_type), 'is_raises_exception': is_raises_exception, 'name': cpp_name(getter), 'union_arguments': v8_methods.union_arguments(idl_type), 'v8_set_return_value': v8_types.v8_set_return_value(idl_type, 'result', extended_attributes=extended_attributes, script_wrappable='imp', release=release), }
def v8_set_return_value(interface_name, method, cpp_value): idl_type = method.idl_type extended_attributes = method.extended_attributes if idl_type == 'void': return None # [CallWith=ScriptState], [RaisesException] if (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or 'RaisesException' in extended_attributes): # use local variable for value if v8_types.is_interface_type(idl_type): cpp_value = 'result.release()' else: cpp_value = 'result' script_wrappable = 'imp' if v8_types.inherits_interface(interface_name, 'Node') else '' return v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes, script_wrappable=script_wrappable)
def cpp_method(method, number_of_arguments): def cpp_argument(argument): if argument.idl_type in ['NodeFilter', 'XPathNSResolver']: # FIXME: remove this special case return '%s.get()' % argument.name return argument.name # Truncate omitted optional arguments arguments = method.arguments[:number_of_arguments] cpp_arguments = [cpp_argument(argument) for argument in arguments] cpp_value = 'imp->%s(%s)' % (method.name, ', '.join(cpp_arguments)) idl_type = method.idl_type if idl_type == 'void': return cpp_value return v8_types.v8_set_return_value(idl_type, cpp_value)
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 v8_set_return_value(interface_name, method, cpp_value, for_main_world=False): idl_type = method.idl_type extended_attributes = method.extended_attributes if idl_type == 'void': return None is_union_type = v8_types.is_union_type(idl_type) release = False # [CallWith=ScriptState], [RaisesException] if (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or 'RaisesException' in extended_attributes or is_union_type): # use local variable for value cpp_value = 'result' if is_union_type: release = [v8_types.is_interface_type(union_member_type) for union_member_type in idl_type.union_member_types] else: release = v8_types.is_interface_type(idl_type) script_wrappable = 'imp' if v8_types.inherits_interface(interface_name, 'Node') else '' return v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes, script_wrappable=script_wrappable, release=release, for_main_world=for_main_world)
def generate_attribute_and_includes(attribute): idl_type = attribute.data_type # FIXME: need to check should_keep_attribute_alive, but for now sufficient # to check if primitive. should_keep_attribute_alive = not v8_types.primitive_type(idl_type) if should_keep_attribute_alive: return_v8_value_statement = None # unused includes = v8_types.includes_for_type(idl_type) includes.add('bindings/v8/V8HiddenPropertyName.h') else: cpp_value = 'imp->%s()' % uncapitalize(attribute.name) return_v8_value_statement = v8_types.v8_set_return_value(idl_type, cpp_value, callback_info='info') includes = [] contents = { 'name': attribute.name, 'conditional_string': generate_conditional_string(attribute), 'cpp_method_name': cpp_method_name(attribute), 'cpp_type': v8_types.cpp_type(idl_type, pointer_type='RefPtr'), 'should_keep_attribute_alive': should_keep_attribute_alive, 'return_v8_value_statement': return_v8_value_statement, 'v8_type': v8_types.v8_type(idl_type), } return contents, includes
def v8_set_return_value_statement(for_main_world=False): if contents['is_keep_alive_for_gc']: return 'v8SetReturnValue(info, wrapper)' return v8_types.v8_set_return_value(idl_type, cpp_value, extended_attributes=extended_attributes, script_wrappable='imp', release=release, for_main_world=for_main_world)