• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(interface_name) %}
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 not attribute.is_read_only else '0' %}
20 {% set wrapper_type_info =
21        'const_cast<WrapperTypeInfo*>(&V8%s::wrapperTypeInfo)' %
22             attribute.constructor_type
23         if attribute.constructor_type else '0' %}
24 {% set access_control = 'static_cast<v8::AccessControl>(%s)' %
25                         ' | '.join(attribute.access_control_list) %}
26 {% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
27                             ' | '.join(attribute.property_attributes) %}
28 {% set on_prototype = ', 0 /* on instance */'
29        if not attribute.is_expose_js_accessors else '' %}
30 {"{{attribute.name}}", {{getter_callback}}, {{setter_callback}}, {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, {{wrapper_type_info}}, {{access_control}}, {{property_attribute}}{{on_prototype}}}
31 {%- endmacro %}
32 
33 
34 {##############################################################################}
35 {% macro method_configuration(method) %}
36 {% set method_callback =
37    '%sV8Internal::%sMethodCallback' % (cpp_class, method.name) %}
38 {% set method_callback_for_main_world =
39    '%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class, method.name)
40    if method.is_per_world_bindings else '0' %}
41 {"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.number_of_required_or_variadic_arguments}}}
42 {%- endmacro %}
43 
44 
45 {##############################################################################}
46 {% block constructor_getter %}
47 {% if has_constructor_attributes %}
48 static void {{interface_name}}ConstructorGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
49 {
50     v8::Handle<v8::Value> data = info.Data();
51     ASSERT(data->IsExternal());
52     V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->CreationContext());
53     if (!perContextData)
54         return;
55     v8SetReturnValue(info, perContextData->constructorForType(WrapperTypeInfo::unwrap(data)));
56 }
57 
58 {% endif %}
59 {% endblock %}
60 
61 
62 {##############################################################################}
63 {% block replaceable_attribute_setter_and_callback %}
64 {% if has_replaceable_attributes or has_constructor_attributes %}
65 {# FIXME: rename to ForceSetAttributeOnThis, since also used for Constructors #}
66 static void {{interface_name}}ReplaceableAttributeSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
67 {
68     info.This()->ForceSet(name, jsValue);
69 }
70 
71 {# FIXME: rename to ForceSetAttributeOnThisCallback, since also used for Constructors #}
72 static void {{interface_name}}ReplaceableAttributeSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
73 {
74     {{interface_name}}V8Internal::{{interface_name}}ReplaceableAttributeSetter(name, jsValue, info);
75 }
76 
77 {% endif %}
78 {% endblock %}
79 
80 
81 {##############################################################################}
82 {% block security_check_functions %}
83 {% if is_check_security and interface_name != 'Window' %}
84 bool indexedSecurityCheck(v8::Local<v8::Object> host, uint32_t index, v8::AccessType type, v8::Local<v8::Value>)
85 {
86     {{cpp_class}}* imp =  {{v8_class}}::toNative(host);
87     return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
88 }
89 
90 bool namedSecurityCheck(v8::Local<v8::Object> host, v8::Local<v8::Value> key, v8::AccessType type, v8::Local<v8::Value>)
91 {
92     {{cpp_class}}* imp =  {{v8_class}}::toNative(host);
93     return BindingSecurity::shouldAllowAccessToFrame(imp->frame(), DoNotReportSecurityError);
94 }
95 
96 {% endif %}
97 {% endblock %}
98 
99 
100 {##############################################################################}
101 {% block origin_safe_method_setter %}
102 {% if has_origin_safe_method_setter %}
103 static void {{cpp_class}}OriginSafeMethodSetter(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
104 {
105     {# FIXME: don't call GetIsolate 3 times #}
106     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
107     if (holder.IsEmpty())
108         return;
109     {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
110     v8::String::Utf8Value attributeName(name);
111     ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
112     if (!BindingSecurity::shouldAllowAccessToFrame(imp->frame(), exceptionState)) {
113         exceptionState.throwIfNeeded();
114         return;
115     }
116 
117     info.This()->SetHiddenValue(name, jsValue);
118 }
119 
120 static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> name, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info)
121 {
122     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
123     {{cpp_class}}V8Internal::{{cpp_class}}OriginSafeMethodSetter(name, jsValue, info);
124     TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
125 }
126 
127 {% endif %}
128 {% endblock %}
129 
130 
131 {##############################################################################}
132 {% from 'methods.cpp' import named_constructor_callback with context %}
133 {% block named_constructor %}
134 {% if named_constructor %}
135 {% set to_active_dom_object = '%s::toActiveDOMObject' % v8_class
136                               if is_active_dom_object else '0' %}
137 const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::derefObject, {{to_active_dom_object}}, 0, 0, {{v8_class}}::installPerContextEnabledMethods, 0, WrapperTypeObjectPrototype };
138 
139 {{named_constructor_callback(named_constructor)}}
140 v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
141 {
142     // This is only for getting a unique pointer which we can pass to privateTemplate.
143     static int privateTemplateUniqueKey;
144     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
145     v8::Local<v8::FunctionTemplate> result = data->privateTemplateIfExists(currentWorldType, &privateTemplateUniqueKey);
146     if (!result.IsEmpty())
147         return result;
148 
149     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
150     v8::EscapableHandleScope scope(isolate);
151     result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
152 
153     v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
154     instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
155     result->SetClassName(v8::String::NewFromUtf8(isolate, "{{cpp_class}}", v8::String::kInternalizedString));
156     result->Inherit({{v8_class}}::domTemplate(isolate, currentWorldType));
157     data->setPrivateTemplate(currentWorldType, &privateTemplateUniqueKey, result);
158 
159     return scope.Escape(result);
160 }
161 
162 {% endif %}
163 {% endblock %}
164 
165 {##############################################################################}
166 {% block overloaded_constructor %}
167 {% if constructors|length > 1 %}
168 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
169 {
170     {% for constructor in constructors %}
171     if ({{constructor.overload_resolution_expression}}) {
172         {{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
173         return;
174     }
175     {% endfor %}
176     {% if interface_length %}
177     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
178     if (UNLIKELY(info.Length() < {{interface_length}})) {
179         exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{interface_length}}, info.Length()));
180         exceptionState.throwIfNeeded();
181         return;
182     }
183     exceptionState.throwTypeError("No matching constructor signature.");
184     exceptionState.throwIfNeeded();
185     {% else %}
186     throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "No matching constructor signature."), info.GetIsolate());
187     {% endif %}
188 }
189 
190 {% endif %}
191 {% endblock %}
192 
193 
194 {##############################################################################}
195 {% block event_constructor %}
196 {% if has_event_constructor %}
197 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
198 {
199     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
200     if (info.Length() < 1) {
201         exceptionState.throwTypeError("An event name must be provided.");
202         exceptionState.throwIfNeeded();
203         return;
204     }
205 
206     V8TRYCATCH_FOR_V8STRINGRESOURCE_VOID(V8StringResource<>, type, info[0]);
207     {% for attribute in any_type_attributes %}
208     v8::Local<v8::Value> {{attribute.name}};
209     {% endfor %}
210     {{cpp_class}}Init eventInit;
211     if (info.Length() >= 2) {
212         V8TRYCATCH_VOID(Dictionary, options, Dictionary(info[1], info.GetIsolate()));
213         if (!initialize{{cpp_class}}(eventInit, options, exceptionState)) {
214             exceptionState.throwIfNeeded();
215             return;
216         }
217         {# Store attributes of type |any| on the wrapper to avoid leaking them
218            between isolated worlds. #}
219         {% for attribute in any_type_attributes %}
220         options.get("{{attribute.name}}", {{attribute.name}});
221         if (!{{attribute.name}}.IsEmpty())
222             info.Holder()->SetHiddenValue(V8HiddenPropertyName::{{attribute.name}}(info.GetIsolate()), {{attribute.name}});
223         {% endfor %}
224     }
225     {% if is_constructor_raises_exception %}
226     RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit, exceptionState);
227     if (exceptionState.throwIfNeeded())
228         return;
229     {% else %}
230     RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit);
231     {% endif %}
232     {% if any_type_attributes and not interface_name == 'ErrorEvent' %}
233     {# If we're in an isolated world, create a SerializedScriptValue and store
234        it in the event for later cloning if the property is accessed from
235        another world. The main world case is handled lazily (in custom code).
236 
237        We do not clone Error objects (exceptions), for 2 reasons:
238        1) Errors carry a reference to the isolated world's global object, and
239           thus passing it around would cause leakage.
240        2) Errors cannot be cloned (or serialized):
241        http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#safe-passing-of-structured-data #}
242     if (isolatedWorldForIsolate(info.GetIsolate())) {
243         {% for attribute in any_type_attributes %}
244         if (!{{attribute.name}}.IsEmpty())
245             event->setSerialized{{attribute.name | blink_capitalize}}(SerializedScriptValue::createAndSwallowExceptions({{attribute.name}}, info.GetIsolate()));
246         {% endfor %}
247     }
248 
249     {% endif %}
250     v8::Handle<v8::Object> wrapper = info.Holder();
251     V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(event.release(), &{{v8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate(), WrapperConfiguration::Dependent);
252     v8SetReturnValue(info, wrapper);
253 }
254 
255 {% endif %}
256 {% endblock %}
257 
258 
259 {##############################################################################}
260 {% block visit_dom_wrapper %}
261 {% if generate_visit_dom_wrapper_function %}
262 void {{v8_class}}::visitDOMWrapper(void* object, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
263 {
264     {{cpp_class}}* impl = fromInternalPointer(object);
265     if (Node* owner = impl->{{generate_visit_dom_wrapper_function}}()) {
266         setObjectGroup(V8GCController::opaqueRootForGC(owner, isolate), wrapper, isolate);
267         return;
268     }
269     setObjectGroup(object, wrapper, isolate);
270 }
271 
272 {% endif %}
273 {% endblock %}
274 
275 
276 {##############################################################################}
277 {% block class_attributes %}
278 {# FIXME: rename to install_attributes and put into configure_class_template #}
279 {% if attributes %}
280 static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[] = {
281     {% for attribute in attributes
282        if not (attribute.is_expose_js_accessors or
283                attribute.is_static or
284                attribute.runtime_enabled_function or
285                attribute.per_context_enabled_function) %}
286     {% filter conditional(attribute.conditional_string) %}
287     {{attribute_configuration(attribute)}},
288     {% endfilter %}
289     {% endfor %}
290 };
291 
292 {% endif %}
293 {% endblock %}
294 
295 
296 {##############################################################################}
297 {% block class_accessors %}
298 {# FIXME: rename install_accessors and put into configure_class_template #}
299 {% if has_accessors %}
300 static const V8DOMConfiguration::AccessorConfiguration {{v8_class}}Accessors[] = {
301     {% for attribute in attributes if attribute.is_expose_js_accessors %}
302     {{attribute_configuration(attribute)}},
303     {% endfor %}
304 };
305 
306 {% endif %}
307 {% endblock %}
308 
309 
310 {##############################################################################}
311 {% block class_methods %}
312 {# FIXME: rename to install_methods and put into configure_class_template #}
313 {% if has_method_configuration %}
314 static const V8DOMConfiguration::MethodConfiguration {{v8_class}}Methods[] = {
315     {% for method in methods if method.do_generate_method_configuration %}
316     {% filter conditional(method.conditional_string) %}
317     {{method_configuration(method)}},
318     {% endfilter %}
319     {% endfor %}
320 };
321 
322 {% endif %}
323 {% endblock %}
324 
325 
326 {##############################################################################}
327 {% block initialize_event %}
328 {% if has_event_constructor %}
329 bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& options, ExceptionState& exceptionState, const String& forEventName)
330 {
331     Dictionary::ConversionContext conversionContext(forEventName.isEmpty() ? String("{{interface_name}}") : forEventName, "", exceptionState);
332     {% if parent_interface %}{# any Event interface except Event itself #}
333     if (!initialize{{parent_interface}}(eventInit, options, exceptionState, forEventName.isEmpty() ? String("{{interface_name}}") : forEventName))
334         return false;
335 
336     {% endif %}
337     {% for attribute in attributes
338            if (attribute.is_initialized_by_event_constructor and
339                not attribute.idl_type == 'any')%}
340     {% set is_nullable = 'true' if attribute.is_nullable else 'false' %}
341     {% if attribute.deprecate_as %}
342     if (options.convert(conversionContext.setConversionType("{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{attribute.cpp_name}})) {
343         if (options.hasProperty("{{attribute.name}}"))
344             UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
345     } else {
346         return false;
347     }
348     {% else %}
349     if (!options.convert(conversionContext.setConversionType("{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{attribute.cpp_name}}))
350         return false;
351     {% endif %}
352     {% endfor %}
353     return true;
354 }
355 
356 {% endif %}
357 {% endblock %}
358 
359 
360 {##############################################################################}
361 {% block constructor_callback %}
362 {% if constructors or has_custom_constructor or has_event_constructor %}
363 void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
364 {
365     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "DOMConstructor");
366     {% if measure_as %}
367     UseCounter::count(activeDOMWindow(), UseCounter::{{measure_as}});
368     {% endif %}
369     if (!info.IsConstructCall()) {
370         throwTypeError(ExceptionMessages::failedToConstruct("{{interface_name}}", "Please use the 'new' operator, this DOM object constructor cannot be called as a function."), info.GetIsolate());
371         return;
372     }
373 
374     if (ConstructorMode::current() == ConstructorMode::WrapExistingObject) {
375         v8SetReturnValue(info, info.Holder());
376         return;
377     }
378 
379     {% if has_custom_constructor %}
380     {{v8_class}}::constructorCustom(info);
381     {% else %}
382     {{cpp_class}}V8Internal::constructor(info);
383     {% endif %}
384 }
385 
386 {% endif %}
387 {% endblock %}
388 
389 
390 {##############################################################################}
391 {% block configure_class_template %}
392 {# FIXME: rename to install_dom_template and Install{{v8_class}}DOMTemplate #}
393 static v8::Handle<v8::FunctionTemplate> Configure{{v8_class}}Template(v8::Handle<v8::FunctionTemplate> functionTemplate, v8::Isolate* isolate, WrapperWorldType currentWorldType)
394 {
395     functionTemplate->ReadOnlyPrototype();
396 
397     v8::Local<v8::Signature> defaultSignature;
398     {% set parent_template =
399            'V8%s::domTemplate(isolate, currentWorldType)' % parent_interface
400            if parent_interface else 'v8::Local<v8::FunctionTemplate>()' %}
401     {% if runtime_enabled_function %}
402     if (!{{runtime_enabled_function}}())
403         defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "", {{parent_template}}, {{v8_class}}::internalFieldCount, 0, 0, 0, 0, 0, 0, isolate, currentWorldType);
404     else
405     {% endif %}
406     {% set runtime_enabled_indent = 4 if runtime_enabled_function else 0 %}
407     {% filter indent(runtime_enabled_indent, true) %}
408     defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTemplate, "{{interface_name}}", {{parent_template}}, {{v8_class}}::internalFieldCount,
409         {# Test needed as size 0 constant arrays are not allowed in VC++ #}
410         {% set attributes_name, attributes_length =
411                ('%sAttributes' % v8_class,
412                 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class)
413            if attributes else (0, 0) %}
414         {% set accessors_name, accessors_length =
415                ('%sAccessors' % v8_class,
416                 'WTF_ARRAY_LENGTH(%sAccessors)' % v8_class)
417            if has_accessors else (0, 0) %}
418         {% set methods_name, methods_length =
419                ('%sMethods' % v8_class,
420                 'WTF_ARRAY_LENGTH(%sMethods)' % v8_class)
421            if has_method_configuration else (0, 0) %}
422         {{attributes_name}}, {{attributes_length}},
423         {{accessors_name}}, {{accessors_length}},
424         {{methods_name}}, {{methods_length}},
425         isolate, currentWorldType);
426     {% endfilter %}
427 
428     {% if constructors or has_custom_constructor or has_event_constructor %}
429     functionTemplate->SetCallHandler({{v8_class}}::constructorCallback);
430     functionTemplate->SetLength({{interface_length}});
431     {% endif %}
432     v8::Local<v8::ObjectTemplate> ALLOW_UNUSED instanceTemplate = functionTemplate->InstanceTemplate();
433     v8::Local<v8::ObjectTemplate> ALLOW_UNUSED prototypeTemplate = functionTemplate->PrototypeTemplate();
434     {% if is_check_security and interface_name != 'Window' %}
435     instanceTemplate->SetAccessCheckCallbacks({{cpp_class}}V8Internal::namedSecurityCheck, {{cpp_class}}V8Internal::indexedSecurityCheck, v8::External::New(isolate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperTypeInfo)));
436     {% endif %}
437     {% for attribute in attributes if attribute.runtime_enabled_function %}
438     {% filter conditional(attribute.conditional_string) %}
439     if ({{attribute.runtime_enabled_function}}()) {
440         static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\
441         {{attribute_configuration(attribute)}};
442         V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate, currentWorldType);
443     }
444     {% endfilter %}
445     {% endfor %}
446     {% if constants %}
447     {{install_constants() | indent}}
448     {% endif %}
449     {% for method in methods if not method.do_not_check_signature %}
450     {% if method.custom_signature and not method.overload_index %}
451     {# No custom signature needed for overloaded methods;
452        separate check because depends on global check for overloads #}
453 
454     // Custom Signature '{{method.name}}'
455     const int {{method.name}}Argc = {{method.arguments | length}};
456     v8::Handle<v8::FunctionTemplate> {{method.name}}Argv[{{method.name}}Argc] = { {{method.custom_signature}} };
457     v8::Handle<v8::Signature> {{method.name}}Signature = v8::Signature::New(isolate, functionTemplate, {{method.name}}Argc, {{method.name}}Argv);
458     {% endif %}
459     {# install_custom_signature #}
460     {% if not method.overload_index or method.overload_index == 1 %}
461     {# For overloaded methods, only generate one accessor #}
462     {% filter conditional(method.conditional_string) %}
463     {% if method.is_do_not_check_security %}
464     {% if method.is_per_world_bindings %}
465     if (currentWorldType == MainWorld) {
466         {{install_do_not_check_security_signature(method, 'ForMainWorld')}}
467     } else {
468         {{install_do_not_check_security_signature(method)}}
469     }
470     {% else %}
471     {{install_do_not_check_security_signature(method)}}
472     {% endif %}
473     {% else %}{# is_do_not_check_security #}
474     {% if method.is_per_world_bindings %}
475     if (currentWorldType == MainWorld) {
476         {% filter runtime_enabled(method.runtime_enabled_function) %}
477         {{install_custom_signature(method, 'ForMainWorld')}}
478         {% endfilter %}
479     } else {
480         {% filter runtime_enabled(method.runtime_enabled_function) %}
481         {{install_custom_signature(method)}}
482         {% endfilter %}
483     }
484     {% else %}
485     {% filter runtime_enabled(method.runtime_enabled_function) %}
486     {{install_custom_signature(method)}}
487     {% endfilter %}
488     {% endif %}
489     {% endif %}{# is_do_not_check_security #}
490     {% endfilter %}
491     {% endif %}{# install_custom_signature #}
492     {% endfor %}
493     {% for attribute in attributes if attribute.is_static %}
494     {% set getter_callback = '%sV8Internal::%sAttributeGetterCallback' %
495            (interface_name, attribute.name) %}
496     functionTemplate->SetNativeDataProperty(v8::String::NewFromUtf8(isolate, "{{attribute.name}}", v8::String::kInternalizedString), {{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));
497     {% endfor %}
498     {% if has_custom_legacy_call_as_function %}
499     functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler({{v8_class}}::legacyCallCustom);
500     {% endif %}
501     {% if interface_name == 'HTMLAllCollection' %}
502     {# Needed for legacy support of document.all #}
503     functionTemplate->InstanceTemplate()->MarkAsUndetectable();
504     {% endif %}
505 
506     // Custom toString template
507     functionTemplate->Set(v8::String::NewFromUtf8(isolate, "toString", v8::String::kInternalizedString), V8PerIsolateData::current()->toStringTemplate());
508     return functionTemplate;
509 }
510 
511 {% endblock %}
512 
513 
514 {######################################}
515 {% macro install_do_not_check_security_signature(method, world_suffix) %}
516 {# FIXME: move to V8DOMConfiguration::installDOMCallbacksWithDoNotCheckSecuritySignature #}
517 {# Methods that are [DoNotCheckSecurity] are always readable, but if they are
518    changed and then accessed from a different origin, we do not return the
519    underlying value, but instead return a new copy of the original function.
520    This is achieved by storing the changed value as a hidden property. #}
521 {% set getter_callback =
522        '%sV8Internal::%sOriginSafeMethodGetterCallback%s' %
523        (cpp_class, method.name, world_suffix) %}
524 {% set setter_callback =
525     '{0}V8Internal::{0}OriginSafeMethodSetterCallback'.format(cpp_class)
526     if not method.is_read_only else '0' %}
527 {% set property_attribute =
528     'static_cast<v8::PropertyAttribute>(%s)' %
529     ' | '.join(method.property_attributes or ['v8::DontDelete']) %}
530 {{method.function_template}}->SetAccessor(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), {{getter_callback}}, {{setter_callback}}, v8Undefined(), v8::ALL_CAN_READ, {{property_attribute}});
531 {%- endmacro %}
532 
533 
534 {######################################}
535 {% macro install_custom_signature(method, world_suffix) %}
536 {# FIXME: move to V8DOMConfiguration::installDOMCallbacksWithCustomSignature #}
537 {% set method_callback = '%sV8Internal::%sMethodCallback%s' %
538                          (interface_name, method.name, world_suffix) %}
539 {% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' %
540                             ' | '.join(method.property_attributes) %}
541 {{method.function_template}}->Set(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, {{method_callback}}, v8Undefined(), {{method.signature}}, {{method.number_of_required_or_variadic_arguments}}){% if method.property_attributes %}, {{property_attribute}}{% endif %});
542 {%- endmacro %}
543 
544 
545 {######################################}
546 {% macro install_constants() %}
547 {# FIXME: should use reflected_name instead of name #}
548 {# Normal (always enabled) constants #}
549 static const V8DOMConfiguration::ConstantConfiguration {{v8_class}}Constants[] = {
550     {% for constant in constants if not constant.runtime_enabled_function %}
551     {"{{constant.name}}", {{constant.value}}},
552     {% endfor %}
553 };
554 V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, {{v8_class}}Constants, WTF_ARRAY_LENGTH({{v8_class}}Constants), isolate);
555 {# Runtime-enabled constants #}
556 {% for constant in constants if constant.runtime_enabled_function %}
557 if ({{constant.runtime_enabled_function}}()) {
558     static const V8DOMConfiguration::ConstantConfiguration constantConfiguration = {"{{constant.name}}", static_cast<signed int>({{constant.value}})};
559     V8DOMConfiguration::installConstants(functionTemplate, prototypeTemplate, &constantConfiguration, 1, isolate);
560 }
561 {% endfor %}
562 {# Check constants #}
563 {% if not do_not_check_constants %}
564 {% for constant in constants %}
565 COMPILE_ASSERT({{constant.value}} == {{cpp_class}}::{{constant.reflected_name}}, TheValueOf{{cpp_class}}_{{constant.reflected_name}}DoesntMatchWithImplementation);
566 {% endfor %}
567 {% endif %}
568 {% endmacro %}
569 
570 
571 {##############################################################################}
572 {% block get_template %}
573 {# FIXME: rename to get_dom_template and GetDOMTemplate #}
574 v8::Handle<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate, WrapperWorldType currentWorldType)
575 {
576     V8PerIsolateData* data = V8PerIsolateData::from(isolate);
577     V8PerIsolateData::TemplateMap::iterator result = data->templateMap(currentWorldType).find(&wrapperTypeInfo);
578     if (result != data->templateMap(currentWorldType).end())
579         return result->value.newLocal(isolate);
580 
581     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "BuildDOMTemplate");
582     v8::EscapableHandleScope handleScope(isolate);
583     v8::Local<v8::FunctionTemplate> templ =
584         Configure{{v8_class}}Template(data->rawDOMTemplate(&wrapperTypeInfo, currentWorldType), isolate, currentWorldType);
585     data->templateMap(currentWorldType).add(&wrapperTypeInfo, UnsafePersistent<v8::FunctionTemplate>(isolate, templ));
586     return handleScope.Escape(templ);
587 }
588 
589 {% endblock %}
590 
591 
592 {##############################################################################}
593 {% block has_instance_and_has_instance_in_any_world %}
594 bool {{v8_class}}::hasInstance(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate, WrapperWorldType currentWorldType)
595 {
596     return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, currentWorldType);
597 }
598 
599 bool {{v8_class}}::hasInstanceInAnyWorld(v8::Handle<v8::Value> jsValue, v8::Isolate* isolate)
600 {
601     return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, MainWorld)
602         || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, IsolatedWorld)
603         || V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, jsValue, WorkerWorld);
604 }
605 
606 {% endblock %}
607 
608 
609 {##############################################################################}
610 {% block install_per_context_attributes %}
611 {% if has_per_context_enabled_attributes %}
612 void {{v8_class}}::installPerContextEnabledProperties(v8::Handle<v8::Object> instanceTemplate, {{cpp_class}}* impl, v8::Isolate* isolate)
613 {
614     v8::Local<v8::Object> prototypeTemplate = v8::Local<v8::Object>::Cast(instanceTemplate->GetPrototype());
615     {% for attribute in attributes if attribute.per_context_enabled_function %}
616     if ({{attribute.per_context_enabled_function}}(impl->document())) {
617         static const V8DOMConfiguration::AttributeConfiguration attributeConfiguration =\
618         {{attribute_configuration(attribute)}};
619         V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate, attributeConfiguration, isolate);
620     }
621     {% endfor %}
622 }
623 
624 {% endif %}
625 {% endblock %}
626 
627 
628 {##############################################################################}
629 {% block install_per_context_methods %}
630 {% if has_per_context_enabled_methods %}
631 void {{v8_class}}::installPerContextEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate)
632 {
633     {# Define per-context enabled operations #}
634     v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate, worldType(isolate)));
635 
636     ExecutionContext* context = toExecutionContext(prototypeTemplate->CreationContext());
637     {% for method in methods if method.per_context_enabled_function %}
638     if (context && context->isDocument() && {{method.per_context_enabled_function}}(toDocument(context)))
639         prototypeTemplate->Set(v8::String::NewFromUtf8(isolate, "{{method.name}}", v8::String::kInternalizedString), v8::FunctionTemplate::New(isolate, {{cpp_class}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());
640     {% endfor %}
641 }
642 
643 {% endif %}
644 {% endblock %}
645 
646 
647 {##############################################################################}
648 {% block to_active_dom_object %}
649 {% if is_active_dom_object %}
650 ActiveDOMObject* {{v8_class}}::toActiveDOMObject(v8::Handle<v8::Object> wrapper)
651 {
652     return toNative(wrapper);
653 }
654 
655 {% endif %}
656 {% endblock %}
657 
658 
659 {##############################################################################}
660 {% block to_event_target %}
661 {% if is_event_target %}
662 EventTarget* {{v8_class}}::toEventTarget(v8::Handle<v8::Object> object)
663 {
664     return toNative(object);
665 }
666 
667 {% endif %}
668 {% endblock %}
669 
670 
671 {##############################################################################}
672 {% block wrap %}
673 {% if special_wrap_for %}
674 v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
675 {
676     ASSERT(impl);
677     {% for special_wrap_interface in special_wrap_for %}
678     if (impl->is{{special_wrap_interface}}())
679         return wrap(to{{special_wrap_interface}}(impl), creationContext, isolate);
680     {% endfor %}
681     v8::Handle<v8::Object> wrapper = {{v8_class}}::createWrapper(impl, creationContext, isolate);
682     return wrapper;
683 }
684 
685 {% endif %}
686 {% endblock %}
687 
688 
689 {##############################################################################}
690 {% block create_wrapper %}
691 {% if not has_custom_to_v8 %}
692 v8::Handle<v8::Object> {{v8_class}}::createWrapper(PassRefPtr<{{cpp_class}}> impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
693 {
694     ASSERT(impl);
695     ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl.get(), isolate));
696     if (ScriptWrappable::wrapperCanBeStoredInObject(impl.get())) {
697         const WrapperTypeInfo* actualInfo = ScriptWrappable::getTypeInfoFromObject(impl.get());
698         // Might be a XXXConstructor::wrapperTypeInfo instead of an XXX::wrapperTypeInfo. These will both have
699         // the same object de-ref functions, though, so use that as the basis of the check.
700         RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction == wrapperTypeInfo.derefObjectFunction);
701     }
702 
703     v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext, &wrapperTypeInfo, toInternalPointer(impl.get()), isolate);
704     if (UNLIKELY(wrapper.IsEmpty()))
705         return wrapper;
706 
707     installPerContextEnabledProperties(wrapper, impl.get(), isolate);
708     {% set wrapper_configuration = 'WrapperConfiguration::Dependent'
709                                    if (has_visit_dom_wrapper or
710                                        is_active_dom_object or
711                                        is_dependent_lifetime) else
712                                    'WrapperConfiguration::Independent' %}
713     V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl, &wrapperTypeInfo, wrapper, isolate, {{wrapper_configuration}});
714     return wrapper;
715 }
716 
717 {% endif %}
718 {% endblock %}
719 
720 
721 {##############################################################################}
722 {% block deref_object_and_to_v8_no_inline %}
723 void {{v8_class}}::derefObject(void* object)
724 {
725     fromInternalPointer(object)->deref();
726 }
727 
728 template<>
729 v8::Handle<v8::Value> toV8NoInline({{cpp_class}}* impl, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
730 {
731     return toV8(impl, creationContext, isolate);
732 }
733 
734 {% endblock %}
735