| OLD | NEW |
| (Empty) | |
| 1 {##############################################################################} |
| 2 {# FIXME: We should return a rejected Promise if an error occurs in this |
| 3 function when ALL methods in this overload return Promise. In order to do so, |
| 4 we must ensure either ALL or NO methods in this overload return Promise #} |
| 5 {% macro overload_resolution_method(method) %} |
| 6 {% set overloads = method.overloads %} |
| 7 {% if method.is_static %} |
| 8 {% set offset = 0 %} |
| 9 {% else %} |
| 10 {% set offset = 1 %} |
| 11 {% endif %} |
| 12 static void {{static_method_name(overloads.name)}}Dispatcher(Dart_NativeArgument
s args) |
| 13 { |
| 14 Dart_Handle exception = nullptr; |
| 15 const int argOffset = {{offset}}; |
| 16 int argCount = Dart_GetNativeArgumentCount(args) - argOffset; |
| 17 |
| 18 {# First resolve by length #} |
| 19 {# 2. Initialize argcount to be min(maxarg, n). #} |
| 20 switch (std::min({{overloads.maxarg}}, argCount)) { |
| 21 {# 3. Remove from S all entries whose type list is not of length argcount. #
} |
| 22 {% for length, tests_methods in overloads.length_tests_methods %} |
| 23 {# 10. If i = d, then: #} |
| 24 case {{length}}: |
| 25 {# Then resolve by testing argument #} |
| 26 {% for test, method in tests_methods %} |
| 27 if ({{test}}) { |
| 28 {% if method.is_custom %} |
| 29 {{static_method_name(method.name)}}(args); |
| 30 {% else %} |
| 31 {{static_method_name(method.name, method.overload_index)}}(args); |
| 32 {% endif %} |
| 33 return; |
| 34 } |
| 35 {% endfor %} |
| 36 break; |
| 37 {% endfor %} |
| 38 default: |
| 39 {# Invalid arity, throw error #} |
| 40 {# Report full list of valid arities if gaps and above minimum #} |
| 41 {% if overloads.valid_arities %} |
| 42 if (argCount >= {{overloads.minarg}}) { |
| 43 const String message = "Wrong arity, expected one of {{overloads.val
id_arities}}"; |
| 44 // TODO(dart): exception = DartUtilities::coreArgumentErrorException
(message); |
| 45 goto fail; |
| 46 } |
| 47 {% endif %} |
| 48 {# Otherwise just report "not enough arguments" #} |
| 49 { |
| 50 const String message = "Not enough arguments (at least {{overloads.m
inarg}} required)"; |
| 51 // TODO(dart): exception = DartUtilities::coreArgumentErrorException
(message); |
| 52 goto fail; |
| 53 } |
| 54 return; |
| 55 } |
| 56 { |
| 57 const String message = "No function was found that matched the signature
provided."; |
| 58 // TODO(dart): exception = DartUtilities::coreArgumentErrorException(mes
sage); |
| 59 goto fail; |
| 60 } |
| 61 return; |
| 62 fail: |
| 63 Dart_ThrowException(exception); |
| 64 ASSERT_NOT_REACHED(); |
| 65 } |
| 66 {% endmacro %} |
| 67 |
| 68 |
| 69 {##############################################################################} |
| 70 {# arguments_count is normal method.number_of_arguments however for optional #} |
| 71 {# arguments then number_of_required_arguments is passed (sans optional). #} |
| 72 {# overload in the index if overloaded. #} |
| 73 {# interface is specified signals that it's a constructor being called the #} |
| 74 {# delegation to the create is emitted. |
| 75 {##############################################################################} |
| 76 {% macro generate_method(method, arguments_count) %} |
| 77 {% set overload_index = method.overload_index %} |
| 78 static void {{static_method_name(method.name, overload_index)}}(Dart_NativeArgum
ents args) |
| 79 { |
| 80 {% if not method.is_static %} |
| 81 {{cpp_class}}* /* FIXME(vsm): Remove this. */ ALLOW_UNUSED receiver = GetRec
eiver<{{cpp_class}}>(args); |
| 82 {% endif %} |
| 83 {% if method.is_custom_element_callbacks %} |
| 84 CustomElementProcessingStack::CallbackDeliveryScope deliveryScope; |
| 85 {% endif %} |
| 86 {% if arguments_count > 0 or |
| 87 method.has_exception_state or |
| 88 method.is_call_with_script_state or |
| 89 method.is_call_with_execution_context or |
| 90 method.is_call_with_script_arguments %} |
| 91 Dart_Handle exception = nullptr; |
| 92 {% endif %} |
| 93 { |
| 94 {% if method.is_call_with_script_state %} |
| 95 ScriptState* state = DartUtilities::currentScriptState(); |
| 96 if (!state) { |
| 97 exception = Dart_NewStringFromCString("Failed to retrieve a script s
tate"); |
| 98 goto fail; |
| 99 } |
| 100 {% endif %} |
| 101 {% if method.is_call_with_execution_context %} |
| 102 ExecutionContext* context = DOMDartState::CurrentDocument(); |
| 103 if (!context) { |
| 104 exception = Dart_NewStringFromCString("Failed to retrieve a context"
); |
| 105 goto fail; |
| 106 } |
| 107 {% endif %} |
| 108 {% if method.is_call_with_script_arguments %} |
| 109 {# Last parameter is the customArgument #} |
| 110 Dart_Handle customArgument = Dart_GetNativeArgument(args, Dart_GetNative
ArgumentCount(args) - 1); |
| 111 RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArgum
ents(customArgument, exception)); |
| 112 if (!scriptArguments) |
| 113 goto fail; |
| 114 {% endif %} |
| 115 {% if method.number_of_arguments != method.number_of_required_arguments
%} |
| 116 int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativ
eArgumentCount(args); |
| 117 {% endif %} |
| 118 {% if method.has_exception_state %} |
| 119 ExceptionState es; |
| 120 {% endif %} |
| 121 {{generate_arguments(method) | indent(8)}} |
| 122 {{callback_return(method, method.dart_set_return_value, method.cpp_value
)}} |
| 123 {% if method.has_exception_state %} |
| 124 if (es.had_exception()) { |
| 125 exception = es.GetDartException(args, {{method.auto_scope}}); |
| 126 goto fail; |
| 127 } |
| 128 |
| 129 {% endif %} |
| 130 return; |
| 131 } |
| 132 |
| 133 {% if arguments_count > 0 or method.has_exception_state or method.is_call_with_s
cript_state or method.is_call_with_execution_context or method.is_call_with_scri
pt_arguments %} |
| 134 fail: |
| 135 Dart_ThrowException(exception); |
| 136 ASSERT_NOT_REACHED(); |
| 137 {% endif %} |
| 138 } |
| 139 {% endmacro %} |
| 140 |
| 141 |
| 142 {##############################################################################} |
| 143 {% macro callback_return(method, dart_set_return_value, cpp_value) %} |
| 144 {%- if method.union_arguments -%} |
| 145 {{callback_union_return(method) | indent(8)}} |
| 146 {%- elif method.idl_type == 'void' -%} |
| 147 {{cpp_value}}; |
| 148 {%- elif method.is_constructor -%} |
| 149 DartConverter<{{cpp_class}}*>::SetReturnValue(args, WTF::getPtr({{cpp_value}}),
{{method.auto_scope}}); |
| 150 {%- else -%} |
| 151 {{dart_set_return_value}}; |
| 152 {%- endif -%} |
| 153 {% endmacro %} |
| 154 |
| 155 |
| 156 {##############################################################################} |
| 157 {% macro callback_union_return(method, argument_count) %} |
| 158 {% set type_index = 0 %} |
| 159 {% for union_argument in method.union_arguments %} |
| 160 {{method.cpp_type[type_index]}} {{union_argument}}; |
| 161 {% set type_index = type_index + 1 %} |
| 162 {% endfor %} |
| 163 {{method.cpp_value}}; |
| 164 |
| 165 {% set union_set_result_index = 0 %} |
| 166 {% for union_argument in method.union_arguments %} |
| 167 if ({{union_argument}}) { |
| 168 {{method.dart_set_return_value[union_set_result_index]}}; |
| 169 return; |
| 170 } |
| 171 {% set union_set_result_index = union_set_result_index + 1 %} |
| 172 {% endfor %} |
| 173 {% endmacro %} |
| 174 |
| 175 |
| 176 {##############################################################################} |
| 177 {% macro generate_argument(method, argument) %} |
| 178 {# If sequence result is passed as an argument not as function return value. #} |
| 179 {% if argument.is_optional and |
| 180 not argument.has_default and |
| 181 not argument.is_callback_interface %} |
| 182 {# Optional arguments without a default value generate an early call with |
| 183 fewer arguments if they are omitted. #} |
| 184 if (UNLIKELY(argCount <= {{argument.arg_index}})) { |
| 185 {{callback_return(method, argument.dart_set_return_value, argument.cpp_value
)}} |
| 186 if (exception) |
| 187 goto fail; |
| 188 return; |
| 189 } |
| 190 {% endif %} |
| 191 {% if argument.is_callback_interface %} |
| 192 {# Callback functions must be functions: |
| 193 http://www.w3.org/TR/WebIDL/#es-callback-function #} |
| 194 {% if argument.is_optional %} |
| 195 {{argument.local_cpp_type}} {{argument.name}}; |
| 196 if (argCount > {{argument.arg_index}}) { |
| 197 {{argument.name}} = DartConverter<{{argument.implemented_as}}*>::FromArgumen
tsWithNullCheck(args, {{argument.arg_index}}, exception); |
| 198 } |
| 199 {% else %}{# argument.is_optional #} |
| 200 {{argument.local_cpp_type}} {{argument.name}} = DartConverter<{{argument.impleme
nted_as}}*>::FromArgumentsWithNullCheck(args, {{argument.arg_index}}, exception)
; |
| 201 {% endif %}{# argument.is_optional #} |
| 202 {% else %}{# argument.is_callback_interface #} |
| 203 {% if argument.is_optional and argument.has_default -%} |
| 204 {{argument.local_cpp_type}} {{argument.name}} = |
| 205 (argCount <= {{argument.arg_index}}) ? ({{argument.default_value}}) : {{argu
ment.dart_value_to_local_cpp_value}}; |
| 206 {% elif argument.is_array_or_sequence_type %} |
| 207 {{argument.local_cpp_type}} {{argument.name}}; |
| 208 {{argument.dart_value_to_local_cpp_value}}; |
| 209 {% else %} |
| 210 {{argument.local_cpp_type}} {{argument.name}} = {{argument.dart_value_to_local_c
pp_value}}; |
| 211 {% endif %} |
| 212 {% endif %}{# argument.is_callback_interface #} |
| 213 if (exception) |
| 214 goto fail; |
| 215 {% endmacro %} |
| 216 |
| 217 |
| 218 {######################################} |
| 219 {% macro generate_arguments(method) %} |
| 220 {%- for argument in method.arguments -%} |
| 221 {{generate_argument(method, argument)}} |
| 222 {%- endfor -%} |
| 223 {% endmacro %} |
| 224 |
| 225 {##############################################################################} |
| 226 {% macro static_method_name(name, overload_index) %} |
| 227 {% set name = 'constructor' if not name else name -%} |
| 228 {% if overload_index -%} |
| 229 {{name}}Callback_{{overload_index}} |
| 230 {%- else -%} |
| 231 {{name}}Callback |
| 232 {%- endif %} |
| 233 {% endmacro -%} |
| 234 |
| 235 |
| 236 {##############################################################################} |
| 237 {% macro generate_resolver_body(dart_class, class_name, method) %} |
| 238 {% for native_entry_group in method.native_entries|groupby('resolver_string') %} |
| 239 {% set uses_script_args = method.is_call_with_script_arguments %} |
| 240 {% if method.overload_index %} |
| 241 {% set method_name = static_method_name(method.name) + "Dispatcher" %} |
| 242 {% else %} |
| 243 {% set method_name = static_method_name(method.name) %} |
| 244 {% endif %} |
| 245 {% set resolver_string = native_entry_group.grouper %} |
| 246 {% if method.is_custom %} |
| 247 // FIXME: we are missing changes from dart.idl so we don't always know how many |
| 248 // args custom methods will take so we ignore that check which could hurt perf |
| 249 // and security but lets us get everything running quicker. |
| 250 if (name == "{{resolver_string}}") { |
| 251 *autoSetupScope = {{method.auto_scope}}; |
| 252 return {{dart_class}}Internal::{{method_name}}; |
| 253 } |
| 254 {% else %} |
| 255 {% set args_one_based = method.number_of_arguments %} |
| 256 {% set args_required_one_based = method.number_of_required_arguments %} |
| 257 {% if not method.is_static %} |
| 258 {% set args_one_based = args_one_based + 1 %} |
| 259 {% set args_required_one_based = args_required_one_based + 1 %} |
| 260 {% endif %} |
| 261 |
| 262 {% if uses_script_args %} |
| 263 {# FIXME(vsm): At least one script argument is expected. Generalize? #} |
| 264 {% set args_one_based = args_one_based + 1 %} |
| 265 {% set args_required_one_based = args_required_one_based + 1 %} |
| 266 {% endif %} |
| 267 |
| 268 {% if args_one_based == args_required_one_based %} |
| 269 if (argumentCount == {{args_one_based}} && name == "{{resolver_string}}") { |
| 270 *autoSetupScope = {{method.auto_scope}}; |
| 271 return {{dart_class}}Internal::{{method_name}}; |
| 272 } |
| 273 {% else %} |
| 274 if (argumentCount >= {{args_required_one_based}} && argumentCount <= {{args_one_
based}} && name == "{{resolver_string}}") { |
| 275 *autoSetupScope = {{method.auto_scope}}; |
| 276 return {{dart_class}}Internal::{{method_name}}; |
| 277 } |
| 278 {% endif %} |
| 279 {% endif %} |
| 280 {% endfor %} |
| 281 {% endmacro %} |
| 282 |
| 283 |
| 284 {##############################################################################} |
| 285 {% macro generate_symbolizer_body(dart_class, class_name, method) %} |
| 286 {% for native_entry_group in method.native_entries|groupby('resolver_string') %} |
| 287 {% set uses_script_args = method.is_call_with_script_arguments %} |
| 288 {% if method.overload_index %} |
| 289 {% set method_name = static_method_name(method.name) + "Dispatcher" %} |
| 290 {% else %} |
| 291 {% set method_name = static_method_name(method.name) %} |
| 292 {% endif %} |
| 293 {% set resolver_string = native_entry_group.grouper %} |
| 294 if (native_function == {{dart_class}}Internal::{{method_name}}) { |
| 295 return reinterpret_cast<const uint8_t*>("{{resolver_string}}"); |
| 296 } |
| 297 {% endfor %} |
| 298 {% endmacro %} |
| 299 |
| 300 |
| 301 {##############################################################################} |
| 302 {% macro generate_constructor(constructor, arguments_count, overload='') %} |
| 303 {% if overload == '' %} |
| 304 {% set overload_index = constructor.overload_index %} |
| 305 {% else %} |
| 306 {% set overload_index = overload %} |
| 307 {% endif %} |
| 308 static void {{static_method_name(constructor.name, overload_index)}}(Dart_Native
Arguments args) |
| 309 { |
| 310 {% if arguments_count > 0 or |
| 311 constructor.has_exception_state or |
| 312 is_constructor_call_with_execution_context or |
| 313 is_constructor_call_with_document or |
| 314 (constructor == named_constructor) %} |
| 315 Dart_Handle exception = nullptr; |
| 316 {% endif %} |
| 317 { |
| 318 {% if is_constructor_call_with_execution_context %} |
| 319 ExecutionContext* context = DOMDartState::CurrentDocument(); |
| 320 if (!context) { |
| 321 exception = Dart_NewStringFromCString("Failed to retrieve a context"
); |
| 322 goto fail; |
| 323 } |
| 324 {% endif %} |
| 325 {% if is_constructor_call_with_document or (constructor == named_constructor) %} |
| 326 LocalDOMWindow* domWindow = DOMDartState::CurrentWindow(); |
| 327 if (!domWindow) { |
| 328 exception = Dart_NewStringFromCString("Failed to fetch domWindow"); |
| 329 goto fail; |
| 330 } |
| 331 Document& document = *domWindow->document(); |
| 332 {% endif %} |
| 333 int argCount /* FIXME(vsm): Remove this. */ ALLOW_UNUSED = Dart_GetNativ
eArgumentCount(args); |
| 334 {% if constructor.has_exception_state %} |
| 335 ExceptionState es; |
| 336 {% endif %} |
| 337 {{generate_arguments(constructor) | indent(8)}} |
| 338 {{callback_return(constructor, constructor.dart_set_return_value, constr
uctor.cpp_value) | indent(8)}} |
| 339 {% if constructor.has_exception_state %} |
| 340 if (es.had_exception()) { |
| 341 exception = es.GetDartException(args, {{constructor.auto_scope}}); |
| 342 goto fail; |
| 343 } |
| 344 |
| 345 {% endif %} |
| 346 return; |
| 347 } |
| 348 |
| 349 {% if arguments_count > 0 or constructor.has_exception_state or is_constructor_c
all_with_execution_context or is_constructor_call_with_document or (constructor
== named_constructor) %} |
| 350 fail: |
| 351 Dart_ThrowException(exception); |
| 352 ASSERT_NOT_REACHED(); |
| 353 {% endif %} |
| 354 } |
| 355 {% endmacro %} |
| 356 |
| 357 |
| 358 {##############################################################################} |
| 359 {% macro generate_event_constructor() %} |
| 360 static void eventConstructorCallback(Dart_NativeArguments args) |
| 361 { |
| 362 Dart_SetReturnValue(args, Dart_Null()); |
| 363 } |
| 364 {% endmacro %} |
| 365 |
| 366 , |
| 367 {##############################################################################} |
| 368 {% macro generate_resolver_constructor(dart_class, class_name, constructor) %} |
| 369 {% for native_entry in constructor.native_entries %} |
| 370 {% set resolver_string = native_entry.resolver_string %} |
| 371 {% if constructor.overload_index %} |
| 372 {% set constructor_name = static_method_name(constructor.name) + "Dispatcher"
%} |
| 373 {% else %} |
| 374 {% set constructor_name = static_method_name(constructor.name) %} |
| 375 {% endif %} |
| 376 {% if has_custom_constructor %} |
| 377 if (name == "{{resolver_string}}") { |
| 378 {% elif constructor.number_of_arguments == constructor.number_of_required_argume
nts %} |
| 379 if (argumentCount == {{constructor.number_of_arguments}} && name == "{{resolver_
string}}") { |
| 380 {% else %} |
| 381 if (argumentCount >= {{constructor.number_of_required_arguments}} && argumentCou
nt <= {{constructor.number_of_arguments}} && name == "{{resolver_string}}") { |
| 382 {% endif %} |
| 383 *autoSetupScope = {{constructor.auto_scope}}; |
| 384 return {{dart_class}}Internal::{{constructor_name}}; |
| 385 } |
| 386 {% endfor %} |
| 387 {% endmacro %} |
| 388 |
| 389 {##############################################################################} |
| 390 {% macro generate_resolver_event_constructor(dart_class, class_name) %} |
| 391 {% set resolver_string = interface_name + "_constructorCallback" %} |
| 392 if (argumentCount == 2 && name == "{{resolver_string}}") { |
| 393 *autoSetupScope = 1; |
| 394 return {{dart_class}}Internal::eventConstructorCallback; |
| 395 } |
| 396 {% endmacro %} |
| 397 |
| 398 {##############################################################################} |
| 399 {% macro generate_symbolizer_constructor(dart_class, class_name, constructor) %} |
| 400 {% for native_entry in constructor.native_entries %} |
| 401 {% set resolver_string = native_entry.resolver_string %} |
| 402 if (native_function == {{dart_class}}Internal::{{static_method_name(constructor.
name, constructor.overload_index)}}) { |
| 403 return reinterpret_cast<const uint8_t*>("{{resolver_string}}"); |
| 404 } |
| 405 {% endfor %} |
| 406 {% endmacro %} |
| OLD | NEW |