Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(177)

Unified Diff: Source/bindings/scripts/v8_interface.py

Issue 17572008: WIP IDL compiler rewrite (Closed) Base URL: https://chromium.googlesource.com/chromium/blink@master
Patch Set: Branch: const + primitive type readonly attributes Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/scripts/v8_includes.py ('k') | Source/bindings/scripts/v8_interface_header.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « Source/bindings/scripts/v8_includes.py ('k') | Source/bindings/scripts/v8_interface_header.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698