1 {##############################################################################}
2 {% macro generate_method(method, world_suffix) %}
3 {% filter conditional(method.conditional_string) %}
4 static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
7 {% if method.has_exception_state %}
8 ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
10 {# Overloaded methods have length checked during overload resolution #}
11 {% if method.number_of_required_arguments and not method.overload_index %}
12 if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
13 {{throw_minimum_arity_type_error(method, method.number_of_required_arguments) | indent(8)}}
17 {% if not method.is_static %}
18 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
20 {% if method.is_custom_element_callbacks %}
21 CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
24 {% if method.is_check_security_for_window %}
25 if (LocalDOMWindow* window = impl->toDOMWindow()) {
26 if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) {
27 {{throw_from_exception_state(method)}};
30 if (!window->document())
33 {% elif method.is_check_security_for_frame %}
34 if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
35 {{throw_from_exception_state(method)}};
39 {% if method.is_check_security_for_node %}
40 if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) {
41 v8SetReturnValueNull(info);
42 {{throw_from_exception_state(method)}};
47 {% if method.arguments %}
48 {{generate_arguments(method, world_suffix) | indent}}
51 {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_value) | indent}}
53 {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
60 {######################################}
61 {% macro generate_arguments(method, world_suffix) %}
62 {% for argument in method.arguments %}
63 {{generate_argument_var_declaration(argument)}};
66 {% for argument in method.arguments %}
67 {% if argument.default_value %}
68 if (!info[{{argument.index}}]->IsUndefined()) {
69 {{generate_argument(method, argument, world_suffix) | indent(8)}}
71 {{argument.name}} = {{argument.default_value}};
74 {{generate_argument(method, argument, world_suffix) | indent}}
81 {######################################}
82 {% macro generate_argument_var_declaration(argument) %}
83 {# FIXME: remove EventListener special case #}
84 {% if argument.idl_type == 'EventListener' %}
85 RefPtr<{{argument.idl_type}}> {{argument.name}}
87 {{argument.cpp_type}} {{argument.name}}
88 {%- endif %}{# argument.idl_type == 'EventListener' #}
92 {######################################}
93 {% macro generate_argument(method, argument, world_suffix) %}
94 {% if argument.is_optional and not argument.has_default and
95 not argument.is_dictionary and
96 not argument.is_callback_interface %}
97 {# Optional arguments without a default value generate an early call with
98 fewer arguments if they are omitted.
99 Optional Dictionary arguments default to empty dictionary. #}
100 if (UNLIKELY(info.Length() <= {{argument.index}})) {
101 {% if world_suffix %}
102 {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | indent}}
104 {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent}}
106 {% if argument.has_event_listener_argument %}
107 {{hidden_dependency_action(method.name) | indent}}
112 {% if argument.has_type_checking_interface and not argument.is_variadic_wrapper_type %}
113 {# Type checking for wrapper interface types (if interface not implemented,
114 throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface
115 Note: for variadic arguments, the type checking is done for each matched
116 argument instead; see argument.is_variadic_wrapper_type code-path below. #}
117 if (info.Length() > {{argument.index}} && {% if argument.is_nullable %}!isUndefinedOrNull(info[{{argument.index}}]) && {% endif %}!V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate())) {
118 {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
119 (argument.index + 1, argument.idl_type)) | indent}}
122 {% endif %}{# argument.has_type_checking_interface #}
123 {% if argument.is_callback_interface %}
124 {# FIXME: remove EventListener special case #}
125 {% if argument.idl_type == 'EventListener' %}
126 {% if method.name == 'removeEventListener' or method.name == 'removeListener' %}
127 {{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOnly);
128 {% else %}{# method.name == 'addEventListener' #}
129 {{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOrCreate);
130 {% endif %}{# method.name #}
131 {% else %}{# argument.idl_type == 'EventListener' #}
132 {# Callback functions must be functions:
133 http://www.w3.org/TR/WebIDL/#es-callback-function #}
134 {% if argument.is_optional %}
135 if (!isUndefinedOrNull(info[{{argument.index}}])) {
136 if (!info[{{argument.index}}]->IsFunction()) {
137 {{throw_type_error(method,
138 '"The callback provided as parameter %s is not a function."' %
139 (argument.index + 1)) | indent(8)}}
142 {{argument.name}} = V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
144 {{argument.name}} = nullptr;
146 {% else %}{# argument.is_optional #}
147 if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %}info[{{argument.index}}]->IsFunction(){% endif %}) {
148 {{throw_type_error(method,
149 '"The callback provided as parameter %s is not a function."' %
150 (argument.index + 1)) | indent }}
153 {{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNull() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
154 {% endif %}{# argument.is_optional #}
155 {% endif %}{# argument.idl_type == 'EventListener' #}
156 {% elif argument.is_variadic_wrapper_type %}
157 for (int i = {{argument.index}}; i < info.Length(); ++i) {
158 if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) {
159 {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
160 (argument.index + 1, argument.idl_type)) | indent(8)}}
163 {{argument.name}}.append(V8{{argument.idl_type}}::toImpl(v8::Handle<v8::Object>::Cast(info[i])));
165 {% elif argument.is_dictionary %}
166 {# Dictionaries must have type Undefined, Null or Object:
167 http://heycam.github.io/webidl/#es-dictionary #}
168 if (!isUndefinedOrNull(info[{{argument.index}}]) && !info[{{argument.index}}]->IsObject()) {
169 {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
170 (argument.index + 1, argument.name)) | indent}}
173 {{argument.v8_value_to_local_cpp_value}};
174 {% else %}{# argument.is_nullable #}
175 {{argument.v8_value_to_local_cpp_value}};
176 {% endif %}{# argument.is_nullable #}
177 {# Type checking, possibly throw a TypeError, per:
178 http://www.w3.org/TR/WebIDL/#es-type-mapping #}
179 {% if argument.has_type_checking_unrestricted %}
180 {# Non-finite floating point values (NaN, +Infinity or −Infinity), per:
181 http://heycam.github.io/webidl/#es-float
182 http://heycam.github.io/webidl/#es-double #}
183 if (!std::isfinite({{argument.name}})) {
184 {{throw_type_error(method, '"%s parameter %s is non-finite."' %
185 (argument.idl_type, argument.index + 1)) | indent}}
188 {% elif argument.enum_validation_expression %}
189 {# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
190 String string = {{argument.name}};
191 if (!({{argument.enum_validation_expression}})) {
192 {{throw_type_error(method,
193 '"parameter %s (\'" + string + "\') is not a valid enum value."' %
194 (argument.index + 1)) | indent}}
197 {% elif argument.idl_type == 'Promise' %}
198 {# We require this for our implementation of promises, though not in spec:
199 http://heycam.github.io/webidl/#es-promise #}
200 if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
201 {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
202 (argument.index + 1, argument.name)) | indent}}
209 {######################################}
210 {% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
211 {# Local variables #}
212 {% if method.is_call_with_script_state %}
213 {# [CallWith=ScriptState] #}
214 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
216 {% if method.is_call_with_execution_context %}
217 {# [ConstructorCallWith=ExecutionContext] #}
218 {# [CallWith=ExecutionContext] #}
219 ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
221 {% if method.is_call_with_script_arguments %}
222 {# [CallWith=ScriptArguments] #}
223 RefPtrWillBeRawPtr<ScriptArguments> scriptArguments(createScriptArguments(scriptState, info, {{method.number_of_arguments}}));
225 {% if method.is_call_with_document %}
226 {# [ConstructorCallWith=Document] #}
227 Document& document = *toDocument(currentExecutionContext(info.GetIsolate()));
230 {% if method.idl_type == 'void' %}
232 {% elif method.is_implemented_in_private_script %}
233 {{method.cpp_type}} result{{method.cpp_type_initializer}};
234 if (!{{method.cpp_value}})
236 {% elif method.use_output_parameter_for_result %}
237 {{method.cpp_type}} result;
239 {% elif method.is_constructor %}
240 {{method.cpp_type}} impl = {{cpp_value}};
241 {% elif method.use_local_result %}
242 {{method.cpp_type}} result = {{cpp_value}};
245 {% if method.is_raises_exception %}
246 if (exceptionState.hadException()) {
247 {{throw_from_exception_state(method)}};
251 {# Set return value #}
252 {% if method.is_constructor %}
253 {{generate_constructor_wrapper(method)}}
254 {%- elif v8_set_return_value %}
255 {% if method.is_explicit_nullable %}
257 v8SetReturnValueNull(info);
259 {{v8_set_return_value}};
261 {{v8_set_return_value}};
263 {%- endif %}{# None for void #}
265 {% if interface_name in ('EventTarget', 'MediaQueryList')
266 and method.name in ('addEventListener', 'removeEventListener', 'addListener', 'removeListener') %}
267 {% set hidden_dependency_action = 'addHiddenValueToArray'
268 if method.name in ('addEventListener', 'addListener') else 'removeHiddenValueFromArray' %}
269 {% set argument_index = '1' if interface_name == 'EventTarget' else '0' %}
270 {# Length check needed to skip action on legacy calls without enough arguments.
271 http://crbug.com/353484 #}
272 if (info.Length() >= {{argument_index}} + 1 && listener && !impl->toNode())
273 {{hidden_dependency_action}}(info.GetIsolate(), info.Holder(), info[{{argument_index}}], {{v8_class}}::eventListenerCacheIndex);
278 {######################################}
279 {% macro throw_type_error(method, error_message) %}
280 {% if method.has_exception_state %}
281 exceptionState.throwTypeError({{error_message}});
282 {{throw_from_exception_state(method)}};
283 {% elif method.idl_type == 'Promise' %}
284 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), V8ThrowException::createTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}})));
286 V8ThrowException::throwTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}});
287 {% endif %}{# method.has_exception_state #}
291 {######################################}
292 {% macro type_error_message(method, error_message) %}
293 {% if method.is_constructor %}
294 ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}})
296 ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}})
301 {######################################}
302 {% macro throw_from_exception_state(method_or_overloads) %}
303 {% if method_or_overloads.idl_type == 'Promise' or method_or_overloads.returns_promise_all %}
304 v8SetReturnValue(info, exceptionState.reject(ScriptState::current(info.GetIsolate())).v8Value())
306 exceptionState.throwIfNeeded()
311 {######################################}
312 {% macro throw_minimum_arity_type_error(method, number_of_required_arguments) %}
313 {% if method.has_exception_state %}
314 setMinimumArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length());
315 {{throw_from_exception_state(method)}};
316 {%- elif method.idl_type == 'Promise' %}
317 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), {{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}));
319 V8ThrowException::throwException({{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}, info.GetIsolate());
324 {######################################}
325 {% macro create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments) %}
326 {% if method.is_constructor %}
327 createMinimumArityTypeErrorForConstructor(info.GetIsolate(), "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
329 createMinimumArityTypeErrorForMethod(info.GetIsolate(), "{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
334 {##############################################################################}
335 {# FIXME: We should return a rejected Promise if an error occurs in this
336 function when ALL methods in this overload return Promise. In order to do so,
337 we must ensure either ALL or NO methods in this overload return Promise #}
338 {% macro overload_resolution_method(overloads, world_suffix) %}
339 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
341 ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
342 {% if overloads.measure_all_as %}
343 UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}});
345 {% if overloads.deprecate_all_as %}
346 UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}});
348 {# First resolve by length #}
349 {# 2. Initialize argcount to be min(maxarg, n). #}
350 switch (std::min({{overloads.maxarg}}, info.Length())) {
351 {# 3. Remove from S all entries whose type list is not of length argcount. #}
352 {% for length, tests_methods in overloads.length_tests_methods %}
353 {# 10. If i = d, then: #}
355 {# Then resolve by testing argument #}
356 {% for test, method in tests_methods %}
357 {% if method.visible %}
358 {% filter runtime_enabled(not overloads.runtime_enabled_function_all and
359 method.runtime_enabled_function) %}
361 {% if method.measure_as and not overloads.measure_all_as %}
362 UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
364 {% if method.deprecate_as and not overloads.deprecate_all_as %}
365 UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
367 {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
375 {% if is_partial or not overloads.has_partial_overloads %}
377 {# If methods are overloaded between interface and partial interface #}
378 {# definitions, need to invoke methods defined in the partial #}
380 {# FIXME: we do not need to always generate this code. #}
381 {# Invalid arity, throw error #}
382 {# Report full list of valid arities if gaps and above minimum #}
383 {% if overloads.valid_arities %}
384 if (info.Length() >= {{overloads.minarg}}) {
385 setArityTypeError(exceptionState, "{{overloads.valid_arities}}", info.Length());
386 {{throw_from_exception_state(overloads)}};
390 {# Otherwise just report "not enough arguments" #}
391 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.minarg}}, info.Length()));
392 {{throw_from_exception_state(overloads)}};
396 {% if not is_partial and overloads.has_partial_overloads %}
397 ASSERT({{overloads.name}}MethodForPartialInterface);
398 ({{overloads.name}}MethodForPartialInterface)(info);
400 {# No match, throw error #}
401 exceptionState.throwTypeError("No function was found that matched the signature provided.");
402 {{throw_from_exception_state(overloads)}};
408 {##############################################################################}
409 {% macro method_callback(method, world_suffix) %}
410 {% filter conditional(method.conditional_string) %}
411 static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
413 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMMethod");
414 {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
415 {% if method.measure_as %}
416 UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
418 {% if method.deprecate_as %}
419 UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
421 {% endif %}{# not method.overloads #}
422 {% if world_suffix in method.activity_logging_world_list %}
423 ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
424 V8PerContextData* contextData = scriptState->perContextData();
425 {% if method.activity_logging_world_check %}
426 if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
428 if (contextData && contextData->activityLogger()) {
430 ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
431 Vector<v8::Handle<v8::Value> > loggerArgs = toImplArguments<v8::Handle<v8::Value> >(info, 0, exceptionState);
432 contextData->activityLogger()->logMethod("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data());
435 {% if method.is_custom %}
436 {{v8_class}}::{{method.name}}MethodCustom(info);
438 {{cpp_class_or_partial}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
440 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
446 {##############################################################################}
447 {% macro origin_safe_method_getter(method, world_suffix) %}
448 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info)
450 {% set signature = 'v8::Local<v8::Signature>()'
451 if method.is_do_not_check_signature else
452 'v8::Signature::New(info.GetIsolate(), %s::domTemplate(info.GetIsolate()))' % v8_class %}
453 static int domTemplateKey; // This address is used for a key to look up the dom template.
454 V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate());
455 {# FIXME: 1 case of [DoNotCheckSignature] in Window.idl may differ #}
456 v8::Handle<v8::FunctionTemplate> privateTemplate = data->domTemplate(&domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
458 v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
459 if (holder.IsEmpty()) {
460 // This is only reachable via |object.__proto__.func|, in which case it
461 // has already passed the same origin security check
462 v8SetReturnValue(info, privateTemplate->GetFunction());
465 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
466 if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), DoNotReportSecurityError)) {
467 static int sharedTemplateKey; // This address is used for a key to look up the dom template.
468 v8::Handle<v8::FunctionTemplate> sharedTemplate = data->domTemplate(&sharedTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
469 v8SetReturnValue(info, sharedTemplate->GetFunction());
473 {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
474 v8::Local<v8::Value> hiddenValue = v8::Handle<v8::Object>::Cast(info.This())->GetHiddenValue(v8AtomicString(info.GetIsolate(), "{{method.name}}"));
475 if (!hiddenValue.IsEmpty()) {
476 v8SetReturnValue(info, hiddenValue);
480 v8SetReturnValue(info, privateTemplate->GetFunction());
483 static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
485 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMGetter");
486 {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}(info);
487 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
492 {##############################################################################}
493 {% macro method_implemented_in_private_script(method) %}
494 bool {{v8_class}}::PrivateScript::{{method.name}}Method({{method.argument_declarations_for_private_script | join(', ')}})
498 v8::HandleScope handleScope(toIsolate(frame));
499 ScriptForbiddenScope::AllowUserAgentScript script;
500 v8::Handle<v8::Context> contextInPrivateScript = toV8Context(frame, DOMWrapperWorld::privateScriptIsolatedWorld());
501 if (contextInPrivateScript.IsEmpty())
503 ScriptState* scriptState = ScriptState::from(contextInPrivateScript);
504 ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame);
505 if (!scriptState->executionContext())
508 ScriptState::Scope scope(scriptState);
509 v8::Handle<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(), scriptState->isolate());
511 {% for argument in method.arguments %}
512 v8::Handle<v8::Value> {{argument.handle}} = {{argument.private_script_cpp_value_to_v8_value}};
514 {% if method.arguments %}
515 v8::Handle<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} };
517 {# Empty array initializers are illegal, and don\t compile in MSVC. #}
518 v8::Handle<v8::Value> *argv = 0;
520 ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{cpp_class}}", scriptState->context()->Global(), scriptState->isolate());
521 v8::Handle<v8::Value> v8Value = PrivateScriptRunner::runDOMMethod(scriptState, scriptStateInUserScript, "{{cpp_class}}", "{{method.name}}", holder, {{method.arguments | length}}, argv);
522 if (v8Value.IsEmpty())
524 {% if method.idl_type != 'void' %}
525 {{method.private_script_v8_value_to_local_cpp_value}};
528 RELEASE_ASSERT(!exceptionState.hadException());
534 {##############################################################################}
535 {% macro generate_constructor(constructor) %}
536 {% set name = '%sConstructorCallback' % v8_class
537 if constructor.is_named_constructor else
538 'constructor%s' % (constructor.overload_index or '') %}
539 static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info)
541 {% if constructor.is_named_constructor %}
542 if (!info.IsConstructCall()) {
543 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::constructorNotCallableAsFunction("{{constructor.name}}"));
547 if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
548 v8SetReturnValue(info, info.Holder());
552 {% if constructor.has_exception_state %}
553 ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
555 {# Overloaded constructors have length checked during overload resolution #}
556 {% if constructor.number_of_required_arguments and not constructor.overload_index %}
557 if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
558 {{throw_minimum_arity_type_error(constructor, constructor.number_of_required_arguments) | indent(8)}}
562 {% if constructor.arguments %}
563 {{generate_arguments(constructor) | indent}}
565 {{cpp_method_call(constructor, constructor.v8_set_return_value, constructor.cpp_value) | indent}}
570 {##############################################################################}
571 {% macro generate_constructor_wrapper(constructor) %}
572 {% if has_custom_wrap %}
573 v8::Handle<v8::Object> wrapper = wrapCustom(impl.get(), info.Holder(), info.GetIsolate());
575 {% set constructor_class = v8_class + ('Constructor'
576 if constructor.is_named_constructor else
578 v8::Handle<v8::Object> wrapper = info.Holder();
579 {% if is_script_wrappable %}
580 impl->associateWithWrapper(&{{constructor_class}}::wrapperTypeInfo, wrapper, info.GetIsolate());
582 V8DOMWrapper::associateObjectWithWrapper(info.GetIsolate(), impl.get(), &{{constructor_class}}::wrapperTypeInfo, wrapper);
585 v8SetReturnValue(info, wrapper);
589 {##############################################################################}
590 {% macro method_configuration(method) %}
591 {% set method_callback =
592 '%sV8Internal::%sMethodCallback' % (cpp_class_or_partial, method.name) %}
593 {% set method_callback_for_main_world =
594 '%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class_or_partial, method.name)
595 if method.is_per_world_bindings else '0' %}
596 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
597 {"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}}}
601 {######################################}
602 {% macro install_custom_signature(method) %}
603 {% set method_callback = '%sV8Internal::%sMethodCallback' % (cpp_class_or_partial, method.name) %}
604 {% set method_callback_for_main_world = '%sForMainWorld' % method_callback
605 if method.is_per_world_bindings else '0' %}
606 {% set property_attribute =
607 'static_cast<v8::PropertyAttribute>(%s)' % ' | '.join(method.property_attributes)
608 if method.property_attributes else 'v8::None' %}
609 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
610 static const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration = {
611 "{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}},
613 V8DOMConfiguration::installMethod({{method.function_template}}, {{method.signature}}, {{property_attribute}}, {{method.name}}MethodConfiguration, isolate);
616 {######################################}
617 {% macro install_conditionally_enabled_methods() %}
618 void {{v8_class_or_partial}}::installConditionallyEnabledMethods(v8::Handle<v8::Object> prototypeObject, v8::Isolate* isolate)
621 {{v8_class}}::installConditionallyEnabledMethods(prototypeObject, isolate);
623 {% if conditionally_enabled_methods %}
624 {# Define per-context enabled operations #}
625 v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate));
626 ExecutionContext* context = toExecutionContext(prototypeObject->CreationContext());
629 {% for method in conditionally_enabled_methods %}
630 {% filter per_context_enabled(method.per_context_enabled_function) %}
631 {% filter exposed(method.exposed_test) %}
632 prototypeObject->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{cpp_class_or_partial}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());