| Index: Source/bindings/scripts/v8_functions.py | 
| diff --git a/Source/bindings/scripts/v8_functions.py b/Source/bindings/scripts/v8_functions.py | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..585fe31cc05da05b6c2350946a33c4b2f6f6792f | 
| --- /dev/null | 
| +++ b/Source/bindings/scripts/v8_functions.py | 
| @@ -0,0 +1,421 @@ | 
| +# Copyright (C) 2013 Google Inc. All rights reserved. | 
| +# | 
| +# Redistribution and use in source and binary forms, with or without | 
| +# modification, are permitted provided that the following conditions are | 
| +# met: | 
| +# | 
| +#     * Redistributions of source code must retain the above copyright | 
| +# notice, this list of conditions and the following disclaimer. | 
| +#     * Redistributions in binary form must reproduce the above | 
| +# copyright notice, this list of conditions and the following disclaimer | 
| +# in the documentation and/or other materials provided with the | 
| +# distribution. | 
| +#     * Neither the name of Google Inc. nor the names of its | 
| +# contributors may be used to endorse or promote products derived from | 
| +# this software without specific prior written permission. | 
| +# | 
| +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
| +# 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
| +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
| +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
| +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
| +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
| +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
| +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
| +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
| +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| + | 
| +"""Generate template values for functions. | 
| + | 
| +FIXME: rename "parameter/parameters": | 
| +"template parameters" is easily confused with "function parameters" | 
| +Also, "parameter*s*", not "parameter". | 
| +""" | 
| + | 
| + | 
| +from code_generator_idl_reader import implemented_as_from_implemented_by | 
| +from v8_includes import * | 
| +from v8_types import * | 
| +from v8_utilities import extended_attribute_contains, generate_conditional_string, get_raises_exception, runtime_enable_function_name, implemented_as_cpp_name | 
| +from v8_values import get_js_value_to_native_statement, get_native_to_js_value_statement, get_pass_owner_expression | 
| + | 
| +from v8_utilities import ACTIVITY_LOGGING_INCLUDES, get_call_with_parameter, get_custom_element_invocation_scope_parameter, get_deprecation_notification_parameter, get_function_mandatory_parameters, get_feature_observation_parameter, has_activity_logging | 
| + | 
| + | 
| +def generate_functions(interface): | 
| +    # FIXME: clearer with a list comprehension + nested function to handle includes | 
| +    functions = [] | 
| +    includes = [] | 
| +    for function in interface.operations: | 
| +        function_contents, function_includes = generate_function(interface, function) | 
| +#             print '[FUNC]', function_contents | 
| +        functions.append(function_contents) | 
| +        includes += function_includes | 
| +    return functions, includes | 
| + | 
| + | 
| +def generate_function(interface, function): | 
| +    includes = [] | 
| +    name = function.name | 
| +    cpp_class_name = implemented_as_cpp_name(interface) | 
| +    is_normal_function = function.name and 'EnabledPerContext' not in function.extended_attributes | 
| +    is_standard_function = get_is_standard_function(interface, function) | 
| +    is_custom = has_custom_implementation(function) | 
| + | 
| +    per_world_bindings = 'PerWorldBindings' in function.extended_attributes | 
| +    for_main_world_suffixes = [''] | 
| +    if per_world_bindings: | 
| +        for_main_world_suffixes.append('ForMainWorld') | 
| + | 
| +    activity_logging = set() | 
| +    setter_function_call_parameter = {} | 
| +    for for_main_world_suffix in for_main_world_suffixes: | 
| +        if has_activity_logging(for_main_world_suffix, function.extended_attributes, 'Method'): | 
| +            activity_logging.add(for_main_world_suffix) | 
| +            includes += ACTIVITY_LOGGING_INCLUDES | 
| + | 
| +    check_security_for_node = 'CheckSecurityForNode' in function.extended_attributes | 
| +    if check_security_for_node: | 
| +        includes.append('bindings/v8/BindingSecurity.h') | 
| + | 
| +    method_for_main_world = '0' | 
| +    if 'PerWorldBindings' in function.extended_attributes: | 
| +        method_for_main_world = '%sV8Internal::%sMethodCallbackForMainWorld' % (implemented_as_cpp_name(interface), function.name) | 
| +    mandatory_parameters = get_function_mandatory_parameters(function) | 
| + | 
| +    if len(function.overloads) > 1: | 
| +        name = '%s%d' % (name, function.overload_index) | 
| +    is_representative = function.overload_index == 1 | 
| +    conditional_runtime = '' | 
| +    enable_function = '' | 
| +    if 'EnabledAtRuntime' in function.extended_attributes: | 
| +        # Only call Set()/SetAccessor() if this method should be enabled | 
| +        enable_function = runtime_enable_function_name(function) | 
| +        conditional_runtime = 'if (%s())\n        ' % enable_function | 
| +    if function.extended_attributes.get('EnabledPerContext'): | 
| +        # Only call Set()/SetAccessor() if this method should be enabled | 
| +        enable_function = get_context_enable_function(function) | 
| +        conditional_runtime = 'if (%s(impl->document()))' % enable_function | 
| + | 
| +    template = 'proto' | 
| +    if 'Unforgeable' in function.extended_attributes: | 
| +        template = 'instance' | 
| +    if function.is_static: | 
| +        template = 'desc' | 
| + | 
| +    setter = '%sV8Internal::%sDomainSafeFunctionSetter' % (cpp_class_name, cpp_class_name) if 'ReadOnly' not in function.extended_attributes else '0' | 
| + | 
| +    signature = 'defaultSignature' | 
| +    if 'DoNotCheckSignature' in function.extended_attributes or function.is_static: | 
| +        signature = 'v8::Local<v8::Signature>()' | 
| +    requires_custom_signature = get_requires_custom_signature(function) | 
| +    if requires_custom_signature: | 
| +        signature = function.name + 'Signature' | 
| + | 
| +    # FIXME: simplify: additional_property_attributes_list, ' | '.join(...) | 
| +    property_attributes = 'v8::DontDelete' | 
| +    if 'NotEnumerable' in function.extended_attributes: | 
| +        property_attributes += ' | v8::DontEnum' | 
| +    if 'ReadOnly' in function.extended_attributes: | 
| +        property_attributes += ' | v8::ReadOnly' | 
| + | 
| +    if property_attributes == 'v8::DontDelete': | 
| +        property_attributes = '' | 
| +    else: | 
| +        property_attributes = ', static_cast<v8::PropertyAttribute>(%s)' % property_attributes | 
| + | 
| +    custom_signatures = [] | 
| +    if requires_custom_signature: | 
| +        for parameter in function.arguments: | 
| +            if is_wrapper_type(parameter.data_type): | 
| +                if parameter.data_type == 'XPathNSResolver': | 
| +                    # Special case for XPathNSResolver.  All other browsers accepts a callable, | 
| +                    # so, even though it's against IDL, accept objects here. | 
| +                    custom_signatures.append('v8::Handle<v8::FunctionTemplate>()') | 
| +                else: | 
| +                    array_or_sequence_type = get_array_or_sequence_type(parameter.data_type) | 
| + | 
| +                    if array_or_sequence_type: | 
| +                        if is_ref_ptr_type(array_or_sequence_type): | 
| +                            includes += get_includes_for_type(array_or_sequence_type) | 
| +                        else: | 
| +                            custom_signatures.append('v8::Handle<v8::FunctionTemplate>()') | 
| +                            continue | 
| +                    else: | 
| +#                             print '[FOO]', parameter.data_type, 'AS', array_or_sequence_type | 
| +                        includes += get_includes_for_type(parameter.data_type) | 
| +                    custom_signatures.append('V8PerIsolateData::from(isolate)->rawTemplate(&V8%s::info, currentWorldType)' % parameter.data_type) | 
| +            else: | 
| +                custom_signatures.append('v8::Handle<v8::FunctionTemplate>()') | 
| +    custom_signature = ', '.join(custom_signatures) | 
| +    function_call_parameters = {} | 
| +    raises_exception = get_raises_exception(function) | 
| +    if any(['IsIndex' in parameter.extended_attributes | 
| +            for parameter in function.arguments]): | 
| +        raises_exception = True | 
| +    feature_observation_parameter = {} | 
| +    deprecation_notification_parameter = {} | 
| +    custom_element_invocation_scope_parameter = {} | 
| +    parameter_check_parameters = {} | 
| + | 
| +    if not is_custom and name: | 
| +        if raises_exception: | 
| +            includes.append('bindings/v8/ExceptionState.h') | 
| + | 
| +        parameter_check_parameters, parameter_check_includes, replacements = get_parameter_check_parameters(interface, function) | 
| +        includes += parameter_check_includes | 
| + | 
| +        for for_main_world_suffix in for_main_world_suffixes: | 
| +            function_call_parameter, function_call_includes = get_function_call_parameter(interface, function, len(function.arguments), for_main_world_suffix=for_main_world_suffix, replacements=replacements) | 
| +            function_call_parameters[for_main_world_suffix] = function_call_parameter | 
| +            includes += function_call_includes | 
| + | 
| +        comment_info = 'Function "%s" (ExtAttr: "%s")' % (function.name, ' '.join(function.extended_attributes.keys())) | 
| + | 
| +#         if template == 'proto' and conditional_runtime == '' and signature == 'defaultSignature' and property_attributes == '': | 
| +#             raise Exception('This shouldn't happen: Class '%s' %s' % (cpp_class_name, comment_info)) | 
| + | 
| +        custom_element_invocation_scope_parameter, custom_element_invocation_scope_includes = get_custom_element_invocation_scope_parameter(function) | 
| +        includes += custom_element_invocation_scope_includes | 
| + | 
| +        feature_observation_parameter, feature_observation_includes = get_feature_observation_parameter(function) | 
| +        includes += feature_observation_includes | 
| + | 
| +        deprecation_notification_parameter, deprecation_notification_includes = get_deprecation_notification_parameter(function) | 
| +        includes += deprecation_notification_includes | 
| + | 
| +    # print | 
| +    # print '#'*30 | 
| +    # print '[get_function_parameter] ', function.data_type, name | 
| +    contents = { | 
| +        'name': name, | 
| +        'is_static': function.is_static, | 
| +        'is_custom': is_custom, | 
| +        'create_callback': is_representative and is_normal_function and is_standard_function, | 
| +        'is_representative': is_representative, | 
| +        'conditional_runtime': conditional_runtime, | 
| +        'template': template, | 
| +        'setter': setter, | 
| +        'signature': signature, | 
| +        'property_attributes': property_attributes, | 
| +        'requires_custom_signature': requires_custom_signature, | 
| +        'custom_signature': custom_signature, | 
| +        'conditional_string': generate_conditional_string(function), | 
| +        'mandatory_parameters': mandatory_parameters, | 
| +        'length': get_function_mandatory_parameters(function, count_variadic=True), | 
| +        'parameters': parameter_check_parameters, | 
| +        'function_call_parameter': function_call_parameters, | 
| +        'method_for_main_world': method_for_main_world, | 
| +        'is_normal_function': is_normal_function, | 
| +        'is_standard_function': is_standard_function, | 
| +        'is_enabled_per_context_function': function.name and 'EnabledPerContext' in function.extended_attributes, | 
| +        'raises_exception': raises_exception, | 
| +        'do_not_check_security': 'DoNotCheckSecurity' in function.extended_attributes, | 
| +        'for_main_world_suffixes': for_main_world_suffixes, | 
| +        'cpp_name': implemented_as_cpp_name(function), | 
| +        'check_security_for_node': check_security_for_node, | 
| +        'enable_function': enable_function, | 
| +        'activity_logging': activity_logging, | 
| +    } | 
| +    contents.update(feature_observation_parameter) | 
| +    contents.update(deprecation_notification_parameter) | 
| +    contents.update(custom_element_invocation_scope_parameter) | 
| +    return contents, includes | 
| + | 
| + | 
| +def get_function_call_parameter(interface, function, number_of_parameters=None, for_main_world_suffix='', replacements=None): | 
| +    # return parameter for function_call macro, includes | 
| +    replacements = replacements or {} | 
| +    if number_of_parameters is None: | 
| +        number_of_parameters = len(function.arguments) | 
| + | 
| +    includes = [] | 
| +    arguments = [] | 
| +    cpp_class_name = implemented_as_cpp_name(interface) | 
| +    implemented_by = function.extended_attributes.get('ImplementedBy') | 
| +    ### TODO Similar to attribute. merge! | 
| +    if implemented_by: | 
| +        implemented_by_cpp_name = implemented_as_from_implemented_by(implemented_by) | 
| +        includes += header_files_for_interface(implemented_by, implemented_by_cpp_name) | 
| +        function_name = '%s::%s' % (implemented_by_cpp_name, implemented_as_cpp_name(function)) | 
| +        if not function.is_static: | 
| +            arguments.append('imp') | 
| +    elif function.is_static: | 
| +        function_name = '%s::%s' % (cpp_class_name, implemented_as_cpp_name(function)) | 
| +    else: | 
| +        function_name = 'imp->%s' % implemented_as_cpp_name(function) | 
| + | 
| +    call_with = function.extended_attributes.get('CallWith') | 
| +    call_with_arguments, call_with_parameter, call_with_includes = get_call_with_parameter(call_with, return_void=True, function=function) | 
| +    includes += call_with_includes | 
| +    arguments = call_with_arguments + arguments | 
| + | 
| +    parameters = [] | 
| +    for index, parameter in enumerate(function.arguments): | 
| +        svg_tear_off_and_not_list = False | 
| +        if index == number_of_parameters: | 
| +            break | 
| +        if replacements.get(parameter.name): | 
| +            arguments.append(replacements.get(parameter.name)) | 
| +        elif parameter.data_type == 'NodeFilter' or parameter.data_type == 'XPathNSResolver': | 
| +            arguments.append('%s.get()' % parameter.name) | 
| +        elif get_svg_type_needing_tear_off(parameter.data_type) and not interface.name.endswith('List'): | 
| +            includes.append('core/dom/ExceptionCode.h') | 
| +            arguments.append('%s->propertyReference()' % parameter.name) | 
| +            svg_tear_off_and_not_list = True | 
| +        elif parameter.data_type == 'SVGMatrix' and interface.name == 'SVGTransformList': | 
| +            arguments.append('%s.get()' % parameter.name) | 
| +        else: | 
| +            arguments.append(parameter.name) | 
| +        parameter = { | 
| +            'svg_tear_off_and_not_list': svg_tear_off_and_not_list, | 
| +            'name': parameter.name, | 
| +        } | 
| +        parameters.append(parameter) | 
| + | 
| +    if get_raises_exception(function): | 
| +        arguments.append('es') | 
| + | 
| +    function_call_expression = '%s(%s)' % (function_name, ', '.join(arguments)) | 
| +    native_value_expression = get_pass_owner_expression(function.data_type, 'result') | 
| +    function_call_statement = '' | 
| +    if function.data_type == 'void': | 
| +        function_call_statement = '%s;' % function_call_expression | 
| +    elif extended_attribute_contains(function.extended_attributes.get('CallWith'), 'ScriptState') or get_raises_exception(function): | 
| +        function_call_statement = '%s result = %s;' % (get_native_type(function.data_type, extended_attributes=function.extended_attributes), function_call_expression) | 
| +    else: | 
| +        native_value_expression = function_call_expression | 
| + | 
| +    extended_attribute_contains_script_state = extended_attribute_contains(call_with, 'ScriptState') | 
| + | 
| +    script_wrappable = is_dom_node_type(interface.name) and 'imp' or 0 | 
| +    return_js_value_statement = '' | 
| +    return_js_value_statement, native_to_js_value_includes = get_native_to_js_value_statement(function.data_type, function.extended_attributes, native_value_expression, creation_context='args.Holder()', isolate='args.GetIsolate()', callback_info='args', script_wrappable=script_wrappable, for_main_world_suffix=for_main_world_suffix, used_as_return_value=True) | 
| +    includes += native_to_js_value_includes | 
| +#         print '[----]', function.name | 
| + | 
| +    svg_native_type = svg_tear_off = get_svg_type_needing_tear_off(function.data_type) | 
| +    svg_tear_off_and_not_list = svg_tear_off and not interface.name.endswith('List') | 
| +    dom_node_type = is_dom_node_type(interface.name) | 
| +    if svg_tear_off_and_not_list: | 
| +        includes.append('V8%s.h' % function.data_type) | 
| +        includes.append('core/svg/properties/SVGPropertyTearOff.h') | 
| + | 
| +    parameter = { | 
| +        'statement': function_call_statement, | 
| +        'raises_exception': get_raises_exception(function), | 
| +        'return_js_value_statement': return_js_value_statement, | 
| +        'extended_attribute_contains_script_state': extended_attribute_contains_script_state, | 
| +        'call_with': call_with_parameter, | 
| +        'parameters': parameters, | 
| +        'svg_tear_off_and_not_list': svg_tear_off_and_not_list, | 
| +        'svg_tear_off': svg_tear_off, | 
| +        'is_dom_node_type': dom_node_type, | 
| +        'for_main_world_suffix': for_main_world_suffix, | 
| +        'svg_native_type': svg_native_type, | 
| +        'native_value_expression': native_value_expression, | 
| +    } | 
| +    return parameter, includes | 
| + | 
| + | 
| +def get_function_mandatory_parameters(function, count_variadic=False): | 
| +    allow_non_optional = True | 
| +    for parameter in function.arguments: | 
| +        if parameter.is_optional or parameter.is_variadic: | 
| +            allow_non_optional = False | 
| +        else: | 
| +            if not allow_non_optional: | 
| +                raise Exception() | 
| +    mandatory_parameters = 0 | 
| +    for parameter in function.arguments: | 
| +        if parameter.is_optional: | 
| +            break | 
| +        if parameter.is_variadic and not count_variadic: | 
| +            break | 
| +        mandatory_parameters += 1 | 
| +#     print '[]', function.name, mandatory_parameters | 
| +    return mandatory_parameters | 
| + | 
| + | 
| +def get_parameter_check_parameters(interface, function, for_main_world_suffix=''): | 
| +    # GenerateParametersCheck in perl | 
| +    includes = [] | 
| +    parameters_check_parameter = [] | 
| +    for parameter_index in range(len(function.arguments)): | 
| +        parameter_check_parameter, parameter_check_includes = get_parameter_check_parameter(interface, function, parameter_index) | 
| +        parameters_check_parameter.append(parameter_check_parameter) | 
| +        includes += parameter_check_includes | 
| +    replacements = {}  # TODO | 
| +    return parameters_check_parameter, includes, replacements | 
| + | 
| + | 
| +def get_parameter_check_parameter(interface, function, parameter_index, for_main_world_suffix=''): | 
| +    # corresponds to for loop in GenerateParametersCheck in perl | 
| +    includes = ['bindings/v8/ExceptionState.h'] | 
| +    parameter = function.arguments[parameter_index] | 
| +    is_callback_interface = is_callback_interface_etc(parameter.data_type) | 
| +    if is_callback_interface: | 
| +        includes.append('V8%s.h' % parameter.data_type) | 
| +    if parameter.data_type == 'SerializedScriptValue': | 
| +        includes.append('bindings/v8/SerializedScriptValue.h') | 
| +    is_index = 'IsIndex' in parameter.extended_attributes | 
| +    if is_index: | 
| +        includes.append('core/dom/ExceptionCode.h') | 
| + | 
| +    native_type = get_native_type(parameter.data_type, extended_attributes=parameter.extended_attributes, used_to_assign_js_value=True) | 
| +    native_element_type = get_native_type(parameter.data_type) | 
| +    if native_element_type.endswith('>'): | 
| +        native_element_type += ' ' | 
| + | 
| +#         print '[[]]', native_type | 
| +    default = '' | 
| +    if 'Default' in parameter.extended_attributes: | 
| +        default = parameter.extended_attributes.get('Default') | 
| + | 
| +    if parameter.is_optional and default == 'NullString': | 
| +        js_value = 'argumentOrNull(args, %d)' % parameter_index | 
| +    else: | 
| +        js_value = 'args[%d]' % parameter_index | 
| + | 
| +    js_to_native_statement, js_value_to_native_includes = get_js_value_to_native_statement(parameter.data_type, parameter.extended_attributes, js_value, parameter.name, 'args.GetIsolate()') | 
| +    includes += js_value_to_native_includes | 
| + | 
| +    enum_values = get_enum_values(parameter.data_type) | 
| +    enum_validation_terms = ['string == "%s"' % enum_value for enum_value in enum_values] | 
| +    enum_validation_expression = ' || '.join(enum_validation_terms) | 
| + | 
| +    # Optional arguments without [Default=...] should generate an early call with fewer arguments. | 
| +    # Optional arguments with [Optional=...] should not generate the early call. | 
| +    # Optional Dictionary arguments always considered to have default of empty dictionary. | 
| +    early_call = parameter.is_optional and 'Default' not in parameter.extended_attributes and native_type != 'Dictionary' and not is_callback_interface | 
| +    early_call_multi_line = False | 
| +    early_call_statements = {} | 
| +    if early_call: | 
| +        # TODO | 
| +        early_call_statements, early_call_includes = get_function_call_parameter(interface, function, parameter_index, for_main_world_suffix=for_main_world_suffix) | 
| +        includes += early_call_includes | 
| +        early_call_multi_line = len([c for c in early_call_statements if c == '\n']) > 1 | 
| + | 
| +    parameter_check_parameter = { | 
| +        'index': parameter_index, | 
| +        'name': parameter.name, | 
| +        'type': parameter.data_type, | 
| +        'early_call': early_call, | 
| +        'early_call_statement_parameter': early_call_statements, | 
| +        'early_call_multi_line': early_call_multi_line, | 
| +        'is_callback_interface': is_callback_interface, | 
| +        'is_optional': parameter.is_optional, | 
| +        'is_variadic': parameter.is_variadic, | 
| +        'is_index': is_index, | 
| +        'is_wrapper_type': is_wrapper_type(parameter.data_type), | 
| +        'clamp': parameter.extended_attributes.get('Clamp'), | 
| +        'strict_type_checking': parameter.extended_attributes.get('StrictTypeChecking'), | 
| +        'enforce_range': 'EnforceRange' in parameter.extended_attributes, | 
| +        'js_to_native_statement': js_to_native_statement, | 
| +        'native_type': native_type, | 
| +        'native_element_type': native_element_type, | 
| +        'enum_validation_expression': enum_validation_expression, | 
| +        'is_enum_type': is_enum_type(parameter.data_type), | 
| +    } | 
| +    return parameter_check_parameter, includes | 
|  |