| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 # Copyright (C) 2013 Google Inc. All rights reserved. | 
|  | 2 # | 
|  | 3 # Redistribution and use in source and binary forms, with or without | 
|  | 4 # modification, are permitted provided that the following conditions are | 
|  | 5 # met: | 
|  | 6 # | 
|  | 7 #     * Redistributions of source code must retain the above copyright | 
|  | 8 # notice, this list of conditions and the following disclaimer. | 
|  | 9 #     * Redistributions in binary form must reproduce the above | 
|  | 10 # copyright notice, this list of conditions and the following disclaimer | 
|  | 11 # in the documentation and/or other materials provided with the | 
|  | 12 # distribution. | 
|  | 13 #     * Neither the name of Google Inc. nor the names of its | 
|  | 14 # contributors may be used to endorse or promote products derived from | 
|  | 15 # this software without specific prior written permission. | 
|  | 16 # | 
|  | 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | 18 # 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | 26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | 28 | 
|  | 29 | 
|  | 30 import struct | 
|  | 31 | 
|  | 32 from v8_utilities import generate_conditional_string, runtime_enable_function_na
     me | 
|  | 33 | 
|  | 34 # WIP | 
|  | 35 from code_generator_idl_reader import base_interface_name, inherits_interface, i
     nterface_inherits_extended_attribute | 
|  | 36 # from v8_includes import includes_for_type | 
|  | 37 from v8_includes import * | 
|  | 38 import v8_attributes | 
|  | 39 import v8_functions | 
|  | 40 import v8_constructors | 
|  | 41 from v8_utilities import get_function_mandatory_parameters, get_feature_observat
     ion_parameter, get_deprecation_notification_parameter | 
|  | 42 import v8_special_accessors | 
|  | 43 import v8_types | 
|  | 44 # from v8_types import cpp_type, v8_type | 
|  | 45 from v8_types import * | 
|  | 46 from v8_utilities import implemented_as_cpp_name | 
|  | 47 | 
|  | 48 | 
|  | 49 ################################################################################ | 
|  | 50 # BRANCH | 
|  | 51 ################################################################################ | 
|  | 52 | 
|  | 53 | 
|  | 54 def generate_constants(interface): | 
|  | 55     return [generate_constant(constant) for constant in interface.constants] | 
|  | 56 | 
|  | 57 | 
|  | 58 def generate_constant(constant): | 
|  | 59     # Extended Attributes: Conditional, DeprecateAs, EnabledAtRuntime, Reflect | 
|  | 60     # FIXME: Conditional and DeprecateAs are only used in tests, so remove | 
|  | 61     name = constant.extended_attributes.get('Reflect', constant.name) | 
|  | 62     value_raw = constant.value | 
|  | 63     # If the value we're dealing with is a hex literal, statically cast it to a | 
|  | 64     # signed integer here, rather than dynamically casting via | 
|  | 65     # static_cast<signed int> in the generated code. | 
|  | 66     # FIXME: why are we casting to signed? | 
|  | 67     # NodeFilter has unsigned 0xFFFFFFFF, which is converted to -1. | 
|  | 68     # FIXME: is this necessary? Hex literals are valid C. | 
|  | 69     #        (only semantic difference is casting to signed) | 
|  | 70     # FIXME: what about octal? decimal? | 
|  | 71     # FIXME: what if we have a negative literal? | 
|  | 72     # FIXME: BUG: Perl only checks '0x', not '0X', | 
|  | 73     #             but we have a test case using 0X. | 
|  | 74     if value_raw.startswith('0x'): | 
|  | 75         value = struct.unpack('i', struct.pack('I', int(value_raw, 16)))[0] | 
|  | 76     else: | 
|  | 77         value = value_raw | 
|  | 78 | 
|  | 79     constant_parameter = { | 
|  | 80         'name': constant.name, | 
|  | 81         'name_reflect': name,  # FIXME: use name_reflect as correct 'name' | 
|  | 82         'value': value, | 
|  | 83         'value_raw': value_raw, | 
|  | 84         # FIXME: remove conditional: only used in tests | 
|  | 85         'conditional_string': generate_conditional_string(constant), | 
|  | 86         'enabled_at_runtime': 'EnabledAtRuntime' in constant.extended_attributes
     , | 
|  | 87         'enable_function': runtime_enable_function_name(constant), | 
|  | 88     } | 
|  | 89     return constant_parameter | 
|  | 90 | 
|  | 91 | 
|  | 92 ################################################################################ | 
|  | 93 # WIP | 
|  | 94 ################################################################################ | 
|  | 95 | 
|  | 96 | 
|  | 97 def generate_implementation(interface): | 
|  | 98     # __IMPL__ in Perl | 
|  | 99     cpp_class_name = implemented_as_cpp_name(interface) | 
|  | 100     v8_class_name = get_v8_class_name(interface) | 
|  | 101     includes = [ | 
|  | 102         'bindings/v8/V8Binding.h', | 
|  | 103         'bindings/v8/V8DOMWrapper.h', | 
|  | 104         'core/dom/ContextFeatures.h', | 
|  | 105         'core/dom/Document.h', | 
|  | 106         'RuntimeEnabledFeatures.h', | 
|  | 107         'wtf/UnusedParam.h', | 
|  | 108         'bindings/v8/V8DOMConfiguration.h', | 
|  | 109         'core/platform/chromium/TraceEvent.h', | 
|  | 110     ] | 
|  | 111 | 
|  | 112     # FIXME: is this only to determine has_callbacks? | 
|  | 113     normal_functions = [] | 
|  | 114     enabled_per_context_functions = []  # FIXME: unused | 
|  | 115     for operation in interface.operations: | 
|  | 116         if not operation.name: | 
|  | 117             continue | 
|  | 118         if 'EnabledPerContext' in operation.extended_attributes: | 
|  | 119             enabled_per_context_functions.append(operation) | 
|  | 120         else: | 
|  | 121             normal_functions.append(operation) | 
|  | 122     has_callbacks = any([ | 
|  | 123             # Only one table entry is needed for overloaded methods: | 
|  | 124             operation.overload_index <= 1 and | 
|  | 125             # Don't put any nonstandard functions into this table: | 
|  | 126             get_is_standard_function(interface, operation) | 
|  | 127             for operation in normal_functions]) | 
|  | 128 | 
|  | 129     inherits_extended_attribute_active_dom_object = interface_inherits_extended_
     attribute(interface, 'ActiveDOMObject') | 
