Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / templates / interface.cpp
1 {% extends 'interface_base.cpp' %}
2
3
4 {##############################################################################}
5 {% macro attribute_configuration(attribute) %}
6 {% set getter_callback =
7        '%sV8Internal::%sAttributeGetterCallback' %
8             (cpp_class, attribute.name)
9        if not attribute.constructor_type else
10        '{0}V8Internal::{0}ConstructorGetter'.format(cpp_class) %}
11 {% set getter_callback_for_main_world =
12        '%sV8Internal::%sAttributeGetterCallbackForMainWorld' %
13             (cpp_class, attribute.name)
14        if attribute.is_per_world_bindings else '0' %}
15 {% set setter_callback = attribute.setter_callback %}
16 {% set setter_callback_for_main_world =
17        '%sV8Internal::%sAttributeSetterCallbackForMainWorld' %
18            (cpp_class, attribute.name)
19        if attribute.is_per_world_bindings and
20           (not attribute.is_read_only or attribute.put_forwards) else '0' %}
21 {% set wrapper_type_info =
22        'const_cast<WrapperTypeInfo*>(&V8%s::wrapperTypeInfo)' %
23             attribute.constructor_type
24         if attribute.constructor_type else '0' %}
25 {% set access_control = 'static_cast<v8::AccessControl>(%s)' %
26                         ' | '.join(attribute.access_control_list) %}
27 {% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
28                             ' | '.join(attribute.property_attributes) %}
29 {% set on_prototype = '1 /* on prototype */'
30        if interface_name == 'Window' and attribute.idl_type == 'EventHandler'
31        else '0 /* on instance */' %}
32 {% set attribute_configuration_list = [
33        '"%s"' % attribute.name,
34        getter_callback,
35        setter_callback,
36        getter_callback_for_main_world,
37        setter_callback_for_main_world,
38        wrapper_type_info,
39        access_control,
40        property_attribute,
41    ] %}
42 {% if not attribute.is_expose_js_accessors %}
43 {% set attribute_configuration_list = attribute_configuration_list
44                                     + [on_prototype] %}
45 {% endif %}
46 {{'{'}}{{attribute_configuration_list|join(', ')}}{{'}'}}
47 {%- endmacro %}
48
49
50 {##############################################################################}
51 {% macro method_configuration(method) %}
52 {% set method_callback =
53    '%sV8Internal::%sMethodCallback' % (cpp_class, method.name) %}
54 {% set method_callback_for_main_world =
55    '%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class, method.name)
56    if method.is_per_world_bindings else '0' %}
57 {"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.number_of_required_or_variadic_arguments}}}
58 {%- endmacro %}
59
60
61 {##############################################################################}
62 {% block constructor_getter %}
63 {% if has_constructor_attributes %}
64 static void {{cpp_class}}ConstructorGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
65 {
66     v8::Handle<v8::Value> data = info.Data();
67     ASSERT(data->IsExternal());
68     V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->CreationContext());
69     if (!perContextData)
70         return;
71     v8SetReturnValue(info, perContextData->constructorForType(WrapperTypeInfo::unwrap(data)));
72 }
73
74 {% endif %}
75 {% endblock %}
76
77
78 {##############################################################################}
79 {% block replaceable_attribute_setter_and_callback %}
80 {% if has_replaceable_attributes or has_constructor_attributes %}
81 {# FIXME: rename to ForceSetAttributeOnThis, since also used for Constructors #}
82 static void {{cpp_class}}ReplaceableAttributeSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
83 {
84     {% if is_check_security %}
85     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
86     v8::String::Utf8Value attributeName(name);
87     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
88     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), imp->frame(), exceptionState)) {
89         exceptionState.throwIfNeeded();
90         return;
91     }
92     {% endif %}
93     info.This()->ForceSet(name, jsValue);
94 }
95
96 {# FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors #}
97 static void {{cpp_class}}ReplaceableAttributeSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
98 {
99     {{cpp_class}}V8Internal::{{cpp_class}}ReplaceableAttributeSetter(name, jsValue, info);
100 }
101
102 {% endif %}
103 {% endblock %}
104
105
106 {##############################################################################}
107 {% block security_check_functions %}
108 {% if is_check_security and interface_name != 'Window' %}
109 bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
110 {
111     {{cpp_class}}* imp =  {{v8_class}}::toNative(host);
112     return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), imp->frame(), DoNotReportSecurityError);
113 }
114
115 bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
116 {
117     {{cpp_class}}* imp =  {{v8_class}}::toNative(host);
118     return BindingSecurity::shouldAllowAccessToFrame(v8::Isolate::GetCurrent(), imp->frame(), DoNotReportSecurityError);
119 }
120
121 {% endif %}
122 {% endblock %}
123
124
125 {##############################################################################}
126 {% block indexed_property_getter %}
127 {% if indexed_property_getter and not indexed_property_getter.is_custom %}
128 {% set getter = indexed_property_getter %}
129 static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
130 {
131     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
132     {% if getter.is_raises_exception %}
133     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
134     {% endif %}
135     {% set getter_name = getter.name or 'anonymousIndexedGetter' %}
136     {% set getter_arguments = ['index', 'exceptionState']
137            if getter.is_raises_exception else ['index'] %}
138     {{getter.cpp_type}} result = imp->{{getter_name}}({{getter_arguments|join(', ')}});
139     {% if getter.is_raises_exception %}
140     if (exceptionState.throwIfNeeded())
141         return;
142     {% endif %}
143     if ({{getter.is_null_expression}})
144         return;
145     {{getter.v8_set_return_value}};
146 }
147
148 {% endif %}
149 {% endblock %}
150
151
152 {##############################################################################}
153 {% block indexed_property_getter_callback %}
154 {% if indexed_property_getter %}
155 {% set getter = indexed_property_getter %}
156 static void indexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
157 {
158     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
159     {% if getter.is_custom %}
160     {{v8_class}}::indexedPropertyGetterCustom(index, info);
161     {% else %}
162     {{cpp_class}}V8Internal::indexedPropertyGetter(index, info);
163     {% endif %}
164     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
165 }
166
167 {% endif %}
168 {% endblock %}
169
170
171 {##############################################################################}
172 {% block indexed_property_setter %}
173 {% if indexed_property_setter and not indexed_property_setter.is_custom %}
174 {% set setter = indexed_property_setter %}
175 static void indexedPropertySetter(uint32_t index, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)
176 {
177     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
178     {{setter.v8_value_to_local_cpp_value}};
179     {% if setter.has_exception_state %}
180     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
181     {% endif %}
182     {% if setter.has_strict_type_checking %}
183     {# Type checking for interface types (if interface not implemented, throw
184        TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
185     if (!isUndefinedOrNull(jsValue) && !V8{{setter.idl_type}}::hasInstance(jsValue, info.GetIsolate())) {
186         exceptionState.throwTypeError("The provided value is not of type '{{setter.idl_type}}'.");
187         exceptionState.throwIfNeeded();
188         return;
189     }
190     {% endif %}
191     {% set setter_name = setter.name or 'anonymousIndexedSetter' %}
192     {% set setter_arguments = ['index', 'propertyValue', 'exceptionState']
193            if setter.is_raises_exception else ['index', 'propertyValue'] %}
194     bool result = imp->{{setter_name}}({{setter_arguments|join(', ')}});
195     {% if setter.is_raises_exception %}
196     if (exceptionState.throwIfNeeded())
197         return;
198     {% endif %}
199     if (!result)
200         return;
201     v8SetReturnValue(info, jsValue);
202 }
203
204 {% endif %}
205 {% endblock %}
206
207
208 {##############################################################################}
209 {% block indexed_property_setter_callback %}
210 {% if indexed_property_setter %}
211 {% set setter = indexed_property_setter %}
212 static void indexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)
213 {
214     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
215     {% if setter.is_custom %}
216     {{v8_class}}::indexedPropertySetterCustom(index, jsValue, info);
217     {% else %}
218     {{cpp_class}}V8Internal::indexedPropertySetter(index, jsValue, info);
219     {% endif %}
220     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
221 }
222
223 {% endif %}
224 {% endblock %}
225
226
227 {##############################################################################}
228 {% block indexed_property_deleter %}
229 {% if indexed_property_deleter and not indexed_property_deleter.is_custom %}
230 {% set deleter = indexed_property_deleter %}
231 static void indexedPropertyDeleter(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
232 {
233     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
234     {% if deleter.is_raises_exception %}
235     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
236     {% endif %}
237     {% set deleter_name = deleter.name or 'anonymousIndexedDeleter' %}
238     {% set deleter_arguments = ['index', 'exceptionState']
239            if deleter.is_raises_exception else ['index'] %}
240     DeleteResult result = imp->{{deleter_name}}({{deleter_arguments|join(', ')}});
241     {% if deleter.is_raises_exception %}
242     if (exceptionState.throwIfNeeded())
243         return;
244     {% endif %}
245     if (result != DeleteUnknownProperty)
246         return v8SetReturnValueBool(info, result == DeleteSuccess);
247 }
248
249 {% endif %}
250 {% endblock %}
251
252
253 {##############################################################################}
254 {% block indexed_property_deleter_callback %}
255 {% if indexed_property_deleter %}
256 {% set deleter = indexed_property_deleter %}
257 static void indexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
258 {
259     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMIndexedProperty");
260     {% if deleter.is_custom %}
261     {{v8_class}}::indexedPropertyDeleterCustom(index, info);
262     {% else %}
263     {{cpp_class}}V8Internal::indexedPropertyDeleter(index, info);
264     {% endif %}
265     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
266 }
267
268 {% endif %}
269 {% endblock %}
270
271
272 {##############################################################################}
273 {% from 'methods.cpp' import union_type_method_call %}
274 {% block named_property_getter %}
275 {% if named_property_getter and not named_property_getter.is_custom %}
276 {% set getter = named_property_getter %}
277 static void namedPropertyGetter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
278 {
279     {% if not is_override_builtins %}
280     if (info.Holder()->HasRealNamedProperty(name))
281         return;
282     if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())
283         return;
284
285     {% endif %}
286     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
287     AtomicString propertyName = toCoreAtomicString(name);
288     {% if getter.is_raises_exception %}
289     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
290     {% endif %}
291     {% if getter.union_arguments %}
292     {{union_type_method_call(getter) | indent}}
293     {% else %}
294     {{getter.cpp_type}} result = {{getter.cpp_value}};
295     {% if getter.is_raises_exception %}
296     if (exceptionState.throwIfNeeded())
297         return;
298     {% endif %}
299     if ({{getter.is_null_expression}})
300         return;
301     {{getter.v8_set_return_value}};
302     {% endif %}
303 }
304
305 {% endif %}
306 {% endblock %}
307
308
309 {##############################################################################}
310 {% block named_property_getter_callback %}
311 {% if named_property_getter %}
312 {% set getter = named_property_getter %}
313 static void namedPropertyGetterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Value>& info)
314 {
315     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
316     {% if getter.is_custom %}
317     {{v8_class}}::namedPropertyGetterCustom(name, info);
318     {% else %}
319     {{cpp_class}}V8Internal::namedPropertyGetter(name, info);
320     {% endif %}
321     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
322 }
323
324 {% endif %}
325 {% endblock %}
326
327
328 {##############################################################################}
329 {% block named_property_setter %}
330 {% if named_property_setter and not named_property_setter.is_custom %}
331 {% set setter = named_property_setter %}
332 static void namedPropertySetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)
333 {
334     {% if not is_override_builtins %}
335     if (info.Holder()->HasRealNamedProperty(name))
336         return;
337     if (!info.Holder()->GetRealNamedPropertyInPrototypeChain(name).IsEmpty())
338         return;
339
340     {% endif %}
341     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
342     {# v8_value_to_local_cpp_value('DOMString', 'name', 'propertyName') #}
343     V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, propertyName, name);
344     {{setter.v8_value_to_local_cpp_value}};
345     {% if setter.has_exception_state %}
346     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
347     {% endif %}
348     {% set setter_name = setter.name or 'anonymousNamedSetter' %}
349     {% set setter_arguments =
350            ['propertyName', 'propertyValue', 'exceptionState']
351            if setter.is_raises_exception else
352            ['propertyName', 'propertyValue'] %}
353     bool result = imp->{{setter_name}}({{setter_arguments|join(', ')}});
354     {% if setter.is_raises_exception %}
355     if (exceptionState.throwIfNeeded())
356         return;
357     {% endif %}
358     if (!result)
359         return;
360     v8SetReturnValue(info, jsValue);
361 }
362
363 {% endif %}
364 {% endblock %}
365
366
367 {##############################################################################}
368 {% block named_property_setter_callback %}
369 {% if named_property_setter %}
370 {% set setter = named_property_setter %}
371 static void namedPropertySetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<v8::Value>& info)
372 {
373     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
374     {% if setter.is_custom %}
375     {{v8_class}}::namedPropertySetterCustom(name, jsValue, info);
376     {% else %}
377     {{cpp_class}}V8Internal::namedPropertySetter(name, jsValue, info);
378     {% endif %}
379     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
380 }
381
382 {% endif %}
383 {% endblock %}
384
385
386 {##############################################################################}
387 {% block named_property_query %}
388 {% if named_property_getter and named_property_getter.is_enumerable and
389       not named_property_getter.is_custom_property_query %}
390 {# If there is an enumerator, there MUST be a query method to properly
391    communicate property attributes. #}
392 static void namedPropertyQuery(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
393 {
394     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
395     AtomicString propertyName = toCoreAtomicString(name);
396     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
397     bool result = imp->namedPropertyQuery(propertyName, exceptionState);
398     if (exceptionState.throwIfNeeded())
399         return;
400     if (!result)
401         return;
402     v8SetReturnValueInt(info, v8::None);
403 }
404
405 {% endif %}
406 {% endblock %}
407
408
409 {##############################################################################}
410 {% block named_property_query_callback %}
411 {% if named_property_getter and named_property_getter.is_enumerable %}
412 {% set getter = named_property_getter %}
413 static void namedPropertyQueryCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
414 {
415     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
416     {% if getter.is_custom_property_query %}
417     {{v8_class}}::namedPropertyQueryCustom(name, info);
418     {% else %}
419     {{cpp_class}}V8Internal::namedPropertyQuery(name, info);
420     {% endif %}
421     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
422 }
423
424 {% endif %}
425 {% endblock %}
426
427
428 {##############################################################################}
429 {% block named_property_deleter %}
430 {% if named_property_deleter and not named_property_deleter.is_custom %}
431 {% set deleter = named_property_deleter %}
432 static void namedPropertyDeleter(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
433 {
434     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
435     AtomicString propertyName = toCoreAtomicString(name);
436     {% if deleter.is_raises_exception %}
437     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
438     {% endif %}
439     {% set deleter_name = deleter.name or 'anonymousNamedDeleter' %}
440     {% set deleter_arguments = ['propertyName', 'exceptionState']
441            if deleter.is_raises_exception else ['propertyName'] %}
442     DeleteResult result = imp->{{deleter_name}}({{deleter_arguments|join(', ')}});
443     {% if deleter.is_raises_exception %}
444     if (exceptionState.throwIfNeeded())
445         return;
446     {% endif %}
447     if (result != DeleteUnknownProperty)
448         return v8SetReturnValueBool(info, result == DeleteSuccess);
449 }
450
451 {% endif %}
452 {% endblock %}
453
454
455 {##############################################################################}
456 {% block named_property_deleter_callback %}
457 {% if named_property_deleter %}
458 {% set deleter = named_property_deleter %}
459 static void namedPropertyDeleterCallback(v8::Local<v8::String> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
460 {
461     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
462     {% if deleter.is_custom %}
463     {{v8_class}}::namedPropertyDeleterCustom(name, info);
464     {% else %}
465     {{cpp_class}}V8Internal::namedPropertyDeleter(name, info);
466     {% endif %}
467     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
468 }
469
470 {% endif %}
471 {% endblock %}
472
473
474 {##############################################################################}
475 {% block named_property_enumerator %}
476 {% if named_property_getter and named_property_getter.is_enumerable and
477       not named_property_getter.is_custom_property_enumerator %}
478 static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
479 {
480     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
481     Vector<String> names;
482     ExceptionState exceptionState(info.Holder(), info.GetIsolate());
483     imp->namedPropertyEnumerator(names, exceptionState);
484     if (exceptionState.throwIfNeeded())
485         return;
486     v8::Handle<v8::Array> v8names = v8::Array::New(info.GetIsolate(), names.size());
487     for (size_t i = 0; i < names.size(); ++i)
488         v8names->Set(v8::Integer::New(info.GetIsolate(), i), v8String(info.GetIsolate(), names[i]));
489     v8SetReturnValue(info, v8names);
490 }
491
492 {% endif %}
493 {% endblock %}
494
495
496 {##############################################################################}
497 {% block named_property_enumerator_callback %}
498 {% if named_property_getter and named_property_getter.is_enumerable %}
499 {% set getter = named_property_getter %}
500 static void namedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>& info)
501 {
502     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMNamedProperty");
503     {% if getter.is_custom_property_enumerator %}
504     {{v8_class}}::namedPropertyEnumeratorCustom(info);
505     {% else %}
506     {{cpp_class}}V8Internal::namedPropertyEnumerator(info);
507     {% endif %}
508     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
509 }
510
511 {% endif %}
512 {% endblock %}
513
514
515 {##############################################################################}
516 {% block origin_safe_method_setter %}
517 {% if has_origin_safe_method_setter %}
518 static void {{cpp_class}}OriginSafeMethodSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
519 {
520     {# FIXME: don't call GetIsolate 3 times #}
521     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
522     if (holder.IsEmpty())
523         return;
524     {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
525     v8::String::Utf8Value attributeName(name);
526     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
527     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), imp->frame(), exceptionState)) {
528         exceptionState.throwIfNeeded();
529         return;
530     }
531
532     setHiddenValue(info.GetIsolate(), info.This(), name, jsValue);
533 }
534
535 static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
536 {
537     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
538     {{cpp_class}}V8Internal::{{cpp_class}}OriginSafeMethodSetter(name, jsValue, info);
539     TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
540 }
541
542 {% endif %}
543 {% endblock %}
544
545
546 {##############################################################################}
547 {% from 'methods.cpp' import named_constructor_callback with context %}
548 {% block named_constructor %}
549 {% if named_constructor %}
550 {% set to_active_dom_object = '%s::toActiveDOMObject' % v8_class
551                               if is_active_dom_object else '0' %}
552 {% set to_event_target = '%s::toEventTarget' % v8_class
553                          if is_event_target else '0' %}
554 const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, 0, {{v8_class}}::installPerContextEnabledMethods, 0, WrapperTypeObjectPrototype, false };
555
556 {{named_constructor_callback(named_constructor)}}
557 v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
558 {
559     // This is only for getting a unique pointer which we can pass to privateTemplate.
560     static int privateTemplateUniqueKey;
561     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
562     v8::Local<v8::FunctionTemplate> result = data->privateTemplateIfExists(currentWorldType, &privateTemplateUniqueKey);
563     if (!result.IsEmpty())
564         return result;
565
566     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
567     v8::EscapableHandleScope scope(isolate);
568     result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
569
570     v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
571     instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
572     result->SetClassName(v8AtomicString(isolate, "{{cpp_class}}"));
573     result->Inherit({{v8_class}}::domTemplate(isolate, currentWorldType));
574     data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result);
575
576     return scope.Escape(result);
577 }
578
579 {% endif %}
580 {% endblock %}
581
582 {##############################################################################}
583 {% block overloaded_constructor %}
584 {% if constructors|length > 1 %}
585 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
586 {
587     {% for constructor in constructors %}
588     if ({{constructor.overload_resolution_expression}}) {
589         {{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
590         return;
591     }
592     {% endfor %}
593     {% if interface_length %}
594     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
595     if (UNLIKELY(info.Length() < {{interface_length}})) {
596         exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{interface_length}}, info.Length()));
597         exceptionState.throwIfNeeded();
598         return;
599     }
600     exceptionState.throwTypeError("No matching constructor signature.");
601     exceptionState.throwIfNeeded();
602     {% else %}
603     throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "No matching constructor signature."), info.GetIsolate());
604     {% endif %}
605 }
606
607 {% endif %}
608 {% endblock %}
609
610
611 {##############################################################################}
612 {% block event_constructor %}
613 {% if has_event_constructor %}
614 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
615 {
616     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
617     if (info.Length() < 1) {
618         exceptionState.throwTypeError("An event name must be provided.");
619         exceptionState.throwIfNeeded();
620         return;
621     }
622
623     V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
624     {% for attribute in any_type_attributes %}
625     v8::Local<v8::Value> {{attribute.name}};
626     {% endfor %}
627     {{cpp_class}}Init eventInit;
628     if (info.Length() >= 2) {
629         V8TRYCATCH_VOID(Dictionary, options, Dictionary(info[1], info.GetIsolate()));
630         if (!initialize{{cpp_class}}(eventInit, options, exceptionState, info)) {
631             exceptionState.throwIfNeeded();
632             return;
633         }
634         {# Store attributes of type |any| on the wrapper to avoid leaking them
635            between isolated worlds. #}
636         {% for attribute in any_type_attributes %}
637         options.get("{{attribute.name}}", {{attribute.name}});
638         if (!{{attribute.name}}.IsEmpty())
639             setHiddenValue(info.GetIsolate(), info.Holder(), "{{attribute.name}}", {{attribute.name}});
640         {% endfor %}
641     }
642     {% if is_constructor_raises_exception %}
643     RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit, exceptionState);
644     if (exceptionState.throwIfNeeded())
645         return;
646     {% else %}
647     RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit);
648     {% endif %}
649     {% if any_type_attributes and not interface_name == 'ErrorEvent' %}
650     {# If we're in an isolated world, create a SerializedScriptValue and store
651        it in the event for later cloning if the property is accessed from
652        another world. The main world case is handled lazily (in custom code).
653
654        We do not clone Error objects (exceptions), for 2 reasons:
655        1) Errors carry a reference to the isolated world's global object, and
656           thus passing it around would cause leakage.
657        2) Errors cannot be cloned (or serialized):
658        http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data #}
659     if (isolatedWorldForIsolate(info.GetIsolate())) {
660         {% for attribute in any_type_attributes %}
661         if (!{{attribute.name}}.IsEmpty())
662             event->setSerialized{{attribute.name | blink_capitalize}}(SerializedScriptValue::createAndSwallowExceptions({{attribute.name}}, info.GetIsolate()));
663         {% endfor %}
664     }
665
666     {% endif %}
667     v8::Handle<v8::Object> wrapper = info.Holder();
668     V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(event.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
669     v8SetReturnValue(info, wrapper);
670 }
671
672 {% endif %}
673 {% endblock %}
674
675
676 {##############################################################################}
677 {% block visit_dom_wrapper %}
678 {% if reachable_node_function or set_wrapper_reference_to_list %}
679 void {{v8_class}}::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
680 {
681     {{cpp_class}}* impl = fromInternalPointer(object);
682     {% if set_wrapper_reference_to_list %}
683     v8::Local<v8::Object> creationContext = v8::Local<v8::Object>::New(isolate, wrapper);
684     V8WrapperInstantiationScope scope(creationContext, isolate);
685     {% for set_wrapper_reference_to in set_wrapper_reference_to_list %}
686     {{set_wrapper_reference_to.idl_type}}* {{set_wrapper_reference_to.name}} = impl->{{set_wrapper_reference_to.name}}();
687     if ({{set_wrapper_reference_to.name}}) {
688         if (!DOMDataStore::containsWrapper<{{set_wrapper_reference_to.v8_type}}>({{set_wrapper_reference_to.name}}, isolate))
689             wrap({{set_wrapper_reference_to.name}}, creationContext, isolate);
690         DOMDataStore::setWrapperReference<{{set_wrapper_reference_to.v8_type}}>(wrapper, {{set_wrapper_reference_to.name}}, isolate);
691     }
692     {% endfor %}
693     {% endif %}
694     {% if reachable_node_function %}
695     if (Node* owner = impl->{{reachable_node_function}}()) {
696         Node* root = V8GCController::opaqueRootForGC(owner, isolate);
697         isolate->SetReferenceFromGroup(v8::UniqueId(reinterpret_cast<intptr_t>(root)), wrapper);
698         return;
699     }
700     {% endif %}
701     setObjectGroup(object, wrapper, isolate);
702 }
703
704 {% endif %}
705 {% endblock %}
706
707
708 {##############################################################################}
709 {% block shadow_attributes %}
710 {% if interface_name == 'Window' %}
711 static const V8DOMConfiguration::AttributeConfiguration shadowAttributes[] = {
712     {% for attribute in attributes if attribute.is_unforgeable %}
713     {{attribute_configuration(attribute)}},
714     {% endfor %}
715 };
716
717 {% endif %}
718 {% endblock %}
719
720
721 {##############################################################################}
722 {% block class_attributes %}
723 {# FIXME: rename to install_attributes and put into configure_class_template #}
724 {% if has_attribute_configuration %}
725 static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[] = {
726     {% for attribute in attributes
727        if not (attribute.is_expose_js_accessors or
728                attribute.is_static or
729                attribute.runtime_enabled_function or
730                attribute.per_context_enabled_function or
731                (interface_name == 'Window' and attribute.is_unforgeable)) %}
732     {% filter conditional(attribute.conditional_string) %}
733     {{attribute_configuration(attribute)}},
734     {% endfilter %}
735     {% endfor %}
736 };
737
738 {% endif %}
739 {% endblock %}
740
741
742 {##############################################################################}
743 {% block class_accessors %}
744 {# FIXME: rename install_accessors and put into configure_class_template #}
745 {% if has_accessors %}
746 static const V8DOMConfiguration::AccessorConfiguration {{v8_class}}Accessors[] = {
747     {% for attribute in attributes if attribute.is_expose_js_accessors %}
748     {{attribute_configuration(attribute)}},
749     {% endfor %}
750 };
751
752 {% endif %}
753 {% endblock %}
754
755
756 {##############################################################################}
757 {% block class_methods %}
758 {# FIXME: rename to install_methods and put into configure_class_template #}
759 {% if has_method_configuration %}
760 static const V8DOMConfiguration::MethodConfiguration {{v8_class}}Methods[] = {
761     {% for method in methods if method.do_generate_method_configuration %}
762     {% filter conditional(method.conditional_string) %}
763     {{method_configuration(method)}},
764     {% endfilter %}
765     {% endfor %}
766 };
767
768 {% endif %}
769 {% endblock %}
770
771
772 {##############################################################################}
773 {% block initialize_event %}
774 {% if has_event_constructor %}
775 bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& options, ExceptionState& exceptionState, const v8::FunctionCallbackInfo<v8::Value>& info, const String& forEventName)
776 {
777     Dictionary::ConversionContext conversionContext(forEventName.isEmpty() ? String("{{interface_name}}") : forEventName, "", exceptionState);
778     {% if parent_interface %}{# any Event interface except Event itself #}
779     if (!initialize{{parent_interface}}(eventInit, options, exceptionState, info, forEventName.isEmpty() ? String("{{interface_name}}") : forEventName))
780         return false;
781
782     {% endif %}
783     {% for attribute in attributes
784            if (attribute.is_initialized_by_event_constructor and
785                not attribute.idl_type == 'any')%}
786     {% set is_nullable = 'true' if attribute.is_nullable else 'false' %}
787     {% if attribute.deprecate_as %}
788     if (options.convert(conversionContext.setConversionType("{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{attribute.cpp_name}})) {
789         if (options.hasProperty("{{attribute.name}}"))
790             UseCounter::countDeprecation(activeExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
791     } else {
792         return false;
793     }
794     {% else %}
795     if (!options.convert(conversionContext.setConversionType("{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{attribute.cpp_name}}))
796         return false;
797     {% endif %}
798     {% endfor %}
799     return true;
800 }
801
802 {% endif %}
803 {% endblock %}
804
805
806 {##############################################################################}
807 {% block constructor_callback %}
808 {% if constructors or has_custom_constructor or has_event_constructor %}
809 void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
810 {
811     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMConstructor");
812     {% if measure_as %}
813     UseCounter::count(activeExecutionContext(info.GetIsolate()), UseCounter::{{measure_as}});
814     {% endif %}
815     if (!info.IsConstructCall()) {
816         throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "Please use the 'new' operator, this DOM object constructor cannot be called as a function."), info.GetIsolate());
817         return;
818     }
819
820     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) {
821         v8SetReturnValue(info, info.Holder());
822         return;
823     }
824
825     {% if has_custom_constructor %}
826     {{v8_class}}::constructorCustom(info);
827     {% else %}
828     {{cpp_class}}V8Internal::constructor(info);
829     {% endif %}
830 }
831
832 {% endif %}
833 {% endblock %}
834
835
836 {##############################################################################}
837 {% block configure_shadow_object_template %}
838 {% if interface_name == 'Window' %}
839 static void configureShadowObjectTemplate(v8::Handle<v8::ObjectTemplate> templ, v8::Isolate* isolate, WrapperWorldType currentWorldType)
840 {
841     V8DOMConfiguration::installAttributes(templ, v8::Handle<v8::ObjectTemplate>(), shadowAttributes, WTF_ARRAY_LENGTH(shadowAttributes), isolate, currentWorldType);
842
843     // Install a security handler with V8.
844     templ->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)));
845     templ->SetInternalFieldCount(V8Window::internalFieldCount);
846 }
847
848 {% endif %}
849 {% endblock %}
850
851
852 {##############################################################################}
853 {% block configure_class_template %}
854 {# FIXME: rename to install_dom_template and Install{{v8_class}}DOMTemplate #}
855 static void configure{{v8_class}}Template(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate, WrapperWorldType currentWorldType)
856 {
857     functionTemplate->ReadOnlyPrototype();
858
859     v8::Local<v8::Signature> defaultSignature;
860     {% set parent_template =
861            'V8%s::domTemplate(isolate, currentWorldType)' % parent_interface
862            if parent_interface else 'v8::Local<v8::FunctionTemplate>()' %}
863     {% if runtime_enabled_function %}
864     if (!{{runtime_enabled_function}}())
865         defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "", {{parent_template}}, {{v8_class}}::internalFieldCount, 0, 0, 0, 0, 0, 0, isolate, currentWorldType);
866     else
867     {% endif %}
868     {% set runtime_enabled_indent = 4 if runtime_enabled_function else 0 %}
869     {% filter indent(runtime_enabled_indent, true) %}
870     defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "{{interface_name}}", {{parent_template}}, {{v8_class}}::internalFieldCount,
871         {# Test needed as size 0 constant arrays are not allowed in VC++ #}
872         {% set attributes_name, attributes_length =
873                ('%sAttributes' % v8_class,
874                 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class)
875            if has_attribute_configuration else (0, 0) %}
876         {% set accessors_name, accessors_length =
877                ('%sAccessors' % v8_class,
878                 'WTF_ARRAY_LENGTH(%sAccessors)' % v8_class)
879            if has_accessors else (0, 0) %}
880         {% set methods_name, methods_length =
881                ('%sMethods' % v8_class,
882                 'WTF_ARRAY_LENGTH(%sMethods)' % v8_class)
883            if has_method_configuration else (0, 0) %}
884         {{attributes_name}}, {{attributes_length}},
885         {{accessors_name}}, {{accessors_length}},
886         {{methods_name}}, {{methods_length}},
887         isolate, currentWorldType);
888     {% endfilter %}
889
890     {% if constructors or has_custom_constructor or has_event_constructor %}
891     functionTemplate->SetCallHandler({{v8_class}}::constructorCallback);
892     functionTemplate->SetLength({{interface_length}});
893     {% endif %}
894     v8::Local<v8::ObjectTemplate> ALLOW_UNUSED instanceTemplate = functionTemplate->InstanceTemplate();
895     v8::Local<v8::ObjectTemplate> ALLOW_UNUSED prototypeTemplate = functionTemplate->PrototypeTemplate();
896     {% if is_check_security and interface_name != 'Window' %}
897     instanceTemplate->SetAccessCheckCallbacks({{cpp_class}}V8Internal::namedSecurityCheck, {{cpp_class}}V8Internal::indexedSecurityCheck, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperTypeInfo)));
898     {% endif %}
899     {% for attribute in attributes
900        if attribute.runtime_enabled_function and
901           not attribute.per_context_enabled_function and
902           not attribute.is_static %}
903     {% filter conditional(attribute.conditional_string) %}
904     if ({{attribute.runtime_enabled_function}}()) {
905         static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\
906         {{attribute_configuration(attribute)}};
907         V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate, currentWorldType);
908     }
909     {% endfilter %}
910     {% endfor %}
911     {% if constants %}
912     {{install_constants() | indent}}
913     {% endif %}
914     {# Special operations #}
915     {# V8 has access-check callback API and it's used on Window instead of
916        deleters or enumerators; see ObjectTemplate::SetAccessCheckCallbacks.
917        In addition, the getter should be set on the prototype template, to get
918        the implementation straight out of the Window prototype, regardless of
919        what prototype is actually set on the object. #}
920     {% set set_on_template = 'PrototypeTemplate' if interface_name == 'Window'
921                         else 'InstanceTemplate' %}
922     {% if indexed_property_getter %}
923     {# if have indexed properties, MUST have an indexed property getter #}
924     {% set indexed_property_getter_callback =
925            '%sV8Internal::indexedPropertyGetterCallback' % cpp_class %}
926     {% set indexed_property_setter_callback =
927            '%sV8Internal::indexedPropertySetterCallback' % cpp_class
928            if indexed_property_setter else '0' %}
929     {% set indexed_property_query_callback = '0' %}{# Unused #}
930     {% set indexed_property_deleter_callback =
931            '%sV8Internal::indexedPropertyDeleterCallback' % cpp_class
932            if indexed_property_deleter else '0' %}
933     {% set indexed_property_enumerator_callback =
934            'indexedPropertyEnumerator<%s>' % cpp_class
935            if indexed_property_getter.is_enumerable else '0' %}
936     functionTemplate->{{set_on_template}}()->SetIndexedPropertyHandler({{indexed_property_getter_callback}}, {{indexed_property_setter_callback}}, {{indexed_property_query_callback}}, {{indexed_property_deleter_callback}}, {{indexed_property_enumerator_callback}});
937     {% endif %}
938     {% if named_property_getter %}
939     {# if have named properties, MUST have a named property getter #}
940     {% set named_property_getter_callback =
941            '%sV8Internal::namedPropertyGetterCallback' % cpp_class %}
942     {% set named_property_setter_callback =
943            '%sV8Internal::namedPropertySetterCallback' % cpp_class
944            if named_property_setter else '0' %}
945     {% set named_property_query_callback =
946            '%sV8Internal::namedPropertyQueryCallback' % cpp_class
947            if named_property_getter.is_enumerable else '0' %}
948     {% set named_property_deleter_callback =
949            '%sV8Internal::namedPropertyDeleterCallback' % cpp_class
950            if named_property_deleter else '0' %}
951     {% set named_property_enumerator_callback =
952            '%sV8Internal::namedPropertyEnumeratorCallback' % cpp_class
953            if named_property_getter.is_enumerable else '0' %}
954     functionTemplate->{{set_on_template}}()->SetNamedPropertyHandler({{named_property_getter_callback}}, {{named_property_setter_callback}}, {{named_property_query_callback}}, {{named_property_deleter_callback}}, {{named_property_enumerator_callback}});
955     {% endif %}
956     {# End special operations #}
957     {% if has_custom_legacy_call_as_function %}
958     functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler({{v8_class}}::legacyCallCustom);
959     {% endif %}
960     {% if interface_name == 'HTMLAllCollection' %}
961     {# Needed for legacy support of document.all #}
962     functionTemplate->InstanceTemplate()->MarkAsUndetectable();
963     {% endif %}
964     {% for method in methods if not method.do_not_check_signature %}
965     {# install_custom_signature #}
966     {% if not method.overload_index or method.overload_index == 1 %}
967     {# For overloaded methods, only generate one accessor #}
968     {% filter conditional(method.conditional_string) %}
969     {% if method.is_do_not_check_security %}
970     {% if method.is_per_world_bindings %}
971     if (currentWorldType == MainWorld) {
972         {{install_do_not_check_security_signature(method, 'ForMainWorld')}}
973     } else {
974         {{install_do_not_check_security_signature(method)}}
975     }
976     {% else %}
977     {{install_do_not_check_security_signature(method)}}
978     {% endif %}
979     {% else %}{# is_do_not_check_security #}
980     {% if method.is_per_world_bindings %}
981     if (currentWorldType == MainWorld) {
982         {% filter runtime_enabled(method.runtime_enabled_function) %}
983         {{install_custom_signature(method, 'ForMainWorld')}}
984         {% endfilter %}
985     } else {
986         {% filter runtime_enabled(method.runtime_enabled_function) %}
987         {{install_custom_signature(method)}}
988         {% endfilter %}
989     }
990     {% else %}
991     {% filter runtime_enabled(method.runtime_enabled_function) %}
992     {{install_custom_signature(method)}}
993     {% endfilter %}
994     {% endif %}
995     {% endif %}{# is_do_not_check_security #}
996     {% endfilter %}
997     {% endif %}{# install_custom_signature #}
998     {% endfor %}
999     {% for attribute in attributes if attribute.is_static %}
1000     {% set getter_callback = '%sV8Internal::%sAttributeGetterCallback' %
1001            (cpp_class, attribute.name) %}
1002     {% filter conditional(attribute.conditional_string) %}
1003     functionTemplate->SetNativeDataProperty(v8AtomicString(isolate, "{{attribute.name}}"), {{getter_callback}}, {{attribute.setter_callback}}, v8::External::New(isolate, 0), static_cast<v8::PropertyAttribute>(v8::None), v8::Handle<v8::AccessorSignature>(), static_cast<v8::AccessControl>(v8::DEFAULT));
1004     {% endfilter %}
1005     {% endfor %}
1006     {# Special interfaces #}
1007     {% if interface_name == 'Window' %}
1008
1009     prototypeTemplate->SetInternalFieldCount(V8Window::internalFieldCount);
1010     functionTemplate->SetHiddenPrototype(true);
1011     instanceTemplate->SetInternalFieldCount(V8Window::internalFieldCount);
1012     // Set access check callbacks, but turned off initially.
1013     // When a context is detached from a frame, turn on the access check.
1014     // Turning on checks also invalidates inline caches of the object.
1015     instanceTemplate->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&V8Window::wrapperTypeInfo)), false);
1016     {% elif interface_name in [
1017            'HTMLDocument', 'DedicatedWorkerGlobalScope',
1018            'SharedWorkerGlobalScope', 'ServiceWorkerGlobalScope'] %}
1019     functionTemplate->SetHiddenPrototype(true);
1020     {% endif %}
1021
1022     // Custom toString template
1023     functionTemplate->Set(v8AtomicString(isolate, "toString"), V8PerIsolateData::current()->toStringTemplate());
1024 }
1025
1026 {% endblock %}
1027
1028
1029 {######################################}
1030 {% macro install_do_not_check_security_signature(method, world_suffix) %}
1031 {# FIXME: move to V8DOMConfiguration::installDOMCallbacksWithDoNotCheckSecuritySignature #}
1032 {# Methods that are [DoNotCheckSecurity] are always readable, but if they are
1033    changed and then accessed from a different origin, we do not return the
1034    underlying value, but instead return a new copy of the original function.
1035    This is achieved by storing the changed value as a hidden property. #}
1036 {% set getter_callback =
1037        '%sV8Internal::%sOriginSafeMethodGetterCallback%s' %
1038        (cpp_class, method.name, world_suffix) %}
1039 {% set setter_callback =
1040     '{0}V8Internal::{0}OriginSafeMethodSetterCallback'.format(cpp_class)
1041     if not method.is_read_only else '0' %}
1042 {% set property_attribute =
1043     'static_cast<v8::PropertyAttribute>(%s)' %
1044     ' | '.join(method.property_attributes or ['v8::DontDelete']) %}
1045 {{method.function_template}}->SetAccessor(v8AtomicString(isolate, "{{method.name}}"), {{getter_callback}}, {{setter_callback}}, v8Undefined(), v8::ALL_CAN_READ, {{property_attribute}});
1046 {%- endmacro %}
1047
1048
1049 {######################################}
1050 {% macro install_custom_signature(method, world_suffix) %}
1051 {# FIXME: move to V8DOMConfiguration::installDOMCallbacksWithCustomSignature #}
1052 {% set method_callback = '%sV8Internal::%sMethodCallback%s' %
1053                          (cpp_class, method.name, world_suffix) %}
1054 {% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
1055                             ' | '.join(method.property_attributes) %}
1056 {{method.function_template}}->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{method_callback}}, v8Undefined(), {{method.signature}}, {{method.number_of_required_or_variadic_arguments}}){% if method.property_attributes %}, {{property_attribute}}{% endif %});
1057 {%- endmacro %}
1058
1059
1060 {######################################}
1061 {% macro install_constants() %}
1062 {# FIXME: should use reflected_name instead of name #}
1063 {# Normal (always enabled) constants #}
1064 static const V8DOMConfiguration::ConstantConfiguration {{v8_class}}Constants[] = {
1065     {% for constant in constants if not constant.runtime_enabled_function %}
1066     {"{{constant.name}}", {{constant.value}}},
1067     {% endfor %}
1068 };
1069 V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, {{v8_class}}Constants, WTF_ARRAY_LENGTH({{v8_class}}Constants), isolate);
1070 {# Runtime-enabled constants #}
1071 {% for constant in constants if constant.runtime_enabled_function %}
1072 if ({{constant.runtime_enabled_function}}()) {
1073     static const V8DOMConfiguration::ConstantConfiguration constantConfiguration = {"{{constant.name}}", static_cast<signed int>({{constant.value}})};
1074     V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, &constantConfiguration, 1, isolate);
1075 }
1076 {% endfor %}
1077 {# Check constants #}
1078 {% if not do_not_check_constants %}
1079 {% for constant in constants %}
1080 {% set constant_cpp_class = constant.cpp_class or cpp_class %}
1081 COMPILE_ASSERT({{constant.value}} == {{constant_cpp_class}}::{{constant.reflected_name}}, TheValueOf{{cpp_class}}_{{constant.reflected_name}}DoesntMatchWithImplementation);
1082 {% endfor %}
1083 {% endif %}
1084 {% endmacro %}
1085
1086
1087 {##############################################################################}
1088 {% block get_template %}
1089 {# FIXME: rename to get_dom_template and GetDOMTemplate #}
1090 v8::Handle<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
1091 {
1092     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
1093     V8PerIsolateData::TemplateMap::iterator result = data->templateMap(currentWorldType).find(&wrapperTypeInfo);
1094     if (result != data->templateMap(currentWorldType).end())
1095         return result->value.newLocal(isolate);
1096
1097     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
1098     v8::EscapableHandleScope handleScope(isolate);
1099     v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate, V8ObjectConstructor::isValidConstructorMode);
1100     configure{{v8_class}}Template(templ, isolate, currentWorldType);
1101     data->templateMap(currentWorldType).add(&wrapperTypeInfo, UnsafePersistent<v8::FunctionTemplate>(isolate, templ));
1102     return handleScope.Escape(templ);
1103 }
1104
1105 {% endblock %}
1106
1107
1108 {##############################################################################}
1109 {% block has_instance %}
1110 bool {{v8_class}}::hasInstance(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate)
1111 {
1112     return V8PerIsolateData::from(isolate)->hasInstanceInMainWorld(&wrapperTypeInfo, jsValue)
1113         || V8PerIsolateData::from(isolate)->hasInstanceInNonMainWorld(&wrapperTypeInfo, jsValue);
1114 }
1115
1116 {% endblock %}
1117
1118
1119 {##############################################################################}
1120 {% block install_per_context_attributes %}
1121 {% if has_per_context_enabled_attributes %}
1122 void {{v8_class}}::installPerContextEnabledProperties(v8::Handle<v8::Object> instanceTemplate, {{cpp_class}}* impl, v8::Isolate* isolate)
1123 {
1124     v8::Local<v8::Object> prototypeTemplate = v8::Local<v8::Object>::Cast(instanceTemplate->GetPrototype());
1125     {% for attribute in attributes if attribute.per_context_enabled_function %}
1126     if ({{attribute.per_context_enabled_function}}(impl->document())) {
1127         static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\
1128         {{attribute_configuration(attribute)}};
1129         V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate);
1130     }
1131     {% endfor %}
1132 }
1133
1134 {% endif %}
1135 {% endblock %}
1136
1137
1138 {##############################################################################}
1139 {% block install_per_context_methods %}
1140 {% if has_per_context_enabled_methods %}
1141 void {{v8_class}}::installPerContextEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate)
1142 {
1143     {# Define per-context enabled operations #}
1144     v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate, worldType(isolate)));
1145
1146     ExecutionContext* context = toExecutionContext(prototypeTemplate->CreationContext());
1147     {% for method in methods if method.per_context_enabled_function %}
1148     if (context && context->isDocument() && {{method.per_context_enabled_function}}(toDocument(context)))
1149         prototypeTemplate->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{cpp_class}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());
1150     {% endfor %}
1151 }
1152
1153 {% endif %}
1154 {% endblock %}
1155
1156
1157 {##############################################################################}
1158 {% block to_active_dom_object %}
1159 {% if is_active_dom_object %}
1160 ActiveDOMObject* {{v8_class}}::toActiveDOMObject(v8::Handle<v8::Object> wrapper)
1161 {
1162     return toNative(wrapper);
1163 }
1164
1165 {% endif %}
1166 {% endblock %}
1167
1168
1169 {##############################################################################}
1170 {% block to_event_target %}
1171 {% if is_event_target %}
1172 EventTarget* {{v8_class}}::toEventTarget(v8::Handle<v8::Object> object)
1173 {
1174     return toNative(object);
1175 }
1176
1177 {% endif %}
1178 {% endblock %}
1179
1180
1181 {##############################################################################}
1182 {% block get_shadow_object_template %}
1183 {% if interface_name == 'Window' %}
1184 v8::Handle<v8::ObjectTemplate> V8Window::getShadowObjectTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
1185 {
1186     if (currentWorldType == MainWorld) {
1187         DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForMainWorld, ());
1188         if (V8WindowShadowObjectCacheForMainWorld.IsEmpty()) {
1189             TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
1190             v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
1191             configureShadowObjectTemplate(templ, isolate, currentWorldType);
1192             V8WindowShadowObjectCacheForMainWorld.Reset(isolate, templ);
1193             return templ;
1194         }
1195         return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForMainWorld);
1196     } else {
1197         DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowObjectCacheForNonMainWorld, ());
1198         if (V8WindowShadowObjectCacheForNonMainWorld.IsEmpty()) {
1199             TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
1200             v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
1201             configureShadowObjectTemplate(templ, isolate, currentWorldType);
1202             V8WindowShadowObjectCacheForNonMainWorld.Reset(isolate, templ);
1203             return templ;
1204         }
1205         return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectCacheForNonMainWorld);
1206     }
1207 }
1208
1209 {% endif %}
1210 {% endblock %}
1211
1212
1213 {##############################################################################}
1214 {% block wrap %}
1215 {% if special_wrap_for or is_document %}
1216 v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
1217 {
1218     ASSERT(impl);
1219     {% for special_wrap_interface in special_wrap_for %}
1220     if (impl->is{{special_wrap_interface}}())
1221         return wrap(to{{special_wrap_interface}}(impl), creationContext, isolate);
1222     {% endfor %}
1223     v8::Handle<v8::Object> wrapper = {{v8_class}}::createWrapper(impl, creationContext, isolate);
1224     {% if is_document %}
1225     if (wrapper.IsEmpty())
1226         return wrapper;
1227     if (!isolatedWorldForEnteredContext(isolate)) {
1228         if (Frame* frame = impl->frame())
1229             frame->script().windowShell(DOMWrapperWorld::mainWorld())->updateDocumentWrapper(wrapper);
1230     }
1231     {% endif %}
1232     return wrapper;
1233 }
1234
1235 {% endif %}
1236 {% endblock %}
1237
1238
1239 {##############################################################################}
1240 {% block create_wrapper %}
1241 {% if not has_custom_to_v8 %}
1242 v8::Handle<v8::Object> {{v8_class}}::createWrapper({{pass_ref_ptr}}<{{cpp_class}}> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
1243 {
1244     ASSERT(impl);
1245     ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl.get(), isolate));
1246     if (ScriptWrappable::wrapperCanBeStoredInObject(impl.get())) {
1247         const WrapperTypeInfo* actualInfo = ScriptWrappable::getTypeInfoFromObject(impl.get());
1248         // Might be a XXXConstructor::wrapperTypeInfo instead of an XXX::wrapperTypeInfo. These will both have
1249         // the same object de-ref functions, though, so use that as the basis of the check.
1250         RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction == wrapperTypeInfo.derefObjectFunction);
1251     }
1252
1253     {% if is_document %}
1254     if (Frame* frame = impl->frame()) {
1255         if (frame->script().initializeMainWorld()) {
1256             // initializeMainWorld may have created a wrapper for the object, retry from the start.
1257             v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper<{{v8_class}}>(impl.get(), isolate);
1258             if (!wrapper.IsEmpty())
1259                 return wrapper;
1260         }
1261     }
1262     {% endif %}
1263     v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &wrapperTypeInfo, toInternalPointer(impl.get()), isolate);
1264     if (UNLIKELY(wrapper.IsEmpty()))
1265         return wrapper;
1266
1267     {% if is_audio_buffer %}
1268     {# We only setDeallocationObservers on array buffers that are held by some
1269        object in the V8 heap, not in the ArrayBuffer constructor itself.
1270        This is because V8 GC only cares about memory it can free on GC, and
1271        until the object is exposed to JavaScript, V8 GC doesn't affect it. #}
1272     for (unsigned i = 0, n = impl->numberOfChannels(); i < n; i++) {
1273         Float32Array* channelData = impl->getChannelData(i);
1274         channelData->buffer()->setDeallocationObserver(V8ArrayBufferDeallocationObserver::instanceTemplate());
1275     }
1276     {% endif %}
1277     installPerContextEnabledProperties(wrapper, impl.get(), isolate);
1278     {% set wrapper_configuration = 'WrapperConfiguration::Dependent'
1279                                    if (has_visit_dom_wrapper or
1280                                        is_active_dom_object or
1281                                        is_dependent_lifetime) else
1282                                    'WrapperConfiguration::Independent' %}
1283     V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl, &wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
1284     return wrapper;
1285 }
1286
1287 {% endif %}
1288 {% endblock %}
1289
1290
1291 {##############################################################################}
1292 {% block deref_object_and_to_v8_no_inline %}
1293 void {{v8_class}}::derefObject(void* object)
1294 {
1295 {% set oilpan_conditional = '!ENABLE(OILPAN)' if is_will_be_garbage_collected
1296                                               else '' %}
1297 {% filter conditional(oilpan_conditional) %}
1298     fromInternalPointer(object)->deref();
1299 {% endfilter %}
1300 }
1301
1302 template<>
1303 v8::Handle<v8::Value> toV8NoInline({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
1304 {
1305     return toV8(impl, creationContext, isolate);
1306 }
1307
1308 {% endblock %}