| Index: sky/engine/bindings2/scripts/templates/methods_cpp.template
|
| diff --git a/sky/engine/bindings2/scripts/templates/methods_cpp.template b/sky/engine/bindings2/scripts/templates/methods_cpp.template
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4946eb906ba16bc9f9bc88a09ff82f609af073f4
|
| --- /dev/null
|
| +++ b/sky/engine/bindings2/scripts/templates/methods_cpp.template
|
| @@ -0,0 +1,406 @@
|
| +{##############################################################################}
|
| +{# FIXME: We should return a rejected Promise if an error occurs in this
|
| +function when ALL methods in this overload return Promise. In order to do so,
|
| +we must ensure either ALL or NO methods in this overload return Promise #}
|
| +{% macro overload_resolution_method(method) %}
|
| +{% set overloads = method.overloads %}
|
| +{% if method.is_static %}
|
| + {% set offset = 0 %}
|
| +{% else %}
|
| + {% set offset = 1 %}
|
| +{% endif %}
|
| +static void {{static_method_name(overloads.name)}}Dispatcher(Dart_NativeArguments args)
|
| +{
|
| + Dart_Handle exception = nullptr;
|
| + const int argOffset = {{offset}};
|
| + int argCount = Dart_GetNativeArgumentCount(args) - argOffset;
|
| +
|
| + {# First resolve by length #}
|
| + {# 2. Initialize argcount to be min(maxarg, n). #}
|
| + switch (std::min({{overloads.maxarg}}, argCount)) {
|
| + {# 3. Remove from S all entries whose type list is not of length argcount. #}
|
| + {% for length, tests_methods in overloads.length_tests_methods %}
|
| + {# 10. If i = d, then: #}
|
| + case {{length}}:
|
| + {# Then resolve by testing argument #}
|
| + {% for test, method in tests_methods %}
|
| + if ({{test}}) {
|
| + {% if method.is_custom %}
|
| + {{static_method_name(method.name)}}(args);
|
| + {% else %}
|
| + {{static_method_name(method.name, method.overload_index)}}(args);
|
| + {% endif %}
|
| + return;
|
| + }
|
| + {% endfor %}
|
| + break;
|
| + {% endfor %}
|
| + default:
|
| + {# Invalid arity, throw error #}
|
| + {# Report full list of valid arities if gaps and above minimum #}
|
| + {% if overloads.valid_arities %}
|
| + if (argCount >= {{overloads.minarg}}) {
|
| + const String message = "Wrong arity, expected one of {{overloads.valid_arities}}";
|
| + // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
|
| + goto fail;
|
| + }
|
| + {% endif %}
|
| + {# Otherwise just report "not enough arguments" #}
|
| + {
|
| + const String message = "Not enough arguments (at least {{overloads.minarg}} required)";
|
| + // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
|
| + goto fail;
|
| + }
|
| + return;
|
| + }
|
| + {
|
| + const String message = "No function was found that matched the signature provided.";
|
| + // TODO(dart): exception = DartUtilities::coreArgumentErrorException(message);
|
| + goto fail;
|
| + }
|
| + return;
|
| +fail:
|
| + Dart_ThrowException(exception);
|
| + ASSERT_NOT_REACHED();
|
| +}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{# arguments_count is normal method.number_of_arguments however for optional #}
|
| +{# arguments then number_of_required_arguments is passed (sans optional). #}
|
| +{# overload in the index if overloaded. #}
|
| +{# interface is specified signals that it's a constructor being called the #}
|
| +{# delegation to the create is emitted.
|
| +{##############################################################################}
|
| +{% macro generate_method(method, arguments_count) %}
|
| +{% set overload_index = method.overload_index %}
|
| +static void {{static_method_name(method.name, overload_index)}}(Dart_NativeArguments args)
|
| +{
|
| +{% if not method.is_static %}
|
| + {{cpp_class}}* /* FIXME(vsm): Remove this. */ ALLOW_UNUSED receiver = GetReceiver<{{cpp_class}}>(args);
|
| +{% endif %}
|
| +{% if method.is_custom_element_callbacks %}
|
| + CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
|
| +{% endif %}
|
| +{% if arguments_count > 0 or
|
| + method.has_exception_state or
|
| + method.is_call_with_script_state or
|
| + method.is_call_with_execution_context or
|
| + method.is_call_with_script_arguments %}
|
| + Dart_Handle exception = nullptr;
|
| +{% endif %}
|
| + {
|
| + {% if method.is_call_with_script_state %}
|
| + ScriptState* state = DartUtilities::currentScriptState();
|
| + if (!state) {
|
| + exception = Dart_NewStringFromCString("Failed to retrieve a script state");
|
| + goto fail;
|
| + }
|
| + {% endif %}
|
| + {% if method.is_call_with_execution_context %}
|
| + ExecutionContext* context = DOMDartState::CurrentDocument();
|
| + if (!context) {
|
| + exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
| + goto fail;
|
| + }
|
| + {% endif %}
|
| + {% if method.is_call_with_script_arguments %}
|
| + {# Last parameter is the customArgument #}
|
| + Dart_Handle customArgument = Dart_GetNativeArgument(args, Dart_GetNativeArgumentCount(args) - 1);
|
| + RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));
|
| + if (!scriptArguments)
|
| + goto fail;
|
| + {% endif %}
|
| + {% if method.number_of_arguments != method.number_of_required_arguments %}
|
| + int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativeArgumentCount(args);
|
| + {% endif %}
|
| + {% if method.has_exception_state %}
|
| + ExceptionState es;
|
| + {% endif %}
|
| + {{generate_arguments(method) | indent(8)}}
|
| + {{callback_return(method, method.dart_set_return_value, method.cpp_value)}}
|
| + {% if method.has_exception_state %}
|
| + if (es.had_exception()) {
|
| + exception = es.GetDartException(args, {{method.auto_scope}});
|
| + goto fail;
|
| + }
|
| +
|
| + {% endif %}
|
| + return;
|
| + }
|
| +
|
| +{% if arguments_count > 0 or method.has_exception_state or method.is_call_with_script_state or method.is_call_with_execution_context or method.is_call_with_script_arguments %}
|
| +fail:
|
| + Dart_ThrowException(exception);
|
| + ASSERT_NOT_REACHED();
|
| +{% endif %}
|
| +}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro callback_return(method, dart_set_return_value, cpp_value) %}
|
| +{%- if method.union_arguments -%}
|
| +{{callback_union_return(method) | indent(8)}}
|
| +{%- elif method.idl_type == 'void' -%}
|
| +{{cpp_value}};
|
| +{%- elif method.is_constructor -%}
|
| +DartConverter<{{cpp_class}}*>::SetReturnValue(args, WTF::getPtr({{cpp_value}}), {{method.auto_scope}});
|
| +{%- else -%}
|
| +{{dart_set_return_value}};
|
| +{%- endif -%}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro callback_union_return(method, argument_count) %}
|
| + {% set type_index = 0 %}
|
| + {% for union_argument in method.union_arguments %}
|
| +{{method.cpp_type[type_index]}} {{union_argument}};
|
| + {% set type_index = type_index + 1 %}
|
| + {% endfor %}
|
| +{{method.cpp_value}};
|
| +
|
| + {% set union_set_result_index = 0 %}
|
| + {% for union_argument in method.union_arguments %}
|
| +if ({{union_argument}}) {
|
| + {{method.dart_set_return_value[union_set_result_index]}};
|
| + return;
|
| +}
|
| + {% set union_set_result_index = union_set_result_index + 1 %}
|
| + {% endfor %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_argument(method, argument) %}
|
| +{# If sequence result is passed as an argument not as function return value. #}
|
| +{% if argument.is_optional and
|
| + not argument.has_default and
|
| + not argument.is_callback_interface %}
|
| +{# Optional arguments without a default value generate an early call with
|
| + fewer arguments if they are omitted. #}
|
| +if (UNLIKELY(argCount <= {{argument.arg_index}})) {
|
| + {{callback_return(method, argument.dart_set_return_value, argument.cpp_value)}}
|
| + if (exception)
|
| + goto fail;
|
| + return;
|
| +}
|
| +{% endif %}
|
| +{% if argument.is_callback_interface %}
|
| +{# Callback functions must be functions:
|
| + http://www.w3.org/TR/WebIDL/#es-callback-function #}
|
| +{% if argument.is_optional %}
|
| +{{argument.local_cpp_type}} {{argument.name}};
|
| +if (argCount > {{argument.arg_index}}) {
|
| + {{argument.name}} = DartConverter<{{argument.implemented_as}}*>::FromArgumentsWithNullCheck(args, {{argument.arg_index}}, exception);
|
| +}
|
| +{% else %}{# argument.is_optional #}
|
| +{{argument.local_cpp_type}} {{argument.name}} = DartConverter<{{argument.implemented_as}}*>::FromArgumentsWithNullCheck(args, {{argument.arg_index}}, exception);
|
| +{% endif %}{# argument.is_optional #}
|
| +{% else %}{# argument.is_callback_interface #}
|
| +{% if argument.is_optional and argument.has_default -%}
|
| +{{argument.local_cpp_type}} {{argument.name}} =
|
| + (argCount <= {{argument.arg_index}}) ? ({{argument.default_value}}) : {{argument.dart_value_to_local_cpp_value}};
|
| +{% elif argument.is_array_or_sequence_type %}
|
| +{{argument.local_cpp_type}} {{argument.name}};
|
| +{{argument.dart_value_to_local_cpp_value}};
|
| +{% else %}
|
| +{{argument.local_cpp_type}} {{argument.name}} = {{argument.dart_value_to_local_cpp_value}};
|
| +{% endif %}
|
| +{% endif %}{# argument.is_callback_interface #}
|
| +if (exception)
|
| + goto fail;
|
| +{% endmacro %}
|
| +
|
| +
|
| +{######################################}
|
| +{% macro generate_arguments(method) %}
|
| +{%- for argument in method.arguments -%}
|
| +{{generate_argument(method, argument)}}
|
| +{%- endfor -%}
|
| +{% endmacro %}
|
| +
|
| +{##############################################################################}
|
| +{% macro static_method_name(name, overload_index) %}
|
| +{% set name = 'constructor' if not name else name -%}
|
| +{% if overload_index -%}
|
| +{{name}}Callback_{{overload_index}}
|
| +{%- else -%}
|
| +{{name}}Callback
|
| +{%- endif %}
|
| +{% endmacro -%}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_resolver_body(dart_class, class_name, method) %}
|
| +{% for native_entry_group in method.native_entries|groupby('resolver_string') %}
|
| +{% set uses_script_args = method.is_call_with_script_arguments %}
|
| +{% if method.overload_index %}
|
| + {% set method_name = static_method_name(method.name) + "Dispatcher" %}
|
| +{% else %}
|
| + {% set method_name = static_method_name(method.name) %}
|
| +{% endif %}
|
| +{% set resolver_string = native_entry_group.grouper %}
|
| +{% if method.is_custom %}
|
| +// FIXME: we are missing changes from dart.idl so we don't always know how many
|
| +// args custom methods will take so we ignore that check which could hurt perf
|
| +// and security but lets us get everything running quicker.
|
| +if (name == "{{resolver_string}}") {
|
| + *autoSetupScope = {{method.auto_scope}};
|
| + return {{dart_class}}Internal::{{method_name}};
|
| +}
|
| +{% else %}
|
| + {% set args_one_based = method.number_of_arguments %}
|
| + {% set args_required_one_based = method.number_of_required_arguments %}
|
| + {% if not method.is_static %}
|
| + {% set args_one_based = args_one_based + 1 %}
|
| + {% set args_required_one_based = args_required_one_based + 1 %}
|
| + {% endif %}
|
| +
|
| + {% if uses_script_args %}
|
| + {# FIXME(vsm): At least one script argument is expected. Generalize? #}
|
| + {% set args_one_based = args_one_based + 1 %}
|
| + {% set args_required_one_based = args_required_one_based + 1 %}
|
| + {% endif %}
|
| +
|
| + {% if args_one_based == args_required_one_based %}
|
| +if (argumentCount == {{args_one_based}} && name == "{{resolver_string}}") {
|
| + *autoSetupScope = {{method.auto_scope}};
|
| + return {{dart_class}}Internal::{{method_name}};
|
| +}
|
| + {% else %}
|
| +if (argumentCount >= {{args_required_one_based}} && argumentCount <= {{args_one_based}} && name == "{{resolver_string}}") {
|
| + *autoSetupScope = {{method.auto_scope}};
|
| + return {{dart_class}}Internal::{{method_name}};
|
| +}
|
| + {% endif %}
|
| +{% endif %}
|
| +{% endfor %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_symbolizer_body(dart_class, class_name, method) %}
|
| +{% for native_entry_group in method.native_entries|groupby('resolver_string') %}
|
| +{% set uses_script_args = method.is_call_with_script_arguments %}
|
| +{% if method.overload_index %}
|
| + {% set method_name = static_method_name(method.name) + "Dispatcher" %}
|
| +{% else %}
|
| + {% set method_name = static_method_name(method.name) %}
|
| +{% endif %}
|
| +{% set resolver_string = native_entry_group.grouper %}
|
| +if (native_function == {{dart_class}}Internal::{{method_name}}) {
|
| + return reinterpret_cast<const uint8_t*>("{{resolver_string}}");
|
| +}
|
| +{% endfor %}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_constructor(constructor, arguments_count, overload='') %}
|
| +{% if overload == '' %}
|
| + {% set overload_index = constructor.overload_index %}
|
| +{% else %}
|
| + {% set overload_index = overload %}
|
| +{% endif %}
|
| +static void {{static_method_name(constructor.name, overload_index)}}(Dart_NativeArguments args)
|
| +{
|
| +{% if arguments_count > 0 or
|
| + constructor.has_exception_state or
|
| + is_constructor_call_with_execution_context or
|
| + is_constructor_call_with_document or
|
| + (constructor == named_constructor) %}
|
| + Dart_Handle exception = nullptr;
|
| +{% endif %}
|
| + {
|
| +{% if is_constructor_call_with_execution_context %}
|
| + ExecutionContext* context = DOMDartState::CurrentDocument();
|
| + if (!context) {
|
| + exception = Dart_NewStringFromCString("Failed to retrieve a context");
|
| + goto fail;
|
| + }
|
| +{% endif %}
|
| +{% if is_constructor_call_with_document or (constructor == named_constructor) %}
|
| + LocalDOMWindow* domWindow = DOMDartState::CurrentWindow();
|
| + if (!domWindow) {
|
| + exception = Dart_NewStringFromCString("Failed to fetch domWindow");
|
| + goto fail;
|
| + }
|
| + Document& document = *domWindow->document();
|
| +{% endif %}
|
| + int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativeArgumentCount(args);
|
| +{% if constructor.has_exception_state %}
|
| + ExceptionState es;
|
| +{% endif %}
|
| + {{generate_arguments(constructor) | indent(8)}}
|
| + {{callback_return(constructor, constructor.dart_set_return_value, constructor.cpp_value) | indent(8)}}
|
| +{% if constructor.has_exception_state %}
|
| + if (es.had_exception()) {
|
| + exception = es.GetDartException(args, {{constructor.auto_scope}});
|
| + goto fail;
|
| + }
|
| +
|
| +{% endif %}
|
| + return;
|
| + }
|
| +
|
| +{% if arguments_count > 0 or constructor.has_exception_state or is_constructor_call_with_execution_context or is_constructor_call_with_document or (constructor == named_constructor) %}
|
| +fail:
|
| + Dart_ThrowException(exception);
|
| + ASSERT_NOT_REACHED();
|
| +{% endif %}
|
| +}
|
| +{% endmacro %}
|
| +
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_event_constructor() %}
|
| +static void eventConstructorCallback(Dart_NativeArguments args)
|
| +{
|
| + Dart_SetReturnValue(args, Dart_Null());
|
| +}
|
| +{% endmacro %}
|
| +
|
| +,
|
| +{##############################################################################}
|
| +{% macro generate_resolver_constructor(dart_class, class_name, constructor) %}
|
| +{% for native_entry in constructor.native_entries %}
|
| +{% set resolver_string = native_entry.resolver_string %}
|
| +{% if constructor.overload_index %}
|
| + {% set constructor_name = static_method_name(constructor.name) + "Dispatcher" %}
|
| +{% else %}
|
| + {% set constructor_name = static_method_name(constructor.name) %}
|
| +{% endif %}
|
| +{% if has_custom_constructor %}
|
| +if (name == "{{resolver_string}}") {
|
| +{% elif constructor.number_of_arguments == constructor.number_of_required_arguments %}
|
| +if (argumentCount == {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
|
| +{% else %}
|
| +if (argumentCount >= {{constructor.number_of_required_arguments}} && argumentCount <= {{constructor.number_of_arguments}} && name == "{{resolver_string}}") {
|
| +{% endif %}
|
| + *autoSetupScope = {{constructor.auto_scope}};
|
| + return {{dart_class}}Internal::{{constructor_name}};
|
| +}
|
| +{% endfor %}
|
| +{% endmacro %}
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_resolver_event_constructor(dart_class, class_name) %}
|
| +{% set resolver_string = interface_name + "_constructorCallback" %}
|
| +if (argumentCount == 2 && name == "{{resolver_string}}") {
|
| + *autoSetupScope = 1;
|
| + return {{dart_class}}Internal::eventConstructorCallback;
|
| +}
|
| +{% endmacro %}
|
| +
|
| +{##############################################################################}
|
| +{% macro generate_symbolizer_constructor(dart_class, class_name, constructor) %}
|
| +{% for native_entry in constructor.native_entries %}
|
| +{% set resolver_string = native_entry.resolver_string %}
|
| +if (native_function == {{dart_class}}Internal::{{static_method_name(constructor.name, constructor.overload_index)}}) {
|
| + return reinterpret_cast<const uint8_t*>("{{resolver_string}}");
|
| +}
|
| +{% endfor %}
|
| +{% endmacro %}
|
|
|