| OLD | NEW |
| 1 {% from 'utilities.cpp.tmpl' import declare_enum_validation_variable, v8_value_t
o_local_cpp_value %} | 1 {% from 'utilities.cpp.tmpl' import declare_enum_validation_variable, v8_value_t
o_local_cpp_value %} |
| 2 | 2 |
| 3 {##############################################################################} | 3 {##############################################################################} |
| 4 {% macro generate_method(method, world_suffix) %} | 4 {% macro generate_method(method, world_suffix) %} |
| 5 static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
v8::FunctionCallbackInfo<v8::Value>& info) | 5 static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const
v8::FunctionCallbackInfo<v8::Value>& info) { |
| 6 {% filter format_remove_duplicates([ | 6 {% filter format_remove_duplicates([ |
| 7 'ExceptionState exceptionState', | 7 'ExceptionState exceptionState', |
| 8 'ScriptState* scriptState = ']) %} | 8 'ScriptState* scriptState = ']) %} |
| 9 { | 9 {% set define_exception_state -%} |
| 10 {% set define_exception_state -%} | 10 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCont
ext, "{{interface_name}}", "{{method.name}}"); |
| 11 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCo
ntext, "{{interface_name}}", "{{method.name}}"); | 11 {%- endset %} |
| 12 {%- endset %} | |
| 13 | 12 |
| 14 {% set function_call = func_call_with_prep_of_args(method, world_suffix) %} | 13 {% set function_call = func_call_with_prep_of_args(method, world_suffix) %} |
| 15 | 14 |
| 16 {% if 'exceptionState' in function_call %} | 15 {% if 'exceptionState' in function_call %} |
| 17 {{define_exception_state}} | 16 {{define_exception_state}} |
| 18 {% if method.returns_promise %} | 17 {% if method.returns_promise %} |
| 19 ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState); | 18 ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState); |
| 20 {% endif %} | 19 {% endif %} |
| 21 {% endif %} | 20 {% endif %} |
| 22 | 21 |
| 23 {% if not method.is_static %} | 22 {% if not method.is_static %} |
| 24 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder()); | 23 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder()); |
| 25 {% endif %} | 24 {% endif %} |
| 26 | 25 |
| 27 {# Security checks #} | 26 {# Security checks #} |
| 28 {% if method.is_check_security_for_receiver %} | 27 {% if method.is_check_security_for_receiver %} |
| 29 {{define_exception_state}} | 28 {{define_exception_state}} |
| 30 {% if interface_name == 'EventTarget' %} | 29 {% if interface_name == 'EventTarget' %} |
| 31 // Performance hack for EventTarget. Checking whether it's a Window or not | 30 // Performance hack for EventTarget. Checking whether it's a Window or not |
| 32 // prior to the call to BindingSecurity::shouldAllowAccessTo increases 30% | 31 // prior to the call to BindingSecurity::shouldAllowAccessTo increases 30% |
| 33 // of speed performance on Android Nexus 7 as of Dec 2015. ALWAYS_INLINE | 32 // of speed performance on Android Nexus 7 as of Dec 2015. ALWAYS_INLINE |
| 34 // didn't work in this case. | 33 // didn't work in this case. |
| 35 if (const DOMWindow* window = impl->toDOMWindow()) { | 34 if (const DOMWindow* window = impl->toDOMWindow()) { |
| 36 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsola
te()), window, exceptionState)) { | 35 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()
), window, exceptionState)) { |
| 37 return; | 36 return; |
| 38 } | |
| 39 } | 37 } |
| 40 {% else %}{# interface_name == 'EventTarget' #} | 38 } |
| 41 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()
), impl, exceptionState)) { | 39 {% else %}{# interface_name == 'EventTarget' #} |
| 42 return; | 40 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()),
impl, exceptionState)) { |
| 43 } | 41 return; |
| 44 {% endif %}{# interface_name == 'EventTarget' #} | 42 } |
| 45 {% endif %} | 43 {% endif %}{# interface_name == 'EventTarget' #} |
| 46 {% if method.is_check_security_for_return_value %} | 44 {% endif %} |
| 47 {{define_exception_state}} | 45 {% if method.is_check_security_for_return_value %} |
| 48 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()
), {{method.cpp_value}}, exceptionState)) { | 46 {{define_exception_state}} |
| 49 v8SetReturnValueNull(info); | 47 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()),
{{method.cpp_value}}, exceptionState)) { |
| 50 return; | 48 v8SetReturnValueNull(info); |
| 51 } | 49 return; |
| 52 {% endif %} | 50 } |
| 51 {% endif %} |
| 53 | 52 |
| 54 {% if 'scriptState' in function_call %} | 53 {% if 'scriptState' in function_call %} |
| 55 {% if method.is_static %} | 54 {% if method.is_static %} |
| 56 ScriptState* scriptState = ScriptState::forFunctionObject(info); | 55 ScriptState* scriptState = ScriptState::forFunctionObject(info); |
| 57 {% else %} | 56 {% else %} |
| 58 ScriptState* scriptState = ScriptState::forReceiverObject(info); | 57 ScriptState* scriptState = ScriptState::forReceiverObject(info); |
| 59 {% endif %} | 58 {% endif %} |
| 60 {% endif %} | 59 {% endif %} |
| 61 | 60 |
| 62 {% if method.is_custom_element_callbacks %} | 61 {% if method.is_custom_element_callbacks %} |
| 63 V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope; | 62 V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope; |
| 64 {% endif %} | 63 {% endif %} |
| 65 | 64 |
| 66 {{function_call | indent}} | 65 {{function_call | indent(2)}} |
| 67 } | 66 } |
| 68 {% endfilter %} | 67 {% endfilter %} |
| 69 {% endmacro %} | 68 {% endmacro %} |
| 70 | 69 |
| 71 | 70 |
| 72 {######################################} | 71 {######################################} |
| 73 {% macro func_call_with_prep_of_args(method, world_suffix) %} | 72 {% macro func_call_with_prep_of_args(method, world_suffix) %} |
| 74 {{generate_arguments(method, world_suffix)}} | 73 {{generate_arguments(method, world_suffix)}} |
| 75 {% if world_suffix %} | 74 {% if world_suffix %} |
| 76 {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_
value)}} | 75 {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_
value)}} |
| 77 {% else %} | 76 {% else %} |
| 78 {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value)}} | 77 {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value)}} |
| 79 {% endif %} | 78 {% endif %} |
| 80 {% endmacro %} | 79 {% endmacro %} |
| 81 | 80 |
| 82 | 81 |
| 83 {######################################} | 82 {######################################} |
| 84 {% macro generate_arguments(method, world_suffix) %} | 83 {% macro generate_arguments(method, world_suffix) %} |
| 85 {% if method.arguments %} | 84 {% if method.arguments %} |
| 86 | 85 |
| 87 {# Overloaded methods/constructors have length checked during overload resolutio
n #} | 86 {# Overloaded methods/constructors have length checked during overload resolutio
n #} |
| 88 {% if method.number_of_required_arguments and not method.overload_index %} | 87 {% if method.number_of_required_arguments and not method.overload_index %} |
| 89 if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) { | 88 if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) { |
| 90 {{throw_type_error(method, | 89 {{throw_type_error(method, |
| 91 'ExceptionMessages::notEnoughArguments(%(expected)d, info.Length())' | 90 'ExceptionMessages::notEnoughArguments(%(expected)d, info.Length())' |
| 92 | format(expected=method.number_of_required_arguments))}} | 91 | format(expected=method.number_of_required_arguments))}} |
| 93 return; | 92 return; |
| 94 } | 93 } |
| 95 {% endif %} | 94 {% endif %} |
| 96 | 95 |
| 97 {% for argument in method.arguments %} | 96 {% for argument in method.arguments %} |
| 98 {{argument.cpp_type}} {{argument.name}}; | 97 {{argument.cpp_type}} {{argument.name}}; |
| 99 {% endfor %} | 98 {% endfor %} |
| 100 {% if method.has_optional_argument_without_default_value %} | 99 {% if method.has_optional_argument_without_default_value %} |
| 101 {# Count the effective number of arguments. (arg1, arg2, undefined) is | 100 {# Count the effective number of arguments. (arg1, arg2, undefined) is |
| 102 interpreted as two arguments are passed and (arg1, undefined, arg3) is | 101 interpreted as two arguments are passed and (arg1, undefined, arg3) is |
| 103 interpreted as three arguments are passed. #} | 102 interpreted as three arguments are passed. #} |
| 104 int numArgsPassed = info.Length(); | 103 int numArgsPassed = info.Length(); |
| 105 while (numArgsPassed > 0) { | 104 while (numArgsPassed > 0) { |
| 106 if (!info[numArgsPassed - 1]->IsUndefined()) | 105 if (!info[numArgsPassed - 1]->IsUndefined()) |
| 107 break; | 106 break; |
| 108 --numArgsPassed; | 107 --numArgsPassed; |
| 109 } | 108 } |
| 110 {% endif %} | 109 {% endif %} |
| 111 {% for argument in method.arguments %} | 110 {% for argument in method.arguments %} |
| 112 {% if argument.set_default_value %} | 111 {% if argument.set_default_value %} |
| 113 if (!info[{{argument.index}}]->IsUndefined()) { | 112 if (!info[{{argument.index}}]->IsUndefined()) { |
| 114 {{generate_argument(method, argument, world_suffix) | indent}} | 113 {{generate_argument(method, argument, world_suffix) | indent(2)}} |
| 115 } else { | 114 } else { |
| 116 {{argument.set_default_value | indent}}; | 115 {{argument.set_default_value | indent(2)}}; |
| 117 } | 116 } |
| 118 {% else %} | 117 {% else %} |
| 119 {{generate_argument(method, argument, world_suffix)}} | 118 {{generate_argument(method, argument, world_suffix)}} |
| 120 {% endif %} | 119 {% endif %} |
| 121 {% endfor %} | 120 {% endfor %} |
| 122 | 121 |
| 123 {% endif %}{# method.arguments #} | 122 {% endif %}{# method.arguments #} |
| 124 {% endmacro %} | 123 {% endmacro %} |
| 125 | 124 |
| 126 | 125 |
| 127 {######################################} | 126 {######################################} |
| 128 {% macro generate_argument(method, argument, world_suffix) %} | 127 {% macro generate_argument(method, argument, world_suffix) %} |
| 129 {% if argument.is_optional_without_default_value %} | 128 {% if argument.is_optional_without_default_value %} |
| 130 {# Optional arguments without a default value generate an early call with | 129 {# Optional arguments without a default value generate an early call with |
| 131 fewer arguments if they are omitted. | 130 fewer arguments if they are omitted. |
| 132 Optional Dictionary arguments default to empty dictionary. #} | 131 Optional Dictionary arguments default to empty dictionary. #} |
| 133 if (UNLIKELY(numArgsPassed <= {{argument.index}})) { | 132 if (UNLIKELY(numArgsPassed <= {{argument.index}})) { |
| 134 {% if world_suffix %} | 133 {% if world_suffix %} |
| 135 {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argum
ent.cpp_value) | indent}} | 134 {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argumen
t.cpp_value) | indent(2)}} |
| 136 {% else %} | 135 {% else %} |
| 137 {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value)
| indent}} | 136 {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) |
indent(2)}} |
| 138 {% endif %} | 137 {% endif %} |
| 139 return; | 138 return; |
| 140 } | 139 } |
| 141 {% endif %} | 140 {% endif %} |
| 142 {% if argument.is_callback_interface %} | 141 {% if argument.is_callback_interface %} |
| 143 {# FIXME: remove EventListener special case #} | 142 {# FIXME: remove EventListener special case #} |
| 144 {% if argument.idl_type == 'EventListener' %} | 143 {% if argument.idl_type == 'EventListener' %} |
| 145 {% if method.name == 'removeEventListener' or method.name == 'removeListener' %} | 144 {% if method.name == 'removeEventListener' or method.name == 'removeListener' %} |
| 146 {{argument.name}} = V8EventListenerHelper::getEventListener(ScriptState::current
(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOnly); | 145 {{argument.name}} = V8EventListenerHelper::getEventListener(ScriptState::current
(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOnly); |
| 147 {% else %}{# method.name == 'addEventListener' #} | 146 {% else %}{# method.name == 'addEventListener' #} |
| 148 {{argument.name}} = V8EventListenerHelper::getEventListener(ScriptState::current
(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOrCreate); | 147 {{argument.name}} = V8EventListenerHelper::getEventListener(ScriptState::current
(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOrCreate); |
| 149 {% endif %}{# method.name #} | 148 {% endif %}{# method.name #} |
| 150 {% else %}{# argument.idl_type == 'EventListener' #} | 149 {% else %}{# argument.idl_type == 'EventListener' #} |
| 151 {# Callback functions must be functions: | 150 {# Callback functions must be functions: |
| 152 http://www.w3.org/TR/WebIDL/#es-callback-function #} | 151 http://www.w3.org/TR/WebIDL/#es-callback-function #} |
| 153 {% if argument.is_optional %} | 152 {% if argument.is_optional %} |
| 154 if (!isUndefinedOrNull(info[{{argument.index}}])) { | 153 if (!isUndefinedOrNull(info[{{argument.index}}])) { |
| 155 if (!info[{{argument.index}}]->IsFunction()) { | 154 if (!info[{{argument.index}}]->IsFunction()) { |
| 156 {{throw_argument_error(method, argument, "The callback provided as param
eter %(index)d is not a function.")}} | 155 {{throw_argument_error(method, argument, "The callback provided as parameter
%(index)d is not a function.")}} |
| 157 return; | 156 return; |
| 158 } | 157 } |
| 159 {{argument.name}} = V8{{argument.idl_type}}::create(v8::Local<v8::Function>:
:Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate())); | 158 {{argument.name}} = V8{{argument.idl_type}}::create(v8::Local<v8::Function>::C
ast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate())); |
| 160 } else { | 159 } else { |
| 161 {{argument.name}} = nullptr; | 160 {{argument.name}} = nullptr; |
| 162 } | 161 } |
| 163 {% else %}{# argument.is_optional #} | 162 {% else %}{# argument.is_optional #} |
| 164 if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{
{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %
}info[{{argument.index}}]->IsFunction(){% endif %}) { | 163 if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{
{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %
}info[{{argument.index}}]->IsFunction(){% endif %}) { |
| 165 {{throw_argument_error(method, argument, "The callback provided as parameter
%(index)d is not a function.")}} | 164 {{throw_argument_error(method, argument, "The callback provided as parameter %
(index)d is not a function.")}} |
| 166 return; | 165 return; |
| 167 } | 166 } |
| 168 {{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNul
l() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Local<v8::Functio
n>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate())); | 167 {{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNul
l() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Local<v8::Functio
n>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate())); |
| 169 {% endif %}{# argument.is_optional #} | 168 {% endif %}{# argument.is_optional #} |
| 170 {% endif %}{# argument.idl_type == 'EventListener' #} | 169 {% endif %}{# argument.idl_type == 'EventListener' #} |
| 171 {% elif argument.is_callback_function %} | 170 {% elif argument.is_callback_function %} |
| 172 if (!info[{{argument.index}}]->IsFunction(){% if argument.is_nullable %} && !inf
o[{{argument.index}}]->IsNull(){% endif %}) { | 171 if (!info[{{argument.index}}]->IsFunction(){% if argument.is_nullable %} && !inf
o[{{argument.index}}]->IsNull(){% endif %}) { |
| 173 {{throw_argument_error(method, argument, "The callback provided as parameter
%(index)d is not a function.")}} | 172 {{throw_argument_error(method, argument, "The callback provided as parameter %
(index)d is not a function.")}} |
| 174 return; | 173 return; |
| 175 } | 174 } |
| 176 {{v8_value_to_local_cpp_value(argument)}} | 175 {{v8_value_to_local_cpp_value(argument)}} |
| 177 {% elif argument.is_variadic_wrapper_type %} | 176 {% elif argument.is_variadic_wrapper_type %} |
| 178 for (int i = {{argument.index}}; i < info.Length(); ++i) { | 177 for (int i = {{argument.index}}; i < info.Length(); ++i) { |
| 179 if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) { | 178 if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) { |
| 180 {{throw_argument_error(method, argument, "parameter %(index)d is not of
type '%(type)s'.")}} | 179 {{throw_argument_error(method, argument, "parameter %(index)d is not of type
'%(type)s'.")}} |
| 181 return; | 180 return; |
| 182 } | 181 } |
| 183 {{argument.name}}.append(V8{{argument.idl_type}}::toImpl(v8::Local<v8::Objec
t>::Cast(info[i]))); | 182 {{argument.name}}.append(V8{{argument.idl_type}}::toImpl(v8::Local<v8::Object>
::Cast(info[i]))); |
| 184 } | 183 } |
| 185 {% elif argument.is_dictionary %} | 184 {% elif argument.is_dictionary %} |
| 186 {% if not argument.use_permissive_dictionary_conversion %} | 185 {% if not argument.use_permissive_dictionary_conversion %} |
| 187 {# Dictionaries must have type Undefined, Null or Object: | 186 {# Dictionaries must have type Undefined, Null or Object: |
| 188 http://heycam.github.io/webidl/#es-dictionary #} | 187 http://heycam.github.io/webidl/#es-dictionary #} |
| 189 if (!isUndefinedOrNull(info[{{argument.index}}]) && !info[{{argument.index}}]->I
sObject()) { | 188 if (!isUndefinedOrNull(info[{{argument.index}}]) && !info[{{argument.index}}]->I
sObject()) { |
| 190 {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') i
s not an object.")}} | 189 {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') is
not an object.")}} |
| 191 return; | 190 return; |
| 192 } | 191 } |
| 193 {% endif %}{# not argument.use_permissive_dictionary_conversion #} | 192 {% endif %}{# not argument.use_permissive_dictionary_conversion #} |
| 194 {{v8_value_to_local_cpp_value(argument)}} | 193 {{v8_value_to_local_cpp_value(argument)}} |
| 195 {% elif argument.is_explicit_nullable %} | 194 {% elif argument.is_explicit_nullable %} |
| 196 if (!isUndefinedOrNull(info[{{argument.index}}])) { | 195 if (!isUndefinedOrNull(info[{{argument.index}}])) { |
| 197 {{v8_value_to_local_cpp_value(argument) | indent}} | 196 {{v8_value_to_local_cpp_value(argument) | indent(2)}} |
| 198 } | 197 } |
| 199 {% else %}{# argument.is_nullable #} | 198 {% else %}{# argument.is_nullable #} |
| 200 {{v8_value_to_local_cpp_value(argument)}} | 199 {{v8_value_to_local_cpp_value(argument)}} |
| 201 {% endif %}{# argument.is_nullable #} | 200 {% endif %}{# argument.is_nullable #} |
| 202 {# Type checking, possibly throw a TypeError, per: | 201 {# Type checking, possibly throw a TypeError, per: |
| 203 http://www.w3.org/TR/WebIDL/#es-type-mapping #} | 202 http://www.w3.org/TR/WebIDL/#es-type-mapping #} |
| 204 {% if argument.has_type_checking_interface and not argument.is_variadic_wrapper_
type %} | 203 {% if argument.has_type_checking_interface and not argument.is_variadic_wrapper_
type %} |
| 205 {# Type checking for wrapper interface types (if interface not implemented, | 204 {# Type checking for wrapper interface types (if interface not implemented, |
| 206 throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface | 205 throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface |
| 207 Note: for variadic arguments, the type checking is done for each matched | 206 Note: for variadic arguments, the type checking is done for each matched |
| 208 argument instead; see argument.is_variadic_wrapper_type code-path above. #} | 207 argument instead; see argument.is_variadic_wrapper_type code-path above. #} |
| 209 if (!{{argument.name}}{% if argument.is_nullable %} && !isUndefinedOrNull(info[{
{argument.index}}]){% endif %}) { | 208 if (!{{argument.name}}{% if argument.is_nullable %} && !isUndefinedOrNull(info[{
{argument.index}}]){% endif %}) { |
| 210 {{throw_argument_error(method, argument, "parameter %(index)d is not of type
'%(type)s'.")}} | 209 {{throw_argument_error(method, argument, "parameter %(index)d is not of type '
%(type)s'.")}} |
| 211 return; | 210 return; |
| 212 } | 211 } |
| 213 {% elif argument.enum_values %} | 212 {% elif argument.enum_values %} |
| 214 {# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #} | 213 {# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #} |
| 215 {% set enum_variable = 'valid' + argument.name[0].upper() + argument.name[1:] +
'Values' %} | 214 {% set enum_variable = 'valid' + argument.name[0].upper() + argument.name[1:] +
'Values' %} |
| 216 {{declare_enum_validation_variable(argument.enum_values, enum_variable)}} | 215 {{declare_enum_validation_variable(argument.enum_values, enum_variable)}} |
| 217 if (!isValidEnum({{argument.name}}, {{enum_variable}}, WTF_ARRAY_LENGTH({{enum_v
ariable}}), "{{argument.enum_type}}", exceptionState)) { | 216 if (!isValidEnum({{argument.name}}, {{enum_variable}}, WTF_ARRAY_LENGTH({{enum_v
ariable}}), "{{argument.enum_type}}", exceptionState)) { |
| 218 return; | 217 return; |
| 219 } | 218 } |
| 220 {% elif argument.idl_type == 'Promise' %} | 219 {% elif argument.idl_type == 'Promise' %} |
| 221 {# We require this for our implementation of promises, though not in spec: | 220 {# We require this for our implementation of promises, though not in spec: |
| 222 http://heycam.github.io/webidl/#es-promise #} | 221 http://heycam.github.io/webidl/#es-promise #} |
| 223 if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) { | 222 if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) { |
| 224 {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') i
s not an object.")}} | 223 {{throw_argument_error(method, argument, "parameter %(index)d ('%(name)s') is
not an object.")}} |
| 225 return; | 224 return; |
| 226 } | 225 } |
| 227 {% endif %} | 226 {% endif %} |
| 228 {% endmacro %} | 227 {% endmacro %} |
| 229 | 228 |
| 230 | 229 |
| 231 {######################################} | 230 {######################################} |
| 232 {% macro cpp_method_call(method, v8_set_return_value, cpp_value) %} | 231 {% macro cpp_method_call(method, v8_set_return_value, cpp_value) %} |
| 233 {% if method.is_custom_call_prologue %} | 232 {% if method.is_custom_call_prologue %} |
| 234 {{v8_class}}::{{method.name}}MethodPrologueCustom(info, impl); | 233 {{v8_class}}::{{method.name}}MethodPrologueCustom(info, impl); |
| 235 {% endif %} | 234 {% endif %} |
| (...skipping 10 matching lines...) Expand all Loading... |
| 246 {% if method.is_call_with_document %} | 245 {% if method.is_call_with_document %} |
| 247 {# [ConstructorCallWith=Document] #} | 246 {# [ConstructorCallWith=Document] #} |
| 248 Document& document = *toDocument(currentExecutionContext(info.GetIsolate())); | 247 Document& document = *toDocument(currentExecutionContext(info.GetIsolate())); |
| 249 {% endif %} | 248 {% endif %} |
| 250 {# Call #} | 249 {# Call #} |
| 251 {% if method.idl_type == 'void' %} | 250 {% if method.idl_type == 'void' %} |
| 252 {{cpp_value}}; | 251 {{cpp_value}}; |
| 253 {% elif method.is_implemented_in_private_script %} | 252 {% elif method.is_implemented_in_private_script %} |
| 254 {{method.cpp_type}} result{{method.cpp_type_initializer}}; | 253 {{method.cpp_type}} result{{method.cpp_type_initializer}}; |
| 255 if (!{{method.cpp_value}}) | 254 if (!{{method.cpp_value}}) |
| 256 return; | 255 return; |
| 257 {% elif method.use_output_parameter_for_result %} | 256 {% elif method.use_output_parameter_for_result %} |
| 258 {{method.cpp_type}} result; | 257 {{method.cpp_type}} result; |
| 259 {{cpp_value}}; | 258 {{cpp_value}}; |
| 260 {% elif method.is_constructor %} | 259 {% elif method.is_constructor %} |
| 261 {{method.cpp_type}} impl = {{cpp_value}}; | 260 {{method.cpp_type}} impl = {{cpp_value}}; |
| 262 {% elif method.use_local_result %} | 261 {% elif method.use_local_result %} |
| 263 {{method.cpp_type}} result = {{cpp_value}}; | 262 {{method.cpp_type}} result = {{cpp_value}}; |
| 264 {% endif %} | 263 {% endif %} |
| 265 {# Post-call #} | 264 {# Post-call #} |
| 266 {% if method.is_raises_exception %} | 265 {% if method.is_raises_exception %} |
| 267 if (exceptionState.hadException()) { | 266 if (exceptionState.hadException()) { |
| 268 return; | 267 return; |
| 269 } | 268 } |
| 270 {% endif %} | 269 {% endif %} |
| 271 {# Set return value #} | 270 {# Set return value #} |
| 272 {% if method.is_new_object and not method.do_not_test_new_object %} | 271 {% if method.is_new_object and not method.do_not_test_new_object %} |
| 273 // [NewObject] must always create a new wrapper. Check that a wrapper | 272 // [NewObject] must always create a new wrapper. Check that a wrapper |
| 274 // does not exist yet. | 273 // does not exist yet. |
| 275 DCHECK(!result || DOMDataStore::getWrapper(result, info.GetIsolate()).IsEmpty())
; | 274 DCHECK(!result || DOMDataStore::getWrapper(result, info.GetIsolate()).IsEmpty())
; |
| 276 {% endif %} | 275 {% endif %} |
| 277 {% if method.is_constructor %} | 276 {% if method.is_constructor %} |
| 278 {{generate_constructor_wrapper(method)}} | 277 {{generate_constructor_wrapper(method)}} |
| 279 {%- elif v8_set_return_value %} | 278 {%- elif v8_set_return_value %} |
| 280 {% if method.is_explicit_nullable %} | 279 {% if method.is_explicit_nullable %} |
| 281 if (result.isNull()) | 280 if (result.isNull()) |
| 282 v8SetReturnValueNull(info); | 281 v8SetReturnValueNull(info); |
| 283 else | 282 else |
| 284 {{v8_set_return_value}}; | 283 {{v8_set_return_value}}; |
| 285 {% else %} | 284 {% else %} |
| 286 {{v8_set_return_value}}; | 285 {{v8_set_return_value}}; |
| 287 {% endif %} | 286 {% endif %} |
| 288 {%- endif %}{# None for void #} | 287 {%- endif %}{# None for void #} |
| 289 {% if method.is_custom_call_epilogue %} | 288 {% if method.is_custom_call_epilogue %} |
| 290 {{v8_class}}::{{method.name}}MethodEpilogueCustom(info, impl); | 289 {{v8_class}}::{{method.name}}MethodEpilogueCustom(info, impl); |
| 291 {% endif %} | 290 {% endif %} |
| 292 {% endmacro %} | 291 {% endmacro %} |
| 293 | 292 |
| 294 | 293 |
| 295 {##############################################################################} | 294 {##############################################################################} |
| 296 {% macro throw_type_error(method, error_message) %} | 295 {% macro throw_type_error(method, error_message) %} |
| 297 {% if method.has_exception_state or | 296 {% if method.has_exception_state or method.returns_promise %} |
| 298 method.returns_promise %} | |
| 299 exceptionState.throwTypeError({{error_message}}); | 297 exceptionState.throwTypeError({{error_message}}); |
| 300 {%- elif method.is_constructor %} | 298 {%- elif method.is_constructor %} |
| 301 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToC
onstruct("{{interface_name}}", {{error_message}})); | 299 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToC
onstruct("{{interface_name}}", {{error_message}})); |
| 302 {%- else %} | 300 {%- else %} |
| 303 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToE
xecute("{{method.name}}", "{{interface_name}}", {{error_message}})); | 301 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::failedToE
xecute("{{method.name}}", "{{interface_name}}", {{error_message}})); |
| 304 {%- endif %} | 302 {%- endif %} |
| 305 {% endmacro %} | 303 {% endmacro %} |
| 306 | 304 |
| 307 | 305 |
| 308 {##############################################################################} | 306 {##############################################################################} |
| 309 {% macro throw_argument_error(method, argument, error_message) %} | 307 {% macro throw_argument_error(method, argument, error_message) %} |
| 310 {% set quoted_message = '"%s"' % (error_message | replace('\"', '\\\"')) %} | 308 {% set quoted_message = '"%s"' % (error_message | replace('\"', '\\\"')) %} |
| 311 {{throw_type_error(method, quoted_message | format(index=(argument.index + 1), n
ame=argument.name, type=argument.idl_type))}} | 309 {{throw_type_error(method, quoted_message | format(index=(argument.index + 1), n
ame=argument.name, type=argument.idl_type))}} |
| 312 {% endmacro %} | 310 {% endmacro %} |
| 313 | 311 |
| 314 | 312 |
| 315 {##############################################################################} | 313 {##############################################################################} |
| 316 {% macro runtime_determined_length_method(overloads) %} | 314 {% macro runtime_determined_length_method(overloads) %} |
| 317 static int {{overloads.name}}MethodLength() | 315 static int {{overloads.name}}MethodLength() { |
| 318 { | 316 {% for length, runtime_enabled_functions in overloads.runtime_determined_lengt
hs %} |
| 319 {% for length, runtime_enabled_functions in overloads.runtime_determined_len
gths %} | 317 {% for runtime_enabled_function in runtime_enabled_functions %} |
| 320 {% for runtime_enabled_function in runtime_enabled_functions %} | 318 {% filter runtime_enabled(runtime_enabled_function) %} |
| 321 {% filter runtime_enabled(runtime_enabled_function) %} | 319 return {{length}}; |
| 322 return {{length}}; | 320 {% endfilter %} |
| 323 {% endfilter %} | 321 {% endfor %} |
| 324 {% endfor %} | 322 {% endfor %} |
| 325 {% endfor %} | |
| 326 } | 323 } |
| 327 {% endmacro %} | 324 {% endmacro %} |
| 328 | 325 |
| 329 | 326 |
| 330 {##############################################################################} | 327 {##############################################################################} |
| 331 {% macro runtime_determined_maxarg_method(overloads) %} | 328 {% macro runtime_determined_maxarg_method(overloads) %} |
| 332 static int {{overloads.name}}MethodMaxArg() | 329 static int {{overloads.name}}MethodMaxArg() { |
| 333 { | 330 {% for length, runtime_enabled_functions in overloads.runtime_determined_maxar
gs %} |
| 334 {% for length, runtime_enabled_functions in overloads.runtime_determined_max
args %} | 331 {% for runtime_enabled_function in runtime_enabled_functions %} |
| 335 {% for runtime_enabled_function in runtime_enabled_functions %} | 332 {% filter runtime_enabled(runtime_enabled_function) %} |
| 336 {% filter runtime_enabled(runtime_enabled_function) %} | 333 return {{length}}; |
| 337 return {{length}}; | 334 {% endfilter %} |
| 338 {% endfilter %} | 335 {% endfor %} |
| 339 {% endfor %} | 336 {% endfor %} |
| 340 {% endfor %} | |
| 341 } | 337 } |
| 342 {% endmacro %} | 338 {% endmacro %} |
| 343 | 339 |
| 344 | 340 |
| 345 {##############################################################################} | 341 {##############################################################################} |
| 346 {% macro overload_resolution_method(overloads, world_suffix) %} | 342 {% macro overload_resolution_method(overloads, world_suffix) %} |
| 347 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
nfo<v8::Value>& info) | 343 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackI
nfo<v8::Value>& info) { |
| 348 { | 344 {% set fall_through_to_partial_overloads = not is_partial and overloads.has_pa
rtial_overloads %} |
| 349 {% set fall_through_to_partial_overloads = | 345 |
| 350 not is_partial and overloads.has_partial_overloads %} | 346 {% if overloads.measure_all_as %} |
| 351 | 347 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext
(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}}); |
| 352 {% if overloads.measure_all_as %} | 348 {% endif %} |
| 353 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionConte
xt(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}}); | 349 {% if overloads.deprecate_all_as %} |
| 354 {% endif %} | 350 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExec
utionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}}); |
| 355 {% if overloads.deprecate_all_as %} | 351 {% endif %} |
| 356 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentEx
ecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}}); | 352 |
| 357 {% endif %} | 353 {# First resolve by length #} |
| 358 | 354 {% if not fall_through_to_partial_overloads %} |
| 359 {# First resolve by length #} | 355 bool isArityError = false; |
| 360 {% if not fall_through_to_partial_overloads %} | 356 {% endif %} |
| 361 bool isArityError = false; | 357 {# 2. Initialize argcount to be min(maxarg, n). #} |
| 362 {% endif %} | 358 switch (std::min({{overloads.maxarg}}, info.Length())) { |
| 363 {# 2. Initialize argcount to be min(maxarg, n). #} | |
| 364 switch (std::min({{overloads.maxarg}}, info.Length())) { | |
| 365 {# 3. Remove from S all entries whose type list is not of length argcount. #
} | 359 {# 3. Remove from S all entries whose type list is not of length argcount. #
} |
| 366 {% for length, tests_methods in overloads.length_tests_methods %} | 360 {% for length, tests_methods in overloads.length_tests_methods %} |
| 367 {# 10. If i = d, then: #} | 361 {# 10. If i = d, then: #} |
| 368 case {{length}}: | 362 case {{length}}: |
| 369 {# Then resolve by testing argument #} | 363 {# Then resolve by testing argument #} |
| 370 {% for test, method in tests_methods %} | 364 {% for test, method in tests_methods %} |
| 371 {% if method.visible %} | 365 {% if method.visible %} |
| 372 {% filter runtime_enabled(not overloads.runtime_enabled_function_all and | 366 {% filter runtime_enabled(not overloads.runtime_enabled_function_all and |
| 373 method.runtime_enabled_function) %} | 367 method.runtime_enabled_function) %} |
| 374 if ({{test}}) { | 368 if ({{test}}) { |
| 375 {% if method.measure_as and not overloads.measure_all_as %} | 369 {% if method.measure_as and not overloads.measure_all_as %} |
| 376 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecut
ionContext(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); | 370 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionC
ontext(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); |
| 377 {% endif %} | |
| 378 {% if method.deprecate_as and not overloads.deprecate_all_as %} | |
| 379 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), c
urrentExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); | |
| 380 {% endif %} | |
| 381 {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info)
; | |
| 382 return; | |
| 383 } | |
| 384 {% endfilter %} | |
| 385 {% endif %} | 371 {% endif %} |
| 386 {% endfor %} | 372 {% if method.deprecate_as and not overloads.deprecate_all_as %} |
| 387 break; | 373 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), curre
ntExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); |
| 388 {% endfor %} | 374 {% endif %} |
| 375 {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info); |
| 376 return; |
| 377 } |
| 378 {% endfilter %} |
| 379 {% endif %} |
| 380 {% endfor %} |
| 381 break; |
| 382 {% endfor %}{# length, tests_methods #} |
| 389 {% if not fall_through_to_partial_overloads %} | 383 {% if not fall_through_to_partial_overloads %} |
| 390 default: | 384 default: |
| 391 {# 4. If S is empty, then throw a TypeError. #} | 385 {# 4. If S is empty, then throw a TypeError. #} |
| 392 isArityError = true; | 386 isArityError = true; |
| 393 {% endif %} | 387 {% endif %} |
| 394 } | 388 } |
| 395 | 389 |
| 396 {% if fall_through_to_partial_overloads %} | 390 {% if fall_through_to_partial_overloads %} |
| 397 | 391 |
| 398 DCHECK({{overloads.name}}MethodForPartialInterface); | 392 DCHECK({{overloads.name}}MethodForPartialInterface); |
| 399 ({{overloads.name}}MethodForPartialInterface)(info); | 393 ({{overloads.name}}MethodForPartialInterface)(info); |
| 400 | 394 |
| 401 {% else %}{# fall_through_to_partial_overloads #} | 395 {% else %}{# fall_through_to_partial_overloads #} |
| 402 | 396 |
| 403 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCo
ntext, "{{interface_name}}", "{{overloads.name}}"); | 397 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCont
ext, "{{interface_name}}", "{{overloads.name}}"); |
| 404 {% if overloads.returns_promise_all %} | 398 {% if overloads.returns_promise_all %} |
| 405 ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState); | 399 ExceptionToRejectPromiseScope rejectPromiseScope(info, exceptionState); |
| 406 {% endif %} | 400 {% endif %} |
| 407 | 401 |
| 408 if (isArityError) { | 402 if (isArityError) { |
| 409 {% if overloads.length != 0 %} | 403 {% if overloads.length != 0 %} |
| 410 if (info.Length() < {{overloads.length}}) { | 404 if (info.Length() < {{overloads.length}}) { |
| 411 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(
{{overloads.length}}, info.Length())); | 405 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{over
loads.length}}, info.Length())); |
| 412 return; | 406 return; |
| 413 } | |
| 414 {% endif %} | |
| 415 {% if overloads.valid_arities %} | |
| 416 if (info.Length() >= {{overloads.length}}) { | |
| 417 exceptionState.throwTypeError(ExceptionMessages::invalidArity("{{ove
rloads.valid_arities}}", info.Length())); | |
| 418 return; | |
| 419 } | |
| 420 {% endif %} | |
| 421 } | |
| 422 exceptionState.throwTypeError("No function was found that matched the signat
ure provided."); | |
| 423 | |
| 424 {% endif %}{# fall_through_to_partial_overloads #} | |
| 425 } | |
| 426 {% endmacro %} | |
| 427 | |
| 428 | |
| 429 {##############################################################################} | |
| 430 {% macro generate_post_message_impl(method) %} | |
| 431 static void postMessageImpl(const char* interfaceName, {{cpp_class}}* instance,
const v8::FunctionCallbackInfo<v8::Value>& info) | |
| 432 { | |
| 433 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCo
ntext, interfaceName, "postMessage"); | |
| 434 if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) { | |
| 435 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{me
thod.number_of_required_arguments}}, info.Length())); | |
| 436 return; | |
| 437 } | |
| 438 | |
| 439 Transferables transferables; | |
| 440 if (info.Length() > 1) { | |
| 441 const int transferablesArgIndex = 1; | |
| 442 if (!SerializedScriptValue::extractTransferables(info.GetIsolate(), info
[transferablesArgIndex], transferablesArgIndex, transferables, exceptionState))
{ | |
| 443 return; | |
| 444 } | |
| 445 } | |
| 446 | |
| 447 RefPtr<SerializedScriptValue> message; | |
| 448 if (instance->canTransferArrayBuffer()) { | |
| 449 // This instance supports sending array buffers by move semantics. | |
| 450 message = SerializedScriptValue::serialize(info.GetIsolate(), info[0], &
transferables, nullptr, exceptionState); | |
| 451 if (exceptionState.hadException()) | |
| 452 return; | |
| 453 } else { | |
| 454 // This instance doesn't support sending array buffers by move | |
| 455 // semantics. Emulate it by copy-and-neuter semantics that sends array | |
| 456 // buffers by copy semantics and then neuters the original array | |
| 457 // buffers. | |
| 458 | |
| 459 // Clear references to array buffers from transferables so that the | |
| 460 // serializer can consider the array buffers as non-transferable and | |
| 461 // copy them into the message. | |
| 462 ArrayBufferArray transferableArrayBuffers = transferables.arrayBuffers; | |
| 463 transferables.arrayBuffers.clear(); | |
| 464 message = SerializedScriptValue::serialize(info.GetIsolate(), info[0], &
transferables, nullptr, exceptionState); | |
| 465 if (exceptionState.hadException()) | |
| 466 return; | |
| 467 | |
| 468 // Neuter the original array buffers on the sender context. | |
| 469 SerializedScriptValue::transferArrayBufferContents(info.GetIsolate(), tr
ansferableArrayBuffers, exceptionState); | |
| 470 if (exceptionState.hadException()) | |
| 471 return; | |
| 472 } | |
| 473 | |
| 474 // FIXME: Only pass context/exceptionState if instance really requires it. | |
| 475 ExecutionContext* context = currentExecutionContext(info.GetIsolate()); | |
| 476 instance->postMessage(context, message.release(), transferables.messagePorts
, exceptionState); | |
| 477 } | |
| 478 {% endmacro %} | |
| 479 | |
| 480 | |
| 481 {##############################################################################} | |
| 482 {% macro method_callback(method, world_suffix) %} | |
| 483 void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInf
o<v8::Value>& info) | |
| 484 { | |
| 485 {% if not method.overloads %}{# Overloaded methods are measured in overload_
resolution_method() #} | |
| 486 {% if method.measure_as %} | |
| 487 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionConte
xt(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); | |
| 488 {% endif %} | |
| 489 {% if method.deprecate_as %} | |
| 490 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentEx
ecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); | |
| 491 {% endif %} | |
| 492 {% endif %}{# not method.overloads #} | |
| 493 {% if world_suffix in method.activity_logging_world_list %} | |
| 494 {% if method.is_static %} | |
| 495 ScriptState* scriptState = ScriptState::forFunctionObject(info); | |
| 496 {% else %} | |
| 497 ScriptState* scriptState = ScriptState::forReceiverObject(info); | |
| 498 {% endif %} | |
| 499 V8PerContextData* contextData = scriptState->perContextData(); | |
| 500 if (contextData && contextData->activityLogger()) { | |
| 501 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::Executi
onContext, "{{interface_name}}", "{{method.name}}"); | |
| 502 Vector<v8::Local<v8::Value>> loggerArgs = toImplArguments<Vector<v8::Loc
al<v8::Value>>>(info, 0, exceptionState); | |
| 503 contextData->activityLogger()->logMethod("{{interface_name}}.{{method.na
me}}", info.Length(), loggerArgs.data()); | |
| 504 } | 407 } |
| 505 {% endif %} | 408 {% endif %} |
| 506 {% if method.is_ce_reactions %} | 409 {% if overloads.valid_arities %} |
| 507 CEReactionsScope ceReactionsScope; | 410 if (info.Length() >= {{overloads.length}}) { |
| 411 exceptionState.throwTypeError(ExceptionMessages::invalidArity("{{overloads
.valid_arities}}", info.Length())); |
| 412 return; |
| 413 } |
| 508 {% endif %} | 414 {% endif %} |
| 509 {% if method.is_custom %} | 415 } |
| 510 {{v8_class}}::{{method.name}}MethodCustom(info); | 416 exceptionState.throwTypeError("No function was found that matched the signatur
e provided."); |
| 511 {% elif method.is_post_message %} | 417 |
| 512 postMessageImpl("{{interface_name}}", {{v8_class}}::toImpl(info.Holder()), i
nfo); | 418 {% endif %}{# fall_through_to_partial_overloads #} |
| 513 {% else %} | 419 } |
| 514 {{cpp_class_or_partial}}V8Internal::{{method.name}}Method{{world_suffix}}(in
fo); | 420 {% endmacro %} |
| 515 {% endif %} | 421 |
| 422 |
| 423 {##############################################################################} |
| 424 {% macro generate_post_message_impl(method) %} |
| 425 static void postMessageImpl(const char* interfaceName, {{cpp_class}}* instance,
const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 426 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCont
ext, interfaceName, "postMessage"); |
| 427 if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) { |
| 428 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{method
.number_of_required_arguments}}, info.Length())); |
| 429 return; |
| 430 } |
| 431 |
| 432 Transferables transferables; |
| 433 if (info.Length() > 1) { |
| 434 const int transferablesArgIndex = 1; |
| 435 if (!SerializedScriptValue::extractTransferables(info.GetIsolate(), info[tra
nsferablesArgIndex], transferablesArgIndex, transferables, exceptionState)) { |
| 436 return; |
| 437 } |
| 438 } |
| 439 |
| 440 RefPtr<SerializedScriptValue> message; |
| 441 if (instance->canTransferArrayBuffer()) { |
| 442 // This instance supports sending array buffers by move semantics. |
| 443 message = SerializedScriptValue::serialize(info.GetIsolate(), info[0], &tran
sferables, nullptr, exceptionState); |
| 444 if (exceptionState.hadException()) |
| 445 return; |
| 446 } else { |
| 447 // This instance doesn't support sending array buffers by move |
| 448 // semantics. Emulate it by copy-and-neuter semantics that sends array |
| 449 // buffers by copy semantics and then neuters the original array |
| 450 // buffers. |
| 451 |
| 452 // Clear references to array buffers from transferables so that the |
| 453 // serializer can consider the array buffers as non-transferable and |
| 454 // copy them into the message. |
| 455 ArrayBufferArray transferableArrayBuffers = transferables.arrayBuffers; |
| 456 transferables.arrayBuffers.clear(); |
| 457 message = SerializedScriptValue::serialize(info.GetIsolate(), info[0], &tran
sferables, nullptr, exceptionState); |
| 458 if (exceptionState.hadException()) |
| 459 return; |
| 460 |
| 461 // Neuter the original array buffers on the sender context. |
| 462 SerializedScriptValue::transferArrayBufferContents(info.GetIsolate(), transf
erableArrayBuffers, exceptionState); |
| 463 if (exceptionState.hadException()) |
| 464 return; |
| 465 } |
| 466 |
| 467 // FIXME: Only pass context/exceptionState if instance really requires it. |
| 468 ExecutionContext* context = currentExecutionContext(info.GetIsolate()); |
| 469 instance->postMessage(context, message.release(), transferables.messagePorts,
exceptionState); |
| 470 } |
| 471 {% endmacro %} |
| 472 |
| 473 |
| 474 {##############################################################################} |
| 475 {% macro method_callback(method, world_suffix) %} |
| 476 void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInf
o<v8::Value>& info) { |
| 477 {% if not method.overloads %}{# Overloaded methods are measured in overload_re
solution_method() #} |
| 478 {% if method.measure_as %} |
| 479 UseCounter::countIfNotPrivateScript(info.GetIsolate(), currentExecutionContext
(info.GetIsolate()), UseCounter::{{method.measure_as('Method')}}); |
| 480 {% endif %} |
| 481 {% if method.deprecate_as %} |
| 482 Deprecation::countDeprecationIfNotPrivateScript(info.GetIsolate(), currentExec
utionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}}); |
| 483 {% endif %} |
| 484 {% endif %}{# not method.overloads #} |
| 485 {% if world_suffix in method.activity_logging_world_list %} |
| 486 {% if method.is_static %} |
| 487 ScriptState* scriptState = ScriptState::forFunctionObject(info); |
| 488 {% else %} |
| 489 ScriptState* scriptState = ScriptState::forReceiverObject(info); |
| 490 {% endif %} |
| 491 V8PerContextData* contextData = scriptState->perContextData(); |
| 492 if (contextData && contextData->activityLogger()) { |
| 493 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ExecutionCo
ntext, "{{interface_name}}", "{{method.name}}"); |
| 494 Vector<v8::Local<v8::Value>> loggerArgs = toImplArguments<Vector<v8::Local<v
8::Value>>>(info, 0, exceptionState); |
| 495 contextData->activityLogger()->logMethod("{{interface_name}}.{{method.name}}
", info.Length(), loggerArgs.data()); |
| 496 } |
| 497 {% endif %} |
| 498 {% if method.is_ce_reactions %} |
| 499 CEReactionsScope ceReactionsScope; |
| 500 {% endif %} |
| 501 {% if method.is_custom %} |
| 502 {{v8_class}}::{{method.name}}MethodCustom(info); |
| 503 {% elif method.is_post_message %} |
| 504 postMessageImpl("{{interface_name}}", {{v8_class}}::toImpl(info.Holder()), inf
o); |
| 505 {% else %} |
| 506 {{cpp_class_or_partial}}V8Internal::{{method.name}}Method{{world_suffix}}(info
); |
| 507 {% endif %} |
| 516 } | 508 } |
| 517 {% endmacro %} | 509 {% endmacro %} |
| 518 | 510 |
| 519 | 511 |
| 520 {##############################################################################} | 512 {##############################################################################} |
| 521 {% macro origin_safe_method_getter(method, world_suffix) %} | 513 {% macro origin_safe_method_getter(method, world_suffix) %} |
| 522 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::Prop
ertyCallbackInfo<v8::Value>& info) | 514 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::Prop
ertyCallbackInfo<v8::Value>& info) { |
| 523 { | 515 static int domTemplateKey; // This address is used for a key to look up the do
m template. |
| 524 static int domTemplateKey; // This address is used for a key to look up the
dom template. | 516 V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate()); |
| 525 V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate()); | 517 const DOMWrapperWorld& world = DOMWrapperWorld::world(info.GetIsolate()->GetCu
rrentContext()); |
| 526 const DOMWrapperWorld& world = DOMWrapperWorld::world(info.GetIsolate()->Get
CurrentContext()); | 518 v8::Local<v8::FunctionTemplate> interfaceTemplate = data->findInterfaceTemplat
e(world, &{{v8_class}}::wrapperTypeInfo); |
| 527 v8::Local<v8::FunctionTemplate> interfaceTemplate = data->findInterfaceTempl
ate(world, &{{v8_class}}::wrapperTypeInfo); | 519 v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), int
erfaceTemplate); |
| 528 v8::Local<v8::Signature> signature = v8::Signature::New(info.GetIsolate(), i
nterfaceTemplate); | 520 |
| 529 | 521 v8::Local<v8::FunctionTemplate> methodTemplate = data->findOrCreateOperationTe
mplate(world, &domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCal
lback{{world_suffix}}, v8Undefined(), signature, {{method.length}}); |
| 530 v8::Local<v8::FunctionTemplate> methodTemplate = data->findOrCreateOperation
Template(world, &domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodC
allback{{world_suffix}}, v8Undefined(), signature, {{method.length}}); | 522 // Return the function by default, unless the user script has overwritten it. |
| 531 // Return the function by default, unless the user script has overwritten it
. | 523 v8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCurre
ntContext()).ToLocalChecked()); |
| 532 v8SetReturnValue(info, methodTemplate->GetFunction(info.GetIsolate()->GetCur
rentContext()).ToLocalChecked()); | 524 |
| 533 | 525 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder()); |
| 534 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder()); | 526 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()),
impl, BindingSecurity::ErrorReportOption::DoNotReport)) { |
| 535 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()
), impl, BindingSecurity::ErrorReportOption::DoNotReport)) { | 527 return; |
| 536 return; | 528 } |
| 537 } | 529 |
| 538 | 530 v8::Local<v8::Value> hiddenValue = V8HiddenValue::getHiddenValue(ScriptState::
current(info.GetIsolate()), v8::Local<v8::Object>::Cast(info.Holder()), v8Atomic
String(info.GetIsolate(), "{{method.name}}")); |
| 539 v8::Local<v8::Value> hiddenValue = V8HiddenValue::getHiddenValue(ScriptState
::current(info.GetIsolate()), v8::Local<v8::Object>::Cast(info.Holder()), v8Atom
icString(info.GetIsolate(), "{{method.name}}")); | 531 if (!hiddenValue.IsEmpty()) { |
| 540 if (!hiddenValue.IsEmpty()) { | 532 v8SetReturnValue(info, hiddenValue); |
| 541 v8SetReturnValue(info, hiddenValue); | 533 } |
| 542 } | 534 } |
| 543 } | 535 |
| 544 | 536 void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8:
:Name>, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 545 void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8:
:Name>, const v8::PropertyCallbackInfo<v8::Value>& info) | 537 {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}
(info); |
| 546 { | |
| 547 {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix
}}(info); | |
| 548 } | 538 } |
| 549 {% endmacro %} | 539 {% endmacro %} |
| 550 | 540 |
| 551 | 541 |
| 552 {##############################################################################} | 542 {##############################################################################} |
| 553 {% macro method_implemented_in_private_script(method) %} | 543 {% macro method_implemented_in_private_script(method) %} |
| 554 bool {{v8_class}}::PrivateScript::{{method.name}}Method({{method.argument_declar
ations_for_private_script | join(', ')}}) | 544 bool {{v8_class}}::PrivateScript::{{method.name}}Method({{method.argument_declar
ations_for_private_script | join(', ')}}) { |
| 555 { | 545 if (!frame) |
| 556 if (!frame) | 546 return false; |
| 557 return false; | 547 v8::HandleScope handleScope(toIsolate(frame)); |
| 558 v8::HandleScope handleScope(toIsolate(frame)); | 548 ScriptForbiddenScope::AllowUserAgentScript script; |
| 559 ScriptForbiddenScope::AllowUserAgentScript script; | 549 ScriptState* scriptState = ScriptState::forWorld(frame, DOMWrapperWorld::priva
teScriptIsolatedWorld()); |
| 560 ScriptState* scriptState = ScriptState::forWorld(frame, DOMWrapperWorld::pri
vateScriptIsolatedWorld()); | 550 if (!scriptState) |
| 561 if (!scriptState) | 551 return false; |
| 562 return false; | 552 ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame); |
| 563 ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame); | 553 if (!scriptStateInUserScript) |
| 564 if (!scriptStateInUserScript) | 554 return false; |
| 565 return false; | 555 |
| 566 | 556 ScriptState::Scope scope(scriptState); |
| 567 ScriptState::Scope scope(scriptState); | 557 v8::Local<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(
), scriptState->isolate()); |
| 568 v8::Local<v8::Value> holder = toV8(holderImpl, scriptState->context()->Globa
l(), scriptState->isolate()); | 558 {% for argument in method.arguments %} |
| 569 {% for argument in method.arguments %} | 559 v8::Local<v8::Value> {{argument.handle}} = {{argument.private_script_cpp_value
_to_v8_value}}; |
| 570 v8::Local<v8::Value> {{argument.handle}} = {{argument.private_script_cpp_val
ue_to_v8_value}}; | 560 {% endfor %} |
| 571 {% endfor %} | 561 {% if method.arguments %} |
| 572 {% if method.arguments %} | 562 v8::Local<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} }; |
| 573 v8::Local<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}}
}; | 563 {% else %} |
| 574 {% else %} | 564 {# Empty array initializers are illegal, and don\t compile in MSVC. #} |
| 575 {# Empty array initializers are illegal, and don\t compile in MSVC. #} | 565 v8::Local<v8::Value> *argv = 0; |
| 576 v8::Local<v8::Value> *argv = 0; | 566 {% endif %} |
| 577 {% endif %} | 567 ExceptionState exceptionState(scriptState->isolate(), ExceptionState::Executio
nContext, "{{cpp_class}}", "{{method.name}}"); |
| 578 ExceptionState exceptionState(scriptState->isolate(), ExceptionState::Execut
ionContext, "{{cpp_class}}", "{{method.name}}"); | 568 v8::Local<v8::Value> v8Value = PrivateScriptRunner::runDOMMethod(scriptState,
scriptStateInUserScript, "{{cpp_class}}", "{{method.name}}", holder, {{method.ar
guments | length}}, argv); |
| 579 v8::Local<v8::Value> v8Value = PrivateScriptRunner::runDOMMethod(scriptState
, scriptStateInUserScript, "{{cpp_class}}", "{{method.name}}", holder, {{method.
arguments | length}}, argv); | 569 if (v8Value.IsEmpty()) |
| 580 if (v8Value.IsEmpty()) | 570 return false; |
| 581 return false; | 571 {% if method.idl_type != 'void' %} |
| 582 {% if method.idl_type != 'void' %} | 572 {{v8_value_to_local_cpp_value(method.private_script_v8_value_to_local_cpp_valu
e) | indent(2)}} |
| 583 {{v8_value_to_local_cpp_value(method.private_script_v8_value_to_local_cpp_va
lue) | indent}} | 573 *result = cppValue; |
| 584 *result = cppValue; | 574 {% endif %} |
| 585 {% endif %} | 575 CHECK(!exceptionState.hadException()); |
| 586 CHECK(!exceptionState.hadException()); | 576 return true; |
| 587 return true; | 577 } |
| 588 } | 578 {% endmacro %} |
| 589 {% endmacro %} | 579 |
| 590 | |
| 591 | 580 |
| 592 {##############################################################################} | 581 {##############################################################################} |
| 593 {% macro generate_constructor(constructor) %} | 582 {% macro generate_constructor(constructor) %} |
| 594 {% set name = '%sConstructorCallback' % v8_class | 583 {% set name = '%sConstructorCallback' % v8_class |
| 595 if constructor.is_named_constructor else | 584 if constructor.is_named_constructor else |
| 596 'constructor%s' % (constructor.overload_index or '') %} | 585 'constructor%s' % (constructor.overload_index or '') %} |
| 597 static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info) | 586 static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 598 { | 587 {% set function_call = func_call_with_prep_of_args(constructor) %} |
| 599 {% set function_call = func_call_with_prep_of_args(constructor) %} | |
| 600 | 588 |
| 601 {% if constructor.is_named_constructor %} | 589 {% if constructor.is_named_constructor %} |
| 602 if (!info.IsConstructCall()) { | 590 if (!info.IsConstructCall()) { |
| 603 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::c
onstructorNotCallableAsFunction("{{constructor.name}}")); | 591 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::const
ructorNotCallableAsFunction("{{constructor.name}}")); |
| 604 return; | 592 return; |
| 605 } | 593 } |
| 606 | 594 |
| 607 if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExis
tingObject) { | 595 if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExisti
ngObject) { |
| 608 v8SetReturnValue(info, info.Holder()); | 596 v8SetReturnValue(info, info.Holder()); |
| 609 return; | 597 return; |
| 610 } | 598 } |
| 611 {% endif %} | 599 {% endif %} |
| 612 | 600 |
| 613 {% if 'exceptionState' in function_call %} | 601 {% if 'exceptionState' in function_call %} |
| 614 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::Constructio
nContext, "{{interface_name}}"); | 602 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::ConstructionC
ontext, "{{interface_name}}"); |
| 615 {% endif %} | 603 {% endif %} |
| 616 {% if 'scriptState' in function_call %} | 604 {% if 'scriptState' in function_call %} |
| 617 ScriptState* scriptState = ScriptState::forReceiverObject(info); | 605 ScriptState* scriptState = ScriptState::forReceiverObject(info); |
| 618 {% endif %} | 606 {% endif %} |
| 619 | 607 |
| 620 {{function_call | indent}} | 608 {{function_call | indent(2)}} |
| 621 } | 609 } |
| 622 {% endmacro %} | 610 {% endmacro %} |
| 623 | 611 |
| 624 | 612 |
| 625 {##############################################################################} | 613 {##############################################################################} |
| 626 {% macro generate_constructor_wrapper(constructor) %} | 614 {% macro generate_constructor_wrapper(constructor) %} |
| 627 {% set constructor_class = v8_class + ('Constructor' | 615 {% set constructor_class = v8_class + ('Constructor' |
| 628 if constructor.is_named_constructor else | 616 if constructor.is_named_constructor else |
| 629 '') %} | 617 '') %} |
| 630 v8::Local<v8::Object> wrapper = info.Holder(); | 618 v8::Local<v8::Object> wrapper = info.Holder(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 655 V8DOMConfiguration::installMethod(isolate, world, {{instance_template}}, {{proto
type_template}}, {{interface_template}}, {{signature}}, {{method.name}}MethodCon
figuration); | 643 V8DOMConfiguration::installMethod(isolate, world, {{instance_template}}, {{proto
type_template}}, {{interface_template}}, {{signature}}, {{method.name}}MethodCon
figuration); |
| 656 {%- endmacro %} | 644 {%- endmacro %} |
| 657 | 645 |
| 658 | 646 |
| 659 {######################################} | 647 {######################################} |
| 660 {% macro install_conditionally_enabled_methods() %} | 648 {% macro install_conditionally_enabled_methods() %} |
| 661 {% if methods | conditionally_exposed(is_partial) %} | 649 {% if methods | conditionally_exposed(is_partial) %} |
| 662 {# Define operations with limited exposure #} | 650 {# Define operations with limited exposure #} |
| 663 v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTempla
te); | 651 v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTempla
te); |
| 664 ExecutionContext* executionContext = toExecutionContext(prototypeObject->Creatio
nContext()); | 652 ExecutionContext* executionContext = toExecutionContext(prototypeObject->Creatio
nContext()); |
| 665 ASSERT(executionContext); | 653 DCHECK(executionContext); |
| 666 {% for method in methods | conditionally_exposed(is_partial) %} | 654 {% for method in methods | conditionally_exposed(is_partial) %} |
| 667 {% filter secure_context(method.overloads.secure_context_test_all | 655 {% filter secure_context(method.overloads.secure_context_test_all |
| 668 if method.overloads else | 656 if method.overloads else |
| 669 method.secure_context_test) %} | 657 method.secure_context_test) %} |
| 670 {% filter exposed(method.overloads.exposed_test_all | 658 {% filter exposed(method.overloads.exposed_test_all |
| 671 if method.overloads else | 659 if method.overloads else |
| 672 method.exposed_test) %} | 660 method.exposed_test) %} |
| 673 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all | 661 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all |
| 674 if method.overloads else | 662 if method.overloads else |
| 675 method.runtime_enabled_function) %} | 663 method.runtime_enabled_function) %} |
| 676 const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration
= {{method_configuration(method)}}; | 664 const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration
= {{method_configuration(method)}}; |
| 677 V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), proto
typeObject, interfaceObject, signature, {{method.name}}MethodConfiguration); | 665 V8DOMConfiguration::installMethod(isolate, world, v8::Local<v8::Object>(), proto
typeObject, interfaceObject, signature, {{method.name}}MethodConfiguration); |
| 678 {% endfilter %}{# runtime_enabled() #} | 666 {% endfilter %}{# runtime_enabled() #} |
| 679 {% endfilter %}{# exposed() #} | 667 {% endfilter %}{# exposed() #} |
| 680 {% endfilter %}{# secure_context() #} | 668 {% endfilter %}{# secure_context() #} |
| 681 {% endfor %} | 669 {% endfor %} |
| 682 {% endif %} | 670 {% endif %} |
| 683 {%- endmacro %} | 671 {%- endmacro %} |
| OLD | NEW |