|  | 130     inherits_event_target = inherits_interface(interface, 'EventTarget') | 
|  | 131     # has_attributes = bool(interface.attributes)  # FIXME: unused | 
|  | 132     cpp_class_name_as_parameter = get_native_type(interface.name, used_as_parame
     ter=True) | 
|  | 133 | 
|  | 134     includes += get_includes_for_type(interface.name) | 
|  | 135 | 
|  | 136     if interface.name == 'ArrayBuffer' or is_typed_array_type(interface.name): | 
|  | 137         includes.append('bindings/v8/custom/V8ArrayBufferCustom.h') | 
|  | 138 | 
|  | 139     attribute_parameters, attribute_includes = v8_attributes.generate_attributes
     _wip(interface) | 
|  | 140     includes += attribute_includes | 
|  | 141     function_parameters, function_includes = v8_functions.generate_functions(int
     erface) | 
|  | 142     includes += function_includes | 
|  | 143     constructor_parameters, constructor_includes = v8_constructors.generate_cons
     tructor_contents(interface) | 
|  | 144     includes += constructor_includes | 
|  | 145     special_accessors_parameter, special_accessors_includes = v8_special_accesso
     rs.get_special_accessors_parameter(interface) | 
|  | 146     includes += special_accessors_includes | 
|  | 147     feature_observation_parameter, feature_observation_includes = get_feature_ob
     servation_parameter(interface) | 
|  | 148     includes += feature_observation_includes | 
|  | 149     deprecation_notification_parameter, deprecation_notification_includes = get_
     deprecation_notification_parameter(interface) | 
|  | 150     includes += deprecation_notification_includes | 
|  | 151     template_parameters_for_create_wrapper, includes_for_create_wrapper = genera
     te_to_v8_converters(interface, v8_class_name, cpp_class_name) | 
|  | 152     includes += includes_for_create_wrapper | 
|  | 153 | 
|  | 154     if interface.parent: | 
|  | 155         parent_class_name = 'V8' + interface.parent | 
|  | 156 #             print 'ADD H', interface.parent | 
|  | 157         includes.append('V8%s.h' % interface.parent) | 
|  | 158         parent_class_template = parent_class_name + '::GetTemplate(isolate, curr
     entWorldType)' | 
|  | 159     else: | 
|  | 160         parent_class_name = '' | 
|  | 161         parent_class_template = 'v8::Local<v8::FunctionTemplate>()' | 
|  | 162 | 
|  | 163     if interface.name == 'MessagePort': | 
|  | 164         # MessagePort is handled like an active dom object even though it doesn'
     t inherit | 
