| Index: Source/bindings/scripts/v8_interface.py | 
| diff --git a/Source/bindings/scripts/v8_interface.py b/Source/bindings/scripts/v8_interface.py | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0cae79dab4826c5acbd66902d919eecd48260d17 | 
| --- /dev/null | 
| +++ b/Source/bindings/scripts/v8_interface.py | 
| @@ -0,0 +1,286 @@ | 
| +# 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. | 
| + | 
| + | 
| +import struct | 
| + | 
| +from v8_utilities import generate_conditional_string, runtime_enable_function_name | 
| + | 
| +# WIP | 
| +from code_generator_idl_reader import base_interface_name, inherits_interface, interface_inherits_extended_attribute | 
| +# from v8_includes import includes_for_type | 
| +from v8_includes import * | 
| +import v8_attributes | 
| +import v8_functions | 
| +import v8_constructors | 
| +from v8_utilities import get_function_mandatory_parameters, get_feature_observation_parameter, get_deprecation_notification_parameter | 
| +import v8_special_accessors | 
| +import v8_types | 
| +# from v8_types import cpp_type, v8_type | 
| +from v8_types import * | 
| +from v8_utilities import implemented_as_cpp_name | 
| + | 
| + | 
| +################################################################################ | 
| +# BRANCH | 
| +################################################################################ | 
| + | 
| + | 
| +def generate_constants(interface): | 
| +    return [generate_constant(constant) for constant in interface.constants] | 
| + | 
| + | 
| +def generate_constant(constant): | 
| +    # Extended Attributes: Conditional, DeprecateAs, EnabledAtRuntime, Reflect | 
| +    # FIXME: Conditional and DeprecateAs are only used in tests, so remove | 
| +    name = constant.extended_attributes.get('Reflect', constant.name) | 
| +    value_raw = constant.value | 
| +    # If the value we're dealing with is a hex literal, statically cast it to a | 
| +    # signed integer here, rather than dynamically casting via | 
| +    # static_cast<signed int> in the generated code. | 
| +    # FIXME: why are we casting to signed? | 
| +    # NodeFilter has unsigned 0xFFFFFFFF, which is converted to -1. | 
| +    # FIXME: is this necessary? Hex literals are valid C. | 
| +    #        (only semantic difference is casting to signed) | 
| +    # FIXME: what about octal? decimal? | 
| +    # FIXME: what if we have a negative literal? | 
| +    # FIXME: BUG: Perl only checks '0x', not '0X', | 
| +    #             but we have a test case using 0X. | 
| +    if value_raw.startswith('0x'): | 
| +        value = struct.unpack('i', struct.pack('I', int(value_raw, 16)))[0] | 
| +    else: | 
| +        value = value_raw | 
| + | 
| +    constant_parameter = { | 
| +        'name': constant.name, | 
| +        'name_reflect': name,  # FIXME: use name_reflect as correct 'name' | 
| +        'value': value, | 
| +        'value_raw': value_raw, | 
| +        # FIXME: remove conditional: only used in tests | 
| +        'conditional_string': generate_conditional_string(constant), | 
| +        'enabled_at_runtime': 'EnabledAtRuntime' in constant.extended_attributes, | 
| +        'enable_function': runtime_enable_function_name(constant), | 
| +    } | 
| +    return constant_parameter | 
| + | 
| + | 
| +################################################################################ | 
| +# WIP | 
| +################################################################################ | 
| + | 
| + | 
| +def generate_implementation(interface): | 
| +    # __IMPL__ in Perl | 
| +    cpp_class_name = implemented_as_cpp_name(interface) | 
| +    v8_class_name = get_v8_class_name(interface) | 
| +    includes = [ | 
| +        'bindings/v8/V8Binding.h', | 
| +        'bindings/v8/V8DOMWrapper.h', | 
| +        'core/dom/ContextFeatures.h', | 
| +        'core/dom/Document.h', | 
| +        'RuntimeEnabledFeatures.h', | 
| +        'wtf/UnusedParam.h', | 
| +        'bindings/v8/V8DOMConfiguration.h', | 
| +        'core/platform/chromium/TraceEvent.h', | 
| +    ] | 
| + | 
| +    # FIXME: is this only to determine has_callbacks? | 
| +    normal_functions = [] | 
| +    enabled_per_context_functions = []  # FIXME: unused | 
| +    for operation in interface.operations: | 
| +        if not operation.name: | 
| +            continue | 
| +        if 'EnabledPerContext' in operation.extended_attributes: | 
| +            enabled_per_context_functions.append(operation) | 
| +        else: | 
| +            normal_functions.append(operation) | 
| +    has_callbacks = any([ | 
| +            # Only one table entry is needed for overloaded methods: | 
| +            operation.overload_index <= 1 and | 
| +            # Don't put any nonstandard functions into this table: | 
| +            get_is_standard_function(interface, operation) | 
| +            for operation in normal_functions]) | 
| + | 
| +    inherits_extended_attribute_active_dom_object = interface_inherits_extended_attribute(interface, 'ActiveDOMObject') | 
| +    inherits_event_target = inherits_interface(interface, 'EventTarget') | 
| +    # has_attributes = bool(interface.attributes)  # FIXME: unused | 
| +    cpp_class_name_as_parameter = get_native_type(interface.name, used_as_parameter=True) | 
| + | 
| +    includes += get_includes_for_type(interface.name) | 
| + | 
| +    if interface.name == 'ArrayBuffer' or is_typed_array_type(interface.name): | 
| +        includes.append('bindings/v8/custom/V8ArrayBufferCustom.h') | 
| + | 
| +    attribute_parameters, attribute_includes = v8_attributes.generate_attributes_wip(interface) | 
| +    includes += attribute_includes | 
| +    function_parameters, function_includes = v8_functions.generate_functions(interface) | 
| +    includes += function_includes | 
| +    constructor_parameters, constructor_includes = v8_constructors.generate_constructor_contents(interface) | 
| +    includes += constructor_includes | 
| +    special_accessors_parameter, special_accessors_includes = v8_special_accessors.get_special_accessors_parameter(interface) | 
| +    includes += special_accessors_includes | 
| +    feature_observation_parameter, feature_observation_includes = get_feature_observation_parameter(interface) | 
| +    includes += feature_observation_includes | 
| +    deprecation_notification_parameter, deprecation_notification_includes = get_deprecation_notification_parameter(interface) | 
| +    includes += deprecation_notification_includes | 
| +    template_parameters_for_create_wrapper, includes_for_create_wrapper = generate_to_v8_converters(interface, v8_class_name, cpp_class_name) | 
| +    includes += includes_for_create_wrapper | 
| + | 
| +    if interface.parent: | 
| +        parent_class_name = 'V8' + interface.parent | 
| +#             print 'ADD H', interface.parent | 
| +        includes.append('V8%s.h' % interface.parent) | 
| +        parent_class_template = parent_class_name + '::GetTemplate(isolate, currentWorldType)' | 
| +    else: | 
| +        parent_class_name = '' | 
| +        parent_class_template = 'v8::Local<v8::FunctionTemplate>()' | 
| + | 
| +    if interface.name == 'MessagePort': | 
| +        # MessagePort is handled like an active dom object even though it doesn't inherit | 
| +        # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject. | 
| +        active_dom_object_return_value = '0' | 
| +    else: | 
| +        active_dom_object_return_value = 'toNative(object)' | 
| + | 
| +    interface_length = get_interface_length(interface) | 
| + | 
| +    is_reachable_method = interface.extended_attributes.get('GenerateIsReachable') | 
| +    generate_opaque_root_for_gc = 'CustomIsReachable' not in interface.extended_attributes | 
| +    if generate_opaque_root_for_gc and is_reachable_method: | 
| +        includes.append('bindings/v8/V8GCController.h') | 
| +        includes.append('core/dom/Element.h') | 
| + | 
| +    number_of_normal_attributes = len([attribute for attribute in attribute_parameters if attribute.get('is_normal')]) | 
| + | 
| +    includes_set = set(includes) | 
| +    includes_set.discard(v8_class_name + '.h') | 
| +    includes = sorted(includes_set) | 
| +    template_parameters = { | 
| +        'interface_name': interface.name, | 
| +        'interface_length': interface_length, | 
| +        'needs_opaque_root_for_gc': needs_opaque_root_for_gc(interface), | 
| +        'generate_opaque_root_for_gc': generate_opaque_root_for_gc, | 
| +        'is_reachable_method': is_reachable_method, | 
| +        'inherits_extended_attribute_active_dom_object': inherits_extended_attribute_active_dom_object, | 
| +        'active_dom_object_return_value': active_dom_object_return_value, | 
| +        'inherits_event_target': inherits_event_target, | 
| +        'namespace_for_interface': 'WTF' if is_typed_array_type(interface.name) else 'WebCore', | 
| +        ### only DOMException isException==True. TODO support exception | 
| +#             'wrapper_type_prototype': interface.is_exception and 'WrapperTypeErrorPrototype' or 'WrapperTypeObjectPrototype', | 
| +        'wrapper_type_prototype': 'WrapperTypeObjectPrototype', | 
| +        'enabled_at_runtime': 'EnabledAtRuntime' in interface.extended_attributes, | 
| +        'enable_function': runtime_enable_function_name(interface), | 
| +        'configure_template_batched_attribute': v8_class_name + 'Attrs' if number_of_normal_attributes else '0', | 
| +        'configure_template_attribute_count': 'WTF_ARRAY_LENGTH(%sAttrs)' % v8_class_name if number_of_normal_attributes else '0', | 
| +        'configure_template_batched_method': v8_class_name + 'Methods' if has_callbacks else '0', | 
| +        'configure_template_method_count': 'WTF_ARRAY_LENGTH(%sMethods)' % v8_class_name if has_callbacks else '0', | 
| +        # FIXME: replace with conditional expressions | 
| +        'to_active_dom_object': v8_class_name + '::toActiveDOMObject' if inherits_extended_attribute_active_dom_object else '0', | 
| +        'to_event_target': v8_class_name + '::toEventTarget' if inherits_event_target else '0', | 
| +        'root_for_gc': v8_class_name + '::opaqueRootForGC' if needs_opaque_root_for_gc(interface) else '0', | 
| +        'check_security': interface.extended_attributes.get('CheckSecurity'), | 
| +        'parent_class_info': '&%s::info' % parent_class_name if parent_class_name else '0', | 
| +        'parent_class_template': parent_class_template, | 
| +        'parent': interface.parent, | 
| +        'attributes': attribute_parameters, | 
| +        'functions': function_parameters, | 
| +        'function_callbacks': len([f for f in function_parameters if f.get('create_callback')]), | 
| +        'cpp_includes': includes, | 
| +        'number_of_enabled_at_runtime_attributes': len([attribute for attribute in attribute_parameters if attribute['enabled_at_runtime']]), | 
| +        'number_of_enabled_per_context_functions': len([function for function in function_parameters if function['is_enabled_per_context_function']]), | 
| +        'number_of_normal_functions': len([function for function in function_parameters if function.get('is_normal_function')]), | 
| +        'number_of_normal_attributes': number_of_normal_attributes, | 
| +        'number_of_any_attributes': len([attribute for attribute in attribute_parameters if attribute.get('type') == 'any']), | 
| +        'do_not_check_constants': 'DoNotCheckConstants' in interface.extended_attributes, | 
| +        'special_accessors': special_accessors_parameter, | 
| +        'custom_legacy_call': 'CustomLegacyCall' in interface.extended_attributes, | 
| +    } | 
| +    template_parameters.update(template_parameters_for_create_wrapper) | 
| +    template_parameters.update(constructor_parameters) | 
| +    template_parameters.update(feature_observation_parameter) | 
| +    template_parameters.update(deprecation_notification_parameter) | 
| +    return template_parameters | 
| + | 
| + | 
| +def get_convert_to_v8_string_resource(attribute_or_parameter, native_type, variable_name, native_value): | 
| +    # FIXME: unused | 
| +    if not native_type.startswith('V8StringResource'): | 
| +        raise Exception('Wrong native type passed: %s' % native_type) | 
| +    if attribute_or_parameter.data_type == 'DOMString' or is_enum_type(attribute_or_parameter.data_type): | 
| +        return 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(%s, %s, %s);' % (native_type, variable_name, native_value) | 
| +    # print '[get_convert_to_V8StringResource] not DOMString nor enum', native_type, get_convert_to_V8StringResource, native_value | 
| +    return '%s %s(%s, true);' % (native_type, variable_name, native_value) | 
| + | 
| + | 
| +def get_interface_length(interface): | 
| +    # The Web IDL specification states that Interface objects for interfaces MUST have a property named | 
| +    # 'length' that returns the length of the shortest argument list of the entries in the effective | 
| +    # overload set for constructors. In other words, use the lowest number of mandatory arguments among | 
| +    # all constructors. | 
| +    if is_constructor_template(interface, 'Event') or is_constructor_template(interface, 'TypedArray'): | 
| +        return 1 | 
| +    # FIXME: once generate constructors properly, replace with: | 
| +    # if not constructors: return 0 | 
| +    if all(extended_attribute not in interface.extended_attributes | 
| +           for extended_attribute in ['Constructor', 'CustomConstructor']): | 
| +        return 0 | 
| +    constructors = interface.constructors + interface.custom_constructors | 
| +    return min([get_function_mandatory_parameters(constructor) | 
| +                for constructor in constructors]) | 
| + | 
| + | 
| +def generate_to_v8_converters(interface, v8_class_name, cpp_class_name): | 
| +    # print '[]', cpp_class_name | 
| +    includes = [] | 
| +    create_wrapper = not ('DoNotGenerateWrap' in interface.extended_attributes or 'DoNotGenerateToV8' in interface.extended_attributes) | 
| +    if not create_wrapper: | 
| +        return {}, includes | 
| + | 
| +    includes = [ | 
| +        'bindings/v8/ScriptController.h', | 
| +        'core/page/Frame.h', | 
| +    ] | 
| +    # TODO make attribute instead of hard code | 
| +    if ('SVG' in v8_class_name or | 
| +        any([interface_inherits_extended_attribute(interface, attribute) | 
| +             for attribute in ['ActiveDOMObject', 'DependentLifetime', 'GenerateIsReachable', 'CustomIsReachable']])): | 
| +        wrapper_configuration = 'WrapperConfiguration::Dependent' | 
| +    else: | 
| +        wrapper_configuration = 'WrapperConfiguration::Independent' | 
| +    # Used in: C++ calls function f(PassRefPtr<XXX>* impl, ...) -> can be replaced to get_type_as_function_parameter(native_type) | 
| +    template_parameters = { | 
| +        'create_wrapper': create_wrapper, | 
| +        'wrapper_configuration': wrapper_configuration, | 
| +#             'create_wrapper_argument_type': get_native_type(cpp_class_name, used_as_parameter=True), | 
| +        'create_wrapper_argument_type': cpp_class_name, | 
| +        'base_interface_name': base_interface_name(interface), | 
| +        'inherit_document': inherits_interface(interface, 'Document'), | 
| +        'is_typed_array_type': is_typed_array_type(interface.name), | 
| +    } | 
| + | 
| +    return template_parameters, includes | 
|  |