Index: Source/bindings/dart/scripts/templates/methods_cpp.template |
diff --git a/Source/bindings/dart/scripts/templates/methods_cpp.template b/Source/bindings/dart/scripts/templates/methods_cpp.template |
index 9caf45dbc5a32b52d64f86f01264ebac7573568f..bf4c6d8d768890b149e66a48dd5a4f721da7f90e 100644 |
--- a/Source/bindings/dart/scripts/templates/methods_cpp.template |
+++ b/Source/bindings/dart/scripts/templates/methods_cpp.template |
@@ -1,16 +1,83 @@ |
{##############################################################################} |
+{# 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 = 0; |
+ 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 %} |
+ {% filter runtime_enabled(not overloads.runtime_enabled_function_all and |
+ method.runtime_enabled_function) %} |
+ if ({{test}}) { |
+ {% if method.is_custom %} |
+ {{static_method_name(method.name)}}(args); |
+ {% else %} |
+ {{static_method_name(method.name, method.overload_index)}}(args); |
+ {% endif %} |
+ return; |
+ } |
+ {% endfilter %} |
+ {% 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}}"; |
+ exception = DartUtilities::coreArgumentErrorException(message); |
+ goto fail; |
+ } |
+ {% endif %} |
+ {# Otherwise just report "not enough arguments" #} |
+ { |
+ const String message = "Not enough arguments (at least {{overloads.minarg}} required)"; |
+ exception = DartUtilities::coreArgumentErrorException(message); |
+ goto fail; |
+ } |
+ return; |
+ } |
+ { |
+ const String message = "No function was found that matched the signature provided."; |
+ 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, overload='', constructor=False) %} |
-{% if overload == '' %} |
- {% set overload_index = method.overload_index %} |
-{% else %} |
- {% set overload_index = overload %} |
-{% endif %} |
+{% 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 %} |
@@ -129,6 +196,18 @@ if (UNLIKELY(argCount <= {{argument.arg_index}})) { |
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}} = Dart{{argument.idl_type}}::createWithNullCheck(args, {{argument.arg_index}}, exception); |
+} |
+{% else %}{# argument.is_optional #} |
+{{argument.local_cpp_type}} {{argument.name}} = Dart{{argument.idl_type}}::createWithNullCheck(args, {{argument.arg_index}}, exception); |
+{% endif %}{# argument.is_optional #} |
+{% else %}{# argument.is_callback_interface #} |
{% if argument.is_optional and argument.default_value -%} |
{{argument.local_cpp_type}} {{argument.name}} = |
(argCount <= {{argument.arg_index}}) ? ({{argument.default_value}}) : {{argument.dart_value_to_local_cpp_value}}; |
@@ -145,6 +224,7 @@ if (UNLIKELY(argCount <= {{argument.arg_index}})) { |
{% 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 %} |
@@ -172,8 +252,12 @@ if (exception) |
{% macro generate_resolver_body(dart_class, class_name, method) %} |
{% for native_entry in method.native_entries %} |
{% set uses_script_args = method.is_call_with_script_arguments %} |
-{% if method.is_custom %} |
+{% if method.overload_index %} |
+ {% set method_name = static_method_name(method.name) + "Dispatcher" %} |
+{% else %} |
{% set method_name = static_method_name(method.name) %} |
+{% endif %} |
+{% 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. |
@@ -182,7 +266,6 @@ if (name == "{{native_entry.resolver_string}}") { |
return {{dart_class}}Internal::{{method_name}}; |
} |
{% else %} |
- {% set method_name = static_method_name(method.name, method.overload_index) %} |
{% set args_one_based = method.number_of_arguments %} |
{% set args_required_one_based = method.number_of_required_arguments %} |
{% if not method.is_static %} |
@@ -216,17 +299,14 @@ if (argumentCount >= {{args_required_one_based}} && argumentCount <= {{args_one_ |
{% macro generate_symbolizer_body(dart_class, class_name, method) %} |
{% for native_entry in method.native_entries %} |
{% set uses_script_args = method.is_call_with_script_arguments %} |
-{% if method.is_custom %} |
-{% set method_name = static_method_name(method.name) %} |
-if (nf == {{dart_class}}Internal::{{method_name}}) { |
- return reinterpret_cast<const uint8_t*>("{{native_entry.resolver_string}}"); |
-} |
+{% if method.overload_index %} |
+ {% set method_name = static_method_name(method.name) + "Dispatcher" %} |
{% else %} |
-{% set method_name = static_method_name(method.name, method.overload_index) %} |
+ {% set method_name = static_method_name(method.name) %} |
+{% endif %} |
if (nf == {{dart_class}}Internal::{{method_name}}) { |
return reinterpret_cast<const uint8_t*>("{{native_entry.resolver_string}}"); |
} |
-{% endif %} |
{% endfor %} |
{% endmacro %} |
@@ -373,11 +453,16 @@ fail: |
} |
{% 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 %} |
@@ -386,7 +471,7 @@ if (argumentCount == {{constructor.number_of_arguments}} && name == "{{resolver_ |
if (argumentCount >= {{constructor.number_of_required_arguments}} && argumentCount <= {{constructor.number_of_arguments}} && name == "{{resolver_string}}") { |
{% endif %} |
*autoSetupScope = {{constructor.auto_scope}}; |
- return {{dart_class}}Internal::{{static_method_name(constructor.name, constructor.overload_index)}}; |
+ return {{dart_class}}Internal::{{constructor_name}}; |
} |
{% endfor %} |
{% endmacro %} |