|  | 165         # from ActiveDOMObject, so don't try to cast it to ActiveDOMObject. | 
|  | 166         active_dom_object_return_value = '0' | 
|  | 167     else: | 
|  | 168         active_dom_object_return_value = 'toNative(object)' | 
|  | 169 | 
|  | 170     interface_length = get_interface_length(interface) | 
|  | 171 | 
|  | 172     is_reachable_method = interface.extended_attributes.get('GenerateIsReachable
     ') | 
|  | 173     generate_opaque_root_for_gc = 'CustomIsReachable' not in interface.extended_
     attributes | 
|  | 174     if generate_opaque_root_for_gc and is_reachable_method: | 
|  | 175         includes.append('bindings/v8/V8GCController.h') | 
|  | 176         includes.append('core/dom/Element.h') | 
|  | 177 | 
|  | 178     number_of_normal_attributes = len([attribute for attribute in attribute_para
     meters if attribute.get('is_normal')]) | 
|  | 179 | 
|  | 180     includes_set = set(includes) | 
|  | 181     includes_set.discard(v8_class_name + '.h') | 
|  | 182     includes = sorted(includes_set) | 
|  | 183     template_parameters = { | 
|  | 184         'interface_name': interface.name, | 
|  | 185         'interface_length': interface_length, | 
|  | 186         'needs_opaque_root_for_gc': needs_opaque_root_for_gc(interface), | 
|  | 187         'generate_opaque_root_for_gc': generate_opaque_root_for_gc, | 
|  | 188         'is_reachable_method': is_reachable_method, | 
|  | 189         'inherits_extended_attribute_active_dom_object': inherits_extended_attri
     bute_active_dom_object, | 
|  | 190         'active_dom_object_return_value': active_dom_object_return_value, | 
|  | 191         'inherits_event_target': inherits_event_target, | 
|  | 192         'namespace_for_interface': 'WTF' if is_typed_array_type(interface.name) 
     else 'WebCore', | 
|  | 193         ### only DOMException isException==True. TODO support exception | 
|  | 194 #             'wrapper_type_prototype': interface.is_exception and 'WrapperTypeE
     rrorPrototype' or 'WrapperTypeObjectPrototype', | 
|  | 195         'wrapper_type_prototype': 'WrapperTypeObjectPrototype', | 
|  | 196         'enabled_at_runtime': 'EnabledAtRuntime' in interface.extended_attribute
     s, | 
|  | 197         'enable_function': runtime_enable_function_name(interface), | 
|  | 198         'configure_template_batched_attribute': v8_class_name + 'Attrs' if numbe
     r_of_normal_attributes else '0', | 
|  | 199         'configure_template_attribute_count': 'WTF_ARRAY_LENGTH(%sAttrs)' % v8_c
     lass_name if number_of_normal_attributes else '0', | 
|  | 200         'configure_template_batched_method': v8_class_name + 'Methods' if has_ca
     llbacks else '0', | 
|  | 201         'configure_template_method_count': 'WTF_ARRAY_LENGTH(%sMethods)' % v8_cl
     ass_name if has_callbacks else '0', | 
|  | 202         # FIXME: replace with conditional expressions | 
|  | 203         'to_active_dom_object': v8_class_name + '::toActiveDOMObject' if inherit
     s_extended_attribute_active_dom_object else '0', | 
|  | 204         'to_event_target': v8_class_name + '::toEventTarget' if inherits_event_t
     arget else '0', | 
|  | 205         'root_for_gc': v8_class_name + '::opaqueRootForGC' if needs_opaque_root_
     for_gc(interface) else '0', | 
|  | 206         'check_security': interface.extended_attributes.get('CheckSecurity'), | 
|  | 207         'parent_class_info': '&%s::info' % parent_class_name if parent_class_nam
     e else '0', | 
|  | 208         'parent_class_template': parent_class_template, | 
|  | 209         'parent': interface.parent, | 
|  | 210         'attributes': attribute_parameters, | 
|  | 211         'functions': function_parameters, | 
|  | 212         'function_callbacks': len([f for f in function_parameters if f.get('crea
     te_callback')]), | 
|  | 213         'cpp_includes': includes, | 
|  | 214         'number_of_enabled_at_runtime_attributes': len([attribute for attribute 
     in attribute_parameters if attribute['enabled_at_runtime']]), | 
|  | 215         'number_of_enabled_per_context_functions': len([function for function in
      function_parameters if function['is_enabled_per_context_function']]), | 
|  | 216         'number_of_normal_functions': len([function for function in function_par
     ameters if function.get('is_normal_function')]), | 
|  | 217         'number_of_normal_attributes': number_of_normal_attributes, | 
|  | 218         'number_of_any_attributes': len([attribute for attribute in attribute_pa
     rameters if attribute.get('type') == 'any']), | 
|  | 219         'do_not_check_constants': 'DoNotCheckConstants' in interface.extended_at
     tributes, | 
|  | 220         'special_accessors': special_accessors_parameter, | 
|  | 221         'custom_legacy_call': 'CustomLegacyCall' in interface.extended_attribute
     s, | 
|  | 222     } | 
|  | 223     template_parameters.update(template_parameters_for_create_wrapper) | 
|  | 224     template_parameters.update(constructor_parameters) | 
|  | 225     template_parameters.update(feature_observation_parameter) | 
|  | 226     template_parameters.update(deprecation_notification_parameter) | 
|  | 227     return template_parameters | 
|  | 228 | 
|  | 229 | 
|  | 230 def get_convert_to_v8_string_resource(attribute_or_parameter, native_type, varia
     ble_name, native_value): | 
|  | 231     # FIXME: unused | 
|  | 232     if not native_type.startswith('V8StringResource'): | 
|  | 233         raise Exception('Wrong native type passed: %s' % native_type) | 
|  | 234     if attribute_or_parameter.data_type == 'DOMString' or is_enum_type(attribute
     _or_parameter.data_type): | 
|  | 235         return 'V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(%s, %s, %s);' % (native_typ
     e, variable_name, native_value) | 
|  | 236     # print '[get_convert_to_V8StringResource] not DOMString nor enum', native_t
     ype, get_convert_to_V8StringResource, native_value | 
|  | 237     return '%s %s(%s, true);' % (native_type, variable_name, native_value) | 
|  | 238 | 
|  | 239 | 
|  | 240 def get_interface_length(interface): | 
|  | 241     # The Web IDL specification states that Interface objects for interfaces MUS
     T have a property named | 
|  | 242     # 'length' that returns the length of the shortest argument list of the entr
     ies in the effective | 
|  | 243     # overload set for constructors. In other words, use the lowest number of ma
     ndatory arguments among | 
|  | 244     # all constructors. | 
|  | 245     if is_constructor_template(interface, 'Event') or is_constructor_template(in
     terface, 'TypedArray'): | 
|  | 246         return 1 | 
|  | 247     # FIXME: once generate constructors properly, replace with: | 
|  | 248     # if not constructors: return 0 | 
|  | 249     if all(extended_attribute not in interface.extended_attributes | 
|  | 250            for extended_attribute in ['Constructor', 'CustomConstructor']): | 
|  | 251         return 0 | 
|  | 252     constructors = interface.constructors + interface.custom_constructors | 
|  | 253     return min([get_function_mandatory_parameters(constructor) | 
|  | 254                 for constructor in constructors]) | 
|  | 255 | 
|  | 256 | 
|  | 257 def generate_to_v8_converters(interface, v8_class_name, cpp_class_name): | 
|  | 258     # print '[]', cpp_class_name | 
|  | 259     includes = [] | 
|  | 260     create_wrapper = not ('DoNotGenerateWrap' in interface.extended_attributes o
     r 'DoNotGenerateToV8' in interface.extended_attributes) | 
|  | 261     if not create_wrapper: | 
|  | 262         return {}, includes | 
|  | 263 | 
|  | 264     includes = [ | 
|  | 265         'bindings/v8/ScriptController.h', | 
|  | 266         'core/page/Frame.h', | 
|  | 267     ] | 
|  | 268     # TODO make attribute instead of hard code | 
|  | 269     if ('SVG' in v8_class_name or | 
|  | 270         any([interface_inherits_extended_attribute(interface, attribute) | 
|  | 271              for attribute in ['ActiveDOMObject', 'DependentLifetime', 'Generate
     IsReachable', 'CustomIsReachable']])): | 
|  | 272         wrapper_configuration = 'WrapperConfiguration::Dependent' | 
|  | 273     else: | 
|  | 274         wrapper_configuration = 'WrapperConfiguration::Independent' | 
|  | 275     # Used in: C++ calls function f(PassRefPtr<XXX>* impl, ...) -> can be replac
     ed to get_type_as_function_parameter(native_type) | 
|  | 276     template_parameters = { | 
|  | 277         'create_wrapper': create_wrapper, | 
|  | 278         'wrapper_configuration': wrapper_configuration, | 
|  | 279 #             'create_wrapper_argument_type': get_native_type(cpp_class_name, us
     ed_as_parameter=True), | 
|  | 280         'create_wrapper_argument_type': cpp_class_name, | 
|  | 281         'base_interface_name': base_interface_name(interface), | 
|  | 282         'inherit_document': inherits_interface(interface, 'Document'), | 
|  | 283         'is_typed_array_type': is_typed_array_type(interface.name), | 
|  | 284     } | 
|  | 285 | 
|  | 286     return template_parameters, includes | 
| OLD | NEW | 
|---|