Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / templates / methods.cpp
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)
5 {
6     {# Local variables #}
7     {% if method.has_exception_state %}
8     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
9     {% endif %}
10     {% if method.number_of_required_arguments %}
11     if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
12         {{throw_arity_type_error(method, method.number_of_required_arguments)}};
13         return;
14     }
15     {% endif %}
16     {% if not method.is_static %}
17     {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
18     {% endif %}
19     {% if method.is_custom_element_callbacks %}
20     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
21     {% endif %}
22     {# Security checks #}
23     {# FIXME: change to method.is_check_security_for_window #}
24     {% if interface_name == 'EventTarget' %}
25     if (DOMWindow* window = impl->toDOMWindow()) {
26         if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) {
27             exceptionState.throwIfNeeded();
28             return;
29         }
30         if (!window->document())
31             return;
32     }
33     {% elif method.is_check_security_for_frame %}
34     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
35         exceptionState.throwIfNeeded();
36         return;
37     }
38     {% endif %}
39     {% if method.is_check_security_for_node %}
40     if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) {
41         v8SetReturnValueNull(info);
42         exceptionState.throwIfNeeded();
43         return;
44     }
45     {% endif %}
46     {# Call method #}
47     {% for argument in method.arguments %}
48     {{generate_argument(method, argument, world_suffix) | indent}}
49     {% endfor %}
50     {% if world_suffix %}
51     {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_value) | indent}}
52     {% else %}
53     {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
54     {% endif %}
55     {# Post-call #}
56     {% if method.has_event_listener_argument %}
57     {{hidden_dependency_action(method.name) | indent}}
58     {% endif %}
59 }
60 {% endfilter %}
61 {% endmacro %}
62
63
64 {######################################}
65 {% macro hidden_dependency_action(method_name) %}
66 if (listener && !impl->toNode())
67     {% if method_name == 'addEventListener' %}
68     addHiddenValueToArray(info.Holder(), info[1], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
69     {% else %}{# method_name == 'removeEventListener' #}
70     removeHiddenValueFromArray(info.Holder(), info[1], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
71     {% endif %}
72 {% endmacro %}
73
74
75 {######################################}
76 {% macro generate_argument(method, argument, world_suffix) %}
77 {% if argument.is_optional and not argument.has_default and
78       argument.idl_type != 'Dictionary' and
79       not argument.is_callback_interface %}
80 {# Optional arguments without a default value generate an early call with
81    fewer arguments if they are omitted.
82    Optional Dictionary arguments default to empty dictionary. #}
83 if (UNLIKELY(info.Length() <= {{argument.index}})) {
84     {% if world_suffix %}
85     {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | indent}}
86     {% else %}
87     {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent}}
88     {% endif %}
89     {% if argument.has_event_listener_argument %}
90     {{hidden_dependency_action(method.name) | indent}}
91     {% endif %}
92     return;
93 }
94 {% endif %}
95 {% if argument.has_type_checking_interface %}
96 {# Type checking for wrapper interface types (if interface not implemented,
97    throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
98 if (info.Length() > {{argument.index}} && {% if argument.is_nullable %}!isUndefinedOrNull(info[{{argument.index}}]) && {% endif %}!V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate())) {
99     {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
100                                (argument.index + 1, argument.idl_type)) | indent}}
101     return;
102 }
103 {% endif %}
104 {% if argument.is_callback_interface %}
105 {# FIXME: remove EventListener special case #}
106 {% if argument.idl_type == 'EventListener' %}
107 {% if method.name == 'removeEventListener' %}
108 RefPtr<{{argument.idl_type}}> {{argument.name}} = V8EventListenerList::getEventListener(info[1], false, ListenerFindOnly);
109 {% else %}{# method.name == 'addEventListener' #}
110 RefPtr<{{argument.idl_type}}> {{argument.name}} = V8EventListenerList::getEventListener(info[1], false, ListenerFindOrCreate);
111 {% endif %}{# method.name #}
112 {% else %}
113 {# Callback functions must be functions:
114    http://www.w3.org/TR/WebIDL/#es-callback-function #}
115 {% if argument.is_optional %}
116 OwnPtr<{{argument.idl_type}}> {{argument.name}};
117 if (info.Length() > {{argument.index}} && !isUndefinedOrNull(info[{{argument.index}}])) {
118     if (!info[{{argument.index}}]->IsFunction()) {
119         {{throw_type_error(method,
120               '"The callback provided as parameter %s is not a function."' %
121                   (argument.index + 1)) | indent(8)}}
122         return;
123     }
124     {{argument.name}} = V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), currentExecutionContext(info.GetIsolate()));
125 }
126 {% else %}
127 if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %}info[{{argument.index}}]->IsFunction(){% endif %}) {
128     {{throw_type_error(method,
129           '"The callback provided as parameter %s is not a function."' %
130               (argument.index + 1)) | indent }}
131     return;
132 }
133 OwnPtr<{{argument.idl_type}}> {{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}}]), currentExecutionContext(info.GetIsolate()));
134 {% endif %}{# argument.is_optional #}
135 {% endif %}{# argument.idl_type == 'EventListener' #}
136 {% elif argument.is_clamp %}{# argument.is_callback_interface #}
137 {# NaN is treated as 0: http://www.w3.org/TR/WebIDL/#es-type-mapping #}
138 {{argument.cpp_type}} {{argument.name}} = 0;
139 TONATIVE_VOID(double, {{argument.name}}NativeValue, info[{{argument.index}}]->NumberValue());
140 if (!std::isnan({{argument.name}}NativeValue))
141     {# IDL type is used for clamping, for the right bounds, since different
142        IDL integer types have same internal C++ type (int or unsigned) #}
143     {{argument.name}} = clampTo<{{argument.idl_type}}>({{argument.name}}NativeValue);
144 {% elif argument.idl_type == 'SerializedScriptValue' %}
145 {{argument.cpp_type}} {{argument.name}} = SerializedScriptValue::create(info[{{argument.index}}], 0, 0, exceptionState, info.GetIsolate());
146 if (exceptionState.throwIfNeeded())
147     return;
148 {% elif argument.is_variadic_wrapper_type %}
149 {{argument.vector_type}}<{{argument.cpp_type}} > {{argument.name}};
150 for (int i = {{argument.index}}; i < info.Length(); ++i) {
151     if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) {
152         {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
153                                    (argument.index + 1, argument.idl_type)) | indent(8)}}
154         return;
155     }
156     {{argument.name}}.append(V8{{argument.idl_type}}::toNative(v8::Handle<v8::Object>::Cast(info[i])));
157 }
158 {% else %}
159 {{argument.v8_value_to_local_cpp_value}};
160 {% endif %}
161 {# Type checking, possibly throw a TypeError, per:
162    http://www.w3.org/TR/WebIDL/#es-type-mapping #}
163 {% if argument.has_type_checking_unrestricted %}
164 {# Non-finite floating point values (NaN, +Infinity or âˆ’Infinity), per:
165    http://heycam.github.io/webidl/#es-float
166    http://heycam.github.io/webidl/#es-double #}
167 if (!std::isfinite({{argument.name}})) {
168     {{throw_type_error(method, '"%s parameter %s is non-finite."' %
169                                (argument.idl_type, argument.index + 1)) | indent}}
170     return;
171 }
172 {% elif argument.enum_validation_expression %}
173 {# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
174 String string = {{argument.name}};
175 if (!({{argument.enum_validation_expression}})) {
176     {{throw_type_error(method,
177           '"parameter %s (\'" + string + "\') is not a valid enum value."' %
178               (argument.index + 1)) | indent}}
179     return;
180 }
181 {% elif argument.idl_type in ['Dictionary', 'Promise'] %}
182 {# Dictionaries must have type Undefined, Null or Object:
183 http://heycam.github.io/webidl/#es-dictionary
184 We also require this for our implementation of promises, though not in spec:
185 http://heycam.github.io/webidl/#es-promise #}
186 if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
187     {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
188                                (argument.index + 1, argument.name)) | indent}}
189     return;
190 }
191 {% endif %}
192 {% endmacro %}
193
194
195 {######################################}
196 {% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
197 {# Local variables #}
198 {% if method.is_partial_interface_member and not method.is_static %}
199 {# instance members (non-static members) in partial interface take |impl| #}
200 ASSERT(impl);
201 {% endif %}
202 {% if method.is_call_with_script_state %}
203 ScriptState* state = ScriptState::current(info.GetIsolate());
204 {% endif %}
205 {% if method.is_call_with_execution_context %}
206 ExecutionContext* scriptContext = currentExecutionContext(info.GetIsolate());
207 {% endif %}
208 {% if method.is_call_with_script_arguments %}
209 RefPtr<ScriptArguments> scriptArguments(createScriptArguments(info, {{method.number_of_arguments}}));
210 {% endif %}
211 {# Call #}
212 {% if method.idl_type == 'void' %}
213 {{cpp_value}};
214 {% elif method.is_constructor %}
215 {{method.cpp_type}} impl = {{cpp_value}};
216 {% elif method.is_call_with_script_state or method.is_raises_exception %}
217 {# FIXME: consider always using a local variable #}
218 {{method.cpp_type}} result = {{cpp_value}};
219 {% endif %}
220 {# Post-call #}
221 {% if method.is_raises_exception %}
222 if (exceptionState.throwIfNeeded())
223     return;
224 {% endif %}
225 {# Set return value #}
226 {% if method.is_constructor %}
227 {{generate_constructor_wrapper(method)}}{% elif method.union_arguments %}
228 {{union_type_method_call_and_set_return_value(method)}}
229 {% elif v8_set_return_value %}{{v8_set_return_value}};{% endif %}{# None for void #}
230 {% endmacro %}
231
232
233 {######################################}
234 {% macro union_type_method_call_and_set_return_value(method) %}
235 {% for cpp_type in method.cpp_type %}
236 bool result{{loop.index0}}Enabled = false;
237 {{cpp_type}} result{{loop.index0}};
238 {% endfor %}
239 {{method.cpp_value}};
240 {% if method.is_null_expression %}{# used by getters #}
241 if ({{method.is_null_expression}})
242     return;
243 {% endif %}
244 {% for v8_set_return_value in method.v8_set_return_value %}
245 if (result{{loop.index0}}Enabled) {
246     {{v8_set_return_value}};
247     return;
248 }
249 {% endfor %}
250 {# Fall back to null if none of the union members results are returned #}
251 v8SetReturnValueNull(info);
252 {%- endmacro %}
253
254
255 {######################################}
256 {% macro throw_type_error(method, error_message) %}
257 {% if method.has_exception_state %}
258 exceptionState.throwTypeError({{error_message}});
259 exceptionState.throwIfNeeded();
260 {%- elif method.is_constructor %}
261 throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}}), info.GetIsolate());
262 {%- else %}
263 throwTypeError(ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}}), info.GetIsolate());
264 {%- endif %}
265 {% endmacro %}
266
267
268 {######################################}
269 {% macro throw_arity_type_error(method, number_of_required_arguments) %}
270 {% if method.has_exception_state %}
271 throwArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length())
272 {%- elif method.is_constructor %}
273 throwArityTypeErrorForConstructor("{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
274 {%- else %}
275 throwArityTypeErrorForMethod("{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
276 {%- endif %}
277 {% endmacro %}
278
279
280 {##############################################################################}
281 {% macro overload_resolution_method(overloads, world_suffix) %}
282 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
283 {
284     {% if overloads.measure_all_as %}
285     UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}});
286     {% endif %}
287     {% if overloads.deprecate_all_as %}
288     UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}});
289     {% endif %}
290     {% for method in overloads.methods %}
291     if ({{method.overload_resolution_expression}}) {
292         {% if method.measure_as and not overloads.measure_all_as %}
293         UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
294         {% endif %}
295         {% if method.deprecate_as and not overloads.deprecate_all_as %}
296         UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
297         {% endif %}
298         {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
299         return;
300     }
301     {% endfor %}
302     {% if overloads.minimum_number_of_required_arguments %}
303     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
304     if (UNLIKELY(info.Length() < {{overloads.minimum_number_of_required_arguments}})) {
305         {{throw_arity_type_error(overloads, overloads.minimum_number_of_required_arguments)}};
306         return;
307     }
308     {% endif %}
309     {{throw_type_error(overloads, '"No function was found that matched the signature provided."') | indent}}
310 }
311 {% endmacro %}
312
313
314 {##############################################################################}
315 {% macro method_callback(method, world_suffix) %}
316 {% filter conditional(method.conditional_string) %}
317 static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
318 {
319     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMMethod");
320     {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
321     {% if method.measure_as %}
322     UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
323     {% endif %}
324     {% if method.deprecate_as %}
325     UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
326     {% endif %}
327     {% endif %}{# not method.overloads #}
328     {% if world_suffix in method.activity_logging_world_list %}
329     DOMWrapperWorld& world = DOMWrapperWorld::current(info.GetIsolate());
330     if (world.activityLogger()) {
331         {# FIXME: replace toVectorOfArguments with toNativeArguments(info, 0)
332            and delete toVectorOfArguments #}
333         Vector<v8::Handle<v8::Value> > loggerArgs = toNativeArguments<v8::Handle<v8::Value> >(info, 0);
334         world.activityLogger()->logMethod("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data());
335     }
336     {% endif %}
337     {% if method.is_custom %}
338     {{v8_class}}::{{method.name}}MethodCustom(info);
339     {% else %}
340     {{cpp_class}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
341     {% endif %}
342     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
343 }
344 {% endfilter %}
345 {% endmacro %}
346
347
348 {##############################################################################}
349 {% macro origin_safe_method_getter(method, world_suffix) %}
350 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info)
351 {
352     {% set signature = 'v8::Local<v8::Signature>()'
353                        if method.is_do_not_check_signature else
354                        'v8::Signature::New(info.GetIsolate(), %s::domTemplate(info.GetIsolate()))' % v8_class %}
355     v8::Isolate* isolate = info.GetIsolate();
356     static int domTemplateKey; // This address is used for a key to look up the dom template.
357     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
358     {# FIXME: 1 case of [DoNotCheckSignature] in Window.idl may differ #}
359     v8::Handle<v8::FunctionTemplate> privateTemplate = data->domTemplate(&domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.number_of_required_or_variadic_arguments}});
360
361     v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), isolate);
362     if (holder.IsEmpty()) {
363         // This is only reachable via |object.__proto__.func|, in which case it
364         // has already passed the same origin security check
365         v8SetReturnValue(info, privateTemplate->GetFunction());
366         return;
367     }
368     {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
369     if (!BindingSecurity::shouldAllowAccessToFrame(isolate, impl->frame(), DoNotReportSecurityError)) {
370         static int sharedTemplateKey; // This address is used for a key to look up the dom template.
371         v8::Handle<v8::FunctionTemplate> sharedTemplate = data->domTemplate(&sharedTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.number_of_required_or_variadic_arguments}});
372         v8SetReturnValue(info, sharedTemplate->GetFunction());
373         return;
374     }
375
376     {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
377     v8::Local<v8::Value> hiddenValue = v8::Handle<v8::Object>::Cast(info.This())->GetHiddenValue(v8AtomicString(isolate, "{{method.name}}"));
378     if (!hiddenValue.IsEmpty()) {
379         v8SetReturnValue(info, hiddenValue);
380         return;
381     }
382
383     v8SetReturnValue(info, privateTemplate->GetFunction());
384 }
385
386 static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
387 {
388     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
389     {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}(info);
390     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
391 }
392 {% endmacro %}
393
394
395 {##############################################################################}
396 {% macro generate_constructor(constructor) %}
397 static void constructor{{constructor.overload_index}}(const v8::FunctionCallbackInfo<v8::Value>& info)
398 {
399     v8::Isolate* isolate = info.GetIsolate();
400     {% if constructor.has_exception_state %}
401     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
402     {% endif %}
403     {% if interface_length and not constructor.overload_index %}
404     {# FIXME: remove UNLIKELY: constructors are expensive, so no difference. #}
405     if (UNLIKELY(info.Length() < {{interface_length}})) {
406         {{throw_arity_type_error(constructor, interface_length)}};
407         return;
408     }
409     {% endif %}
410     {% for argument in constructor.arguments %}
411     {{generate_argument(constructor, argument) | indent}}
412     {% endfor %}
413     {% if is_constructor_call_with_execution_context %}
414     ExecutionContext* context = currentExecutionContext(isolate);
415     {% endif %}
416     {% if is_constructor_call_with_document %}
417     Document& document = *toDocument(currentExecutionContext(isolate));
418     {% endif %}
419     {{constructor.cpp_type}} impl = {{cpp_class}}::create({{constructor.argument_list | join(', ')}});
420     {% if is_constructor_raises_exception %}
421     if (exceptionState.throwIfNeeded())
422         return;
423     {% endif %}
424
425     {{generate_constructor_wrapper(constructor) | indent}}
426 }
427 {% endmacro %}
428
429
430 {##############################################################################}
431 {% macro generate_constructor_wrapper(constructor) %}
432 {% if has_custom_wrap %}
433 v8::Handle<v8::Object> wrapper = wrap(impl.get(), info.Holder(), isolate);
434 {% else %}
435 {% set constructor_class = v8_class + ('Constructor'
436                                        if constructor.is_named_constructor else
437                                        '') %}
438 v8::Handle<v8::Object> wrapper = info.Holder();
439 V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{constructor_class}}::wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
440 {% endif %}
441 v8SetReturnValue(info, wrapper);
442 {% endmacro %}
443
444
445 {##############################################################################}
446 {% macro named_constructor_callback(constructor) %}
447 static void {{v8_class}}ConstructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
448 {
449     v8::Isolate* isolate = info.GetIsolate();
450     if (!info.IsConstructCall()) {
451         throwTypeError(ExceptionMessages::constructorNotCallableAsFunction("{{constructor.name}}"), isolate);
452         return;
453     }
454
455     if (ConstructorMode::current(isolate) == ConstructorMode::WrapExistingObject) {
456         v8SetReturnValue(info, info.Holder());
457         return;
458     }
459
460     Document* document = currentDOMWindow(isolate)->document();
461     ASSERT(document);
462
463     // Make sure the document is added to the DOM Node map. Otherwise, the {{cpp_class}} instance
464     // may end up being the only node in the map and get garbage-collected prematurely.
465     toV8(document, info.Holder(), isolate);
466
467     {% if constructor.has_exception_state %}
468     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), isolate);
469     {% endif %}
470     {% if constructor.number_of_required_arguments %}
471     if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
472         {{throw_arity_type_error(constructor, constructor.number_of_required_arguments)}};
473         return;
474     }
475     {% endif %}
476     {% for argument in constructor.arguments %}
477     {{generate_argument(constructor, argument) | indent}}
478     {% endfor %}
479     {{constructor.cpp_type}} impl = {{cpp_class}}::createForJSConstructor({{constructor.argument_list | join(', ')}});
480     {% if is_constructor_raises_exception %}
481     if (exceptionState.throwIfNeeded())
482         return;
483     {% endif %}
484
485     {{generate_constructor_wrapper(constructor) | indent}}
486 }
487 {% endmacro %}