Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / bindings / templates / interface.cpp
blob33be1e4b5eec5643d2e72dc1c0914855de23159e
1 {% extends 'interface_base.cpp' %}
4 {##############################################################################}
5 {% block indexed_property_getter %}
6 {% if indexed_property_getter and not indexed_property_getter.is_custom %}
7 {% set getter = indexed_property_getter %}
8 static void indexedPropertyGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
10 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
11 {% if getter.is_raises_exception %}
12 ExceptionState exceptionState(ExceptionState::IndexedGetterContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
13 {% endif %}
14 {% set getter_name = getter.name or 'anonymousIndexedGetter' %}
15 {% set getter_arguments = ['index'] %}
16 {% if getter.is_call_with_script_state %}
17 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
18 {% set getter_arguments = ['scriptState'] + getter_arguments %}
19 {% endif %}
20 {% if getter.is_raises_exception %}
21 {% set getter_arguments = getter_arguments + ['exceptionState'] %}
22 {% endif %}
23 {{getter.cpp_type}} result = impl->{{getter_name}}({{getter_arguments | join(', ')}});
24 {% if getter.is_raises_exception %}
25 if (exceptionState.throwIfNeeded())
26 return;
27 {% endif %}
28 if ({{getter.is_null_expression}})
29 return;
30 {{getter.v8_set_return_value}};
33 {% endif %}
34 {% endblock %}
37 {##############################################################################}
38 {% block indexed_property_getter_callback %}
39 {% if indexed_property_getter %}
40 {% set getter = indexed_property_getter %}
41 static void indexedPropertyGetterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info)
43 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMIndexedProperty");
44 {% if getter.is_custom %}
45 {{v8_class}}::indexedPropertyGetterCustom(index, info);
46 {% else %}
47 {{cpp_class}}V8Internal::indexedPropertyGetter(index, info);
48 {% endif %}
49 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
52 {% endif %}
53 {% endblock %}
56 {##############################################################################}
57 {% block indexed_property_setter %}
58 {% from 'conversions.cpp' import v8_value_to_local_cpp_value %}
59 {% if indexed_property_setter and not indexed_property_setter.is_custom %}
60 {% set setter = indexed_property_setter %}
61 static void indexedPropertySetter(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
63 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
64 {{v8_value_to_local_cpp_value(setter) | indent}}
65 {% if setter.has_exception_state %}
66 ExceptionState exceptionState(ExceptionState::IndexedSetterContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
67 {% endif %}
68 {% if setter.has_type_checking_interface %}
69 {# Type checking for interface types (if interface not implemented, throw
70 TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
71 if (!propertyValue{% if setter.is_nullable %} && !isUndefinedOrNull(v8Value){% endif %}) {
72 exceptionState.throwTypeError("The provided value is not of type '{{setter.idl_type}}'.");
73 exceptionState.throwIfNeeded();
74 return;
76 {% endif %}
77 {% set setter_name = setter.name or 'anonymousIndexedSetter' %}
78 {% set setter_arguments = ['index', 'propertyValue'] %}
79 {% if setter.is_call_with_script_state %}
80 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
81 {% set setter_arguments = ['scriptState'] + setter_arguments %}
82 {% endif %}
83 {% if setter.is_raises_exception %}
84 {% set setter_arguments = setter_arguments + ['exceptionState'] %}
85 {% endif %}
86 bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
87 {% if setter.is_raises_exception %}
88 if (exceptionState.throwIfNeeded())
89 return;
90 {% endif %}
91 if (!result)
92 return;
93 v8SetReturnValue(info, v8Value);
96 {% endif %}
97 {% endblock %}
100 {##############################################################################}
101 {% block indexed_property_setter_callback %}
102 {% if indexed_property_setter %}
103 {% set setter = indexed_property_setter %}
104 static void indexedPropertySetterCallback(uint32_t index, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
106 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMIndexedProperty");
107 {% if setter.is_custom %}
108 {{v8_class}}::indexedPropertySetterCustom(index, v8Value, info);
109 {% else %}
110 {{cpp_class}}V8Internal::indexedPropertySetter(index, v8Value, info);
111 {% endif %}
112 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
115 {% endif %}
116 {% endblock %}
119 {##############################################################################}
120 {% block indexed_property_deleter %}
121 {% if indexed_property_deleter and not indexed_property_deleter.is_custom %}
122 {% set deleter = indexed_property_deleter %}
123 static void indexedPropertyDeleter(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
125 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
126 {% if deleter.is_raises_exception %}
127 ExceptionState exceptionState(ExceptionState::IndexedDeletionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
128 {% endif %}
129 {% set deleter_name = deleter.name or 'anonymousIndexedDeleter' %}
130 {% set deleter_arguments = ['index'] %}
131 {% if deleter.is_call_with_script_state %}
132 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
133 {% set deleter_arguments = ['scriptState'] + deleter_arguments %}
134 {% endif %}
135 {% if deleter.is_raises_exception %}
136 {% set deleter_arguments = deleter_arguments + ['exceptionState'] %}
137 {% endif %}
138 DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
139 {% if deleter.is_raises_exception %}
140 if (exceptionState.throwIfNeeded())
141 return;
142 {% endif %}
143 if (result != DeleteUnknownProperty)
144 return v8SetReturnValueBool(info, result == DeleteSuccess);
147 {% endif %}
148 {% endblock %}
151 {##############################################################################}
152 {% block indexed_property_deleter_callback %}
153 {% if indexed_property_deleter %}
154 {% set deleter = indexed_property_deleter %}
155 static void indexedPropertyDeleterCallback(uint32_t index, const v8::PropertyCallbackInfo<v8::Boolean>& info)
157 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMIndexedProperty");
158 {% if deleter.is_custom %}
159 {{v8_class}}::indexedPropertyDeleterCustom(index, info);
160 {% else %}
161 {{cpp_class}}V8Internal::indexedPropertyDeleter(index, info);
162 {% endif %}
163 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
166 {% endif %}
167 {% endblock %}
170 {##############################################################################}
171 {% block named_property_getter %}
172 {% if named_property_getter and not named_property_getter.is_custom %}
173 {% set getter = named_property_getter %}
174 static void namedPropertyGetter(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info)
176 auto nameString = name.As<v8::String>();
177 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
178 AtomicString propertyName = toCoreAtomicString(nameString);
179 {% if getter.is_raises_exception %}
180 v8::String::Utf8Value namedProperty(nameString);
181 ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
182 {% endif %}
183 {% if getter.is_call_with_script_state %}
184 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
185 {% endif %}
186 {% if getter.use_output_parameter_for_result %}
187 {{getter.cpp_type}} result;
188 {{getter.cpp_value}};
189 {% else %}
190 {{getter.cpp_type}} result = {{getter.cpp_value}};
191 {% endif %}
192 {% if getter.is_raises_exception %}
193 if (exceptionState.throwIfNeeded())
194 return;
195 {% endif %}
196 if ({{getter.is_null_expression}})
197 return;
198 {{getter.v8_set_return_value}};
201 {% endif %}
202 {% endblock %}
205 {##############################################################################}
206 {% block named_property_getter_callback %}
207 {% if named_property_getter %}
208 {% set getter = named_property_getter %}
209 static void namedPropertyGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info)
211 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMNamedProperty");
212 {% if getter.is_custom %}
213 {{v8_class}}::namedPropertyGetterCustom(name, info);
214 {% else %}
215 {{cpp_class}}V8Internal::namedPropertyGetter(name, info);
216 {% endif %}
217 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
220 {% endif %}
221 {% endblock %}
224 {##############################################################################}
225 {% block named_property_setter %}
226 {% from 'conversions.cpp' import v8_value_to_local_cpp_value %}
227 {% if named_property_setter and not named_property_setter.is_custom %}
228 {% set setter = named_property_setter %}
229 static void namedPropertySetter(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
231 auto nameString = name.As<v8::String>();
232 {% if setter.has_exception_state %}
233 v8::String::Utf8Value namedProperty(nameString);
234 ExceptionState exceptionState(ExceptionState::SetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
235 {% endif %}
236 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
237 {# v8_value_to_local_cpp_value('DOMString', 'nameString', 'propertyName') #}
238 V8StringResource<> propertyName(nameString);
239 if (!propertyName.prepare())
240 return;
241 {{v8_value_to_local_cpp_value(setter) | indent}}
242 {% if setter.has_type_checking_interface %}
243 {# Type checking for interface types (if interface not implemented, throw
244 TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
245 if (!propertyValue{% if setter.is_nullable %} && !isUndefinedOrNull(v8Value){% endif %}) {
246 exceptionState.throwTypeError("The provided value is not of type '{{setter.idl_type}}'.");
247 exceptionState.throwIfNeeded();
248 return;
250 {% endif %}
251 {% if setter.is_call_with_script_state %}
252 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
253 {% endif %}
254 {% set setter_name = setter.name or 'anonymousNamedSetter' %}
255 {% set setter_arguments = ['propertyName', 'propertyValue'] %}
256 {% if setter.is_call_with_script_state %}
257 {% set setter_arguments = ['scriptState'] + setter_arguments %}
258 {% endif %}
259 {% if setter.is_raises_exception %}
260 {% set setter_arguments = setter_arguments + ['exceptionState'] %}
261 {% endif %}
262 bool result = impl->{{setter_name}}({{setter_arguments | join(', ')}});
263 {% if setter.is_raises_exception %}
264 if (exceptionState.throwIfNeeded())
265 return;
266 {% endif %}
267 if (!result)
268 return;
269 v8SetReturnValue(info, v8Value);
272 {% endif %}
273 {% endblock %}
276 {##############################################################################}
277 {% block named_property_setter_callback %}
278 {% if named_property_setter %}
279 {% set setter = named_property_setter %}
280 static void namedPropertySetterCallback(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<v8::Value>& info)
282 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMNamedProperty");
283 {% if setter.is_custom %}
284 {{v8_class}}::namedPropertySetterCustom(name, v8Value, info);
285 {% else %}
286 {{cpp_class}}V8Internal::namedPropertySetter(name, v8Value, info);
287 {% endif %}
288 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
291 {% endif %}
292 {% endblock %}
295 {##############################################################################}
296 {% block named_property_query %}
297 {% if named_property_getter and named_property_getter.is_enumerable and
298 not named_property_getter.is_custom_property_query %}
299 {% set getter = named_property_getter %}
300 {# If there is an enumerator, there MUST be a query method to properly
301 communicate property attributes. #}
302 static void namedPropertyQuery(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
304 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
305 AtomicString propertyName = toCoreAtomicString(name.As<v8::String>());
306 v8::String::Utf8Value namedProperty(name);
307 ExceptionState exceptionState(ExceptionState::GetterContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
308 {% set getter_arguments = ['propertyName', 'exceptionState'] %}
309 {% if getter.is_call_with_script_state %}
310 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
311 {% set getter_arguments = ['scriptState'] + getter_arguments %}
312 {% endif %}
313 bool result = impl->namedPropertyQuery({{getter_arguments | join(', ')}});
314 if (exceptionState.throwIfNeeded())
315 return;
316 if (!result)
317 return;
318 v8SetReturnValueInt(info, v8::None);
321 {% endif %}
322 {% endblock %}
325 {##############################################################################}
326 {% block named_property_query_callback %}
327 {% if named_property_getter and named_property_getter.is_enumerable %}
328 {% set getter = named_property_getter %}
329 static void namedPropertyQueryCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Integer>& info)
331 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMNamedProperty");
332 {% if getter.is_custom_property_query %}
333 {{v8_class}}::namedPropertyQueryCustom(name, info);
334 {% else %}
335 {{cpp_class}}V8Internal::namedPropertyQuery(name, info);
336 {% endif %}
337 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
340 {% endif %}
341 {% endblock %}
344 {##############################################################################}
345 {% block named_property_deleter %}
346 {% if named_property_deleter and not named_property_deleter.is_custom %}
347 {% set deleter = named_property_deleter %}
348 static void namedPropertyDeleter(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
350 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
351 AtomicString propertyName = toCoreAtomicString(name.As<v8::String>());
352 {% if deleter.is_raises_exception %}
353 v8::String::Utf8Value namedProperty(name);
354 ExceptionState exceptionState(ExceptionState::DeletionContext, *namedProperty, "{{interface_name}}", info.Holder(), info.GetIsolate());
355 {% endif %}
356 {% if deleter.is_call_with_script_state %}
357 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
358 {% endif %}
359 {% set deleter_name = deleter.name or 'anonymousNamedDeleter' %}
360 {% set deleter_arguments = ['propertyName'] %}
361 {% if deleter.is_call_with_script_state %}
362 {% set deleter_arguments = ['scriptState'] + deleter_arguments %}
363 {% endif %}
364 {% if deleter.is_raises_exception %}
365 {% set deleter_arguments = deleter_arguments + ['exceptionState'] %}
366 {% endif %}
367 DeleteResult result = impl->{{deleter_name}}({{deleter_arguments | join(', ')}});
368 {% if deleter.is_raises_exception %}
369 if (exceptionState.throwIfNeeded())
370 return;
371 {% endif %}
372 if (result != DeleteUnknownProperty)
373 return v8SetReturnValueBool(info, result == DeleteSuccess);
376 {% endif %}
377 {% endblock %}
380 {##############################################################################}
381 {% block named_property_deleter_callback %}
382 {% if named_property_deleter %}
383 {% set deleter = named_property_deleter %}
384 static void namedPropertyDeleterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Boolean>& info)
386 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMNamedProperty");
387 {% if deleter.is_custom %}
388 {{v8_class}}::namedPropertyDeleterCustom(name, info);
389 {% else %}
390 {{cpp_class}}V8Internal::namedPropertyDeleter(name, info);
391 {% endif %}
392 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
395 {% endif %}
396 {% endblock %}
399 {##############################################################################}
400 {% block named_property_enumerator %}
401 {% if named_property_getter and named_property_getter.is_enumerable and
402 not named_property_getter.is_custom_property_enumerator %}
403 static void namedPropertyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info)
405 {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
406 Vector<String> names;
407 ExceptionState exceptionState(ExceptionState::EnumerationContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
408 impl->namedPropertyEnumerator(names, exceptionState);
409 if (exceptionState.throwIfNeeded())
410 return;
411 v8::Local<v8::Array> v8names = v8::Array::New(info.GetIsolate(), names.size());
412 for (size_t i = 0; i < names.size(); ++i) {
413 if (!v8CallBoolean(v8names->Set(info.GetIsolate()->GetCurrentContext(), v8::Integer::New(info.GetIsolate(), i), v8String(info.GetIsolate(), names[i]))))
414 return;
416 v8SetReturnValue(info, v8names);
419 {% endif %}
420 {% endblock %}
423 {##############################################################################}
424 {% block named_property_enumerator_callback %}
425 {% if named_property_getter and named_property_getter.is_enumerable %}
426 {% set getter = named_property_getter %}
427 static void namedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array>& info)
429 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMNamedProperty");
430 {% if getter.is_custom_property_enumerator %}
431 {{v8_class}}::namedPropertyEnumeratorCustom(info);
432 {% else %}
433 {{cpp_class}}V8Internal::namedPropertyEnumerator(info);
434 {% endif %}
435 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
438 {% endif %}
439 {% endblock %}
442 {##############################################################################}
443 {% block origin_safe_method_setter %}
444 {% if has_origin_safe_method_setter %}
445 static void {{cpp_class}}OriginSafeMethodSetter(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
447 v8::Local<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
448 if (holder.IsEmpty())
449 return;
450 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
451 v8::String::Utf8Value attributeName(name);
452 ExceptionState exceptionState(ExceptionState::SetterContext, *attributeName, "{{interface_name}}", info.Holder(), info.GetIsolate());
453 if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
454 exceptionState.throwIfNeeded();
455 return;
458 {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
459 V8HiddenValue::setHiddenValue(info.GetIsolate(), v8::Local<v8::Object>::Cast(info.This()), name.As<v8::String>(), v8Value);
462 static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::Name> name, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info)
464 TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMSetter");
465 {{cpp_class}}V8Internal::{{cpp_class}}OriginSafeMethodSetter(name, v8Value, info);
466 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
469 {% endif %}
470 {% endblock %}
473 {##############################################################################}
474 {% block named_constructor %}
475 {% from 'methods.cpp' import generate_constructor with context %}
476 {% if named_constructor %}
477 {% set to_active_dom_object = '%s::toActiveDOMObject' % v8_class
478 if is_active_dom_object else '0' %}
479 // Suppress warning: global constructors, because struct WrapperTypeInfo is trivial
480 // and does not depend on another global objects.
481 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
482 #pragma clang diagnostic push
483 #pragma clang diagnostic ignored "-Wglobal-constructors"
484 #endif
485 const WrapperTypeInfo {{v8_class}}Constructor::wrapperTypeInfo = { gin::kEmbedderBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::refObject, {{v8_class}}::derefObject, {{v8_class}}::trace, {{to_active_dom_object}}, 0, {{v8_class}}::preparePrototypeObject, {{v8_class}}::installConditionallyEnabledProperties, "{{interface_name}}", 0, WrapperTypeInfo::WrapperTypeObjectPrototype, WrapperTypeInfo::{{wrapper_class_id}}, WrapperTypeInfo::{{event_target_inheritance}}, WrapperTypeInfo::{{lifetime}}, WrapperTypeInfo::{{gc_type}} };
486 #if defined(COMPONENT_BUILD) && defined(WIN32) && COMPILER(CLANG)
487 #pragma clang diagnostic pop
488 #endif
490 {{generate_constructor(named_constructor)}}
491 v8::Local<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolate* isolate)
493 static int domTemplateKey; // This address is used for a key to look up the dom template.
494 V8PerIsolateData* data = V8PerIsolateData::from(isolate);
495 v8::Local<v8::FunctionTemplate> result = data->existingDOMTemplate(&domTemplateKey);
496 if (!result.IsEmpty())
497 return result;
499 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BuildDOMTemplate");
500 result = v8::FunctionTemplate::New(isolate, {{v8_class}}ConstructorCallback);
501 v8::Local<v8::ObjectTemplate> instanceTemplate = result->InstanceTemplate();
502 instanceTemplate->SetInternalFieldCount({{v8_class}}::internalFieldCount);
503 result->SetClassName(v8AtomicString(isolate, "{{cpp_class}}"));
504 result->Inherit({{v8_class}}::domTemplate(isolate));
505 data->setDOMTemplate(&domTemplateKey, result);
506 return result;
509 {% endif %}
510 {% endblock %}
512 {##############################################################################}
513 {% block overloaded_constructor %}
514 {% if constructor_overloads %}
515 static void constructor(const v8::FunctionCallbackInfo<v8::Value>& info)
517 ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
518 {# 2. Initialize argcount to be min(maxarg, n). #}
519 switch (std::min({{constructor_overloads.maxarg}}, info.Length())) {
520 {# 3. Remove from S all entries whose type list is not of length argcount. #}
521 {% for length, tests_constructors in constructor_overloads.length_tests_methods %}
522 case {{length}}:
523 {# Then resolve by testing argument #}
524 {% for test, constructor in tests_constructors %}
525 {# 10. If i = d, then: #}
526 if ({{test}}) {
527 {{cpp_class}}V8Internal::constructor{{constructor.overload_index}}(info);
528 return;
530 {% endfor %}
531 break;
532 {% endfor %}
533 default:
534 {# Invalid arity, throw error #}
535 {# Report full list of valid arities if gaps and above minimum #}
536 {% if constructor_overloads.valid_arities %}
537 if (info.Length() >= {{constructor_overloads.length}}) {
538 throwArityTypeError(exceptionState, "{{constructor_overloads.valid_arities}}", info.Length());
539 return;
541 {% endif %}
542 {# Otherwise just report "not enough arguments" #}
543 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{constructor_overloads.length}}, info.Length()));
544 exceptionState.throwIfNeeded();
545 return;
547 {# No match, throw error #}
548 exceptionState.throwTypeError("No matching constructor signature.");
549 exceptionState.throwIfNeeded();
552 {% endif %}
553 {% endblock %}
556 {##############################################################################}
557 {% block visit_dom_wrapper %}
558 {% if set_wrapper_reference_from or set_wrapper_reference_to %}
559 void {{v8_class}}::visitDOMWrapper(v8::Isolate* isolate, ScriptWrappable* scriptWrappable, const v8::Persistent<v8::Object>& wrapper)
561 {{cpp_class}}* impl = scriptWrappable->toImpl<{{cpp_class}}>();
562 {% if set_wrapper_reference_to %}
563 v8::Local<v8::Object> context = v8::Local<v8::Object>::New(isolate, wrapper);
564 v8::Context::Scope scope(context->CreationContext());
565 {{set_wrapper_reference_to.cpp_type}} {{set_wrapper_reference_to.name}} = impl->{{set_wrapper_reference_to.name}}();
566 if ({{set_wrapper_reference_to.name}}) {
567 if (DOMDataStore::containsWrapper({{set_wrapper_reference_to.name}}, isolate))
568 DOMDataStore::setWrapperReference(wrapper, {{set_wrapper_reference_to.name}}, isolate);
570 {% endif %}
571 {% if set_wrapper_reference_from %}
572 // The {{set_wrapper_reference_from}}() method may return a reference or a pointer.
573 if (Node* owner = WTF::getPtr(impl->{{set_wrapper_reference_from}}())) {
574 Node* root = V8GCController::opaqueRootForGC(isolate, owner);
575 isolate->SetReferenceFromGroup(v8::UniqueId(reinterpret_cast<intptr_t>(root)), wrapper);
576 return;
578 {% endif %}
581 {% endif %}
582 {% endblock %}
585 {##############################################################################}
586 {% block constructor_callback %}
587 {% if constructors or has_custom_constructor or has_event_constructor %}
588 void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
590 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMConstructor");
591 {% if measure_as %}
592 UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{measure_as('Constructor')}});
593 {% endif %}
594 if (!info.IsConstructCall()) {
595 V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::constructorNotCallableAsFunction("{{interface_name}}"));
596 return;
599 if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
600 v8SetReturnValue(info, info.Holder());
601 return;
604 {% if has_custom_constructor %}
605 {{v8_class}}::constructorCustom(info);
606 {% else %}
607 {{cpp_class}}V8Internal::constructor(info);
608 {% endif %}
611 {% endif %}
612 {% endblock %}
615 {##############################################################################}
616 {% macro install_do_not_check_security_method(method, world_suffix, instance_template, prototype_template) %}
617 {% from 'conversions.cpp' import property_location %}
618 {# Methods that are [DoNotCheckSecurity] are always readable, but if they are
619 changed and then accessed from a different origin, we do not return the
620 underlying value, but instead return a new copy of the original function.
621 This is achieved by storing the changed value as a hidden property. #}
622 {% set getter_callback =
623 '%sV8Internal::%sOriginSafeMethodGetterCallback%s' %
624 (cpp_class, method.name, world_suffix) %}
625 {% set setter_callback =
626 '{0}V8Internal::{0}OriginSafeMethodSetterCallback'.format(cpp_class)
627 if not method.is_read_only else '0' %}
628 {% if method.is_per_world_bindings %}
629 {% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %}
630 {% set setter_callback_for_main_world = '%sForMainWorld' % setter_callback
631 if not method.is_read_only else '0' %}
632 {% else %}
633 {% set getter_callback_for_main_world = '0' %}
634 {% set setter_callback_for_main_world = '0' %}
635 {% endif %}
636 {% set property_attribute =
637 'static_cast<v8::PropertyAttribute>(%s)' %
638 ' | '.join(method.property_attributes or ['v8::DontDelete']) %}
639 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
640 {% set holder_check = 'V8DOMConfiguration::DoNotCheckHolder' if method.is_do_not_check_signature else 'V8DOMConfiguration::CheckHolder' %}
641 const V8DOMConfiguration::AttributeConfiguration {{method.name}}OriginSafeAttributeConfiguration = {
642 "{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, &{{v8_class}}::wrapperTypeInfo, v8::ALL_CAN_READ, {{property_attribute}}, {{only_exposed_to_private_script}}, {{property_location(method)}}, {{holder_check}},
644 V8DOMConfiguration::installAttribute(isolate, {{instance_template}}, {{prototype_template}}, {{method.name}}OriginSafeAttributeConfiguration);
645 {%- endmacro %}
648 {##############################################################################}
649 {% block get_dom_template %}
650 {% if not is_array_buffer_or_view %}
651 v8::Local<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate)
653 {% if has_partial_interface %}
654 {% set installTemplateFunction = '%s::install%sTemplateFunction' % (v8_class, v8_class) %}
655 ASSERT({{installTemplateFunction}} != {{v8_class}}::install{{v8_class}}Template);
656 {% else %}
657 {% set installTemplateFunction = 'install%sTemplate' % v8_class %}
658 {% endif %}
659 {% set installTemplateFunction = '%s::install%sTemplateFunction' % (v8_class, v8_class) if has_partial_interface else 'install%sTemplate' % v8_class %}
660 return V8DOMConfiguration::domClassTemplate(isolate, const_cast<WrapperTypeInfo*>(&wrapperTypeInfo), {{installTemplateFunction}});
663 {% endif %}
664 {% endblock %}
667 {##############################################################################}
668 {% block has_instance %}
669 bool {{v8_class}}::hasInstance(v8::Local<v8::Value> v8Value, v8::Isolate* isolate)
671 {% if is_array_buffer_or_view %}
672 return v8Value->Is{{interface_name}}();
673 {% else %}
674 return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, v8Value);
675 {% endif %}
678 {% if not is_array_buffer_or_view %}
679 v8::Local<v8::Object> {{v8_class}}::findInstanceInPrototypeChain(v8::Local<v8::Value> v8Value, v8::Isolate* isolate)
681 return V8PerIsolateData::from(isolate)->findInstanceInPrototypeChain(&wrapperTypeInfo, v8Value);
684 {% endif %}
685 {% endblock %}
688 {##############################################################################}
689 {% block to_impl %}
690 {% if interface_name == 'ArrayBuffer' or interface_name == 'SharedArrayBuffer' %}
691 {{cpp_class}}* V8{{interface_name}}::toImpl(v8::Local<v8::Object> object)
693 ASSERT(object->Is{{interface_name}}());
694 v8::Local<v8::{{interface_name}}> v8buffer = object.As<v8::{{interface_name}}>();
695 if (v8buffer->IsExternal()) {
696 const WrapperTypeInfo* wrapperTypeInfo = toWrapperTypeInfo(object);
697 RELEASE_ASSERT(wrapperTypeInfo);
698 RELEASE_ASSERT(wrapperTypeInfo->ginEmbedder == gin::kEmbedderBlink);
699 return toScriptWrappable(object)->toImpl<{{cpp_class}}>();
702 // Transfer the ownership of the allocated memory to an {{interface_name}} without
703 // copying.
704 v8::{{interface_name}}::Contents v8Contents = v8buffer->Externalize();
705 WTF::ArrayBufferContents contents(v8Contents.Data(), v8Contents.ByteLength(), WTF::ArrayBufferContents::{% if interface_name == 'ArrayBuffer' %}Not{% endif %}Shared);
706 RefPtr<{{cpp_class}}> buffer = {{cpp_class}}::create(contents);
707 v8::Local<v8::Object> associatedWrapper = buffer->associateWithWrapper(v8::Isolate::GetCurrent(), buffer->wrapperTypeInfo(), object);
708 ASSERT_UNUSED(associatedWrapper, associatedWrapper == object);
710 return buffer.get();
713 {% elif interface_name == 'ArrayBufferView' %}
714 {{cpp_class}}* V8ArrayBufferView::toImpl(v8::Local<v8::Object> object)
716 ASSERT(object->IsArrayBufferView());
717 ScriptWrappable* scriptWrappable = toScriptWrappable(object);
718 if (scriptWrappable)
719 return scriptWrappable->toImpl<{{cpp_class}}>();
721 if (object->IsInt8Array())
722 return V8Int8Array::toImpl(object);
723 if (object->IsInt16Array())
724 return V8Int16Array::toImpl(object);
725 if (object->IsInt32Array())
726 return V8Int32Array::toImpl(object);
727 if (object->IsUint8Array())
728 return V8Uint8Array::toImpl(object);
729 if (object->IsUint8ClampedArray())
730 return V8Uint8ClampedArray::toImpl(object);
731 if (object->IsUint16Array())
732 return V8Uint16Array::toImpl(object);
733 if (object->IsUint32Array())
734 return V8Uint32Array::toImpl(object);
735 if (object->IsFloat32Array())
736 return V8Float32Array::toImpl(object);
737 if (object->IsFloat64Array())
738 return V8Float64Array::toImpl(object);
739 if (object->IsDataView())
740 return V8DataView::toImpl(object);
742 ASSERT_NOT_REACHED();
743 return 0;
746 {% elif is_array_buffer_or_view %}
747 {{cpp_class}}* {{v8_class}}::toImpl(v8::Local<v8::Object> object)
749 ASSERT(object->Is{{interface_name}}());
750 ScriptWrappable* scriptWrappable = toScriptWrappable(object);
751 if (scriptWrappable)
752 return scriptWrappable->toImpl<{{cpp_class}}>();
754 v8::Local<v8::{{interface_name}}> v8View = object.As<v8::{{interface_name}}>();
755 v8::Local<v8::Object> arrayBuffer = v8View->Buffer();
756 RefPtr<{{cpp_class}}> typedArray;
757 if (arrayBuffer->IsArrayBuffer()) {
758 typedArray = {{cpp_class}}::create(V8ArrayBuffer::toImpl(arrayBuffer), v8View->ByteOffset(), v8View->{% if interface_name == 'DataView' %}Byte{% endif %}Length());
759 } else if (arrayBuffer->IsSharedArrayBuffer()) {
760 typedArray = {{cpp_class}}::create(V8SharedArrayBuffer::toImpl(arrayBuffer), v8View->ByteOffset(), v8View->{% if interface_name == 'DataView' %}Byte{% endif %}Length());
761 } else {
762 ASSERT_NOT_REACHED();
764 v8::Local<v8::Object> associatedWrapper = typedArray->associateWithWrapper(v8::Isolate::GetCurrent(), typedArray->wrapperTypeInfo(), object);
765 ASSERT_UNUSED(associatedWrapper, associatedWrapper == object);
767 return typedArray->toImpl<{{cpp_class}}>();
770 {% endif %}
771 {% endblock %}
774 {##############################################################################}
775 {% block to_impl_with_type_check %}
776 {{cpp_class}}* {{v8_class}}::toImplWithTypeCheck(v8::Isolate* isolate, v8::Local<v8::Value> value)
778 return hasInstance(value, isolate) ? toImpl(v8::Local<v8::Object>::Cast(value)) : 0;
781 {% endblock %}
784 {##############################################################################}
785 {% block install_conditional_attributes %}
786 {% from 'attributes.cpp' import attribute_configuration with context %}
787 {% if has_conditional_attributes_on_instance %}
788 void {{v8_class}}::installConditionallyEnabledProperties(v8::Local<v8::Object> instanceObject, v8::Isolate* isolate)
790 #error TODO(yukishiino): Rename this function to prepareInstanceObject (c.f. preparePrototypeObject) and implement this function if necessary. http://crbug.com/503508
793 {% endif %}
794 {% endblock %}
797 {##############################################################################}
798 {% block prepare_prototype_object %}
799 {% from 'methods.cpp' import install_conditionally_enabled_methods with context %}
800 {% if unscopeables or has_conditional_attributes_on_prototype or conditionally_enabled_methods %}
801 void {{v8_class}}::preparePrototypeObject(v8::Isolate* isolate, v8::Local<v8::Object> prototypeObject, v8::Local<v8::FunctionTemplate> interfaceTemplate)
803 {% if unscopeables %}
804 {{install_unscopeables() | indent}}
805 {% endif %}
806 {% if has_conditional_attributes_on_prototype %}
807 {{install_conditionally_enabled_attributes_on_prototype() | indent}}
808 {% endif %}
809 {% if conditionally_enabled_methods %}
810 {{install_conditionally_enabled_methods() | indent}}
811 {% endif %}
814 {% endif %}
815 {% endblock %}
818 {##############################################################################}
819 {% macro install_unscopeables() %}
820 v8::Local<v8::Context> v8Context(prototypeObject->CreationContext());
821 v8::Local<v8::Name> unscopablesSymbol(v8::Symbol::GetUnscopables(isolate));
822 v8::Local<v8::Object> unscopeables;
823 if (v8CallBoolean(prototypeObject->HasOwnProperty(v8Context, unscopablesSymbol)))
824 unscopeables = prototypeObject->Get(v8Context, unscopablesSymbol).ToLocalChecked().As<v8::Object>();
825 else
826 unscopeables = v8::Object::New(isolate);
827 {% for name, runtime_enabled_function in unscopeables %}
828 {% filter runtime_enabled(runtime_enabled_function) %}
829 unscopeables->CreateDataProperty(v8Context, v8AtomicString(isolate, "{{name}}"), v8::True(isolate)).FromJust();
830 {% endfilter %}
831 {% endfor %}
832 prototypeObject->CreateDataProperty(v8Context, unscopablesSymbol, unscopeables).FromJust();
833 {% endmacro %}
836 {##############################################################################}
837 {% macro install_conditionally_enabled_attributes_on_prototype() %}
838 {% from 'attributes.cpp' import attribute_configuration with context %}
839 ExecutionContext* context = toExecutionContext(prototypeObject->CreationContext());
840 v8::Local<v8::Signature> signature = v8::Signature::New(isolate, interfaceTemplate);
841 {% for attribute in attributes if attribute.exposed_test and attribute.on_prototype %}
842 {% filter exposed(attribute.exposed_test) %}
843 const V8DOMConfiguration::AccessorConfiguration accessorConfiguration = {{attribute_configuration(attribute)}};
844 V8DOMConfiguration::installAccessor(isolate, v8::Local<v8::Object>(), prototypeObject, v8::Local<v8::Function>(), signature, accessorConfiguration);
845 {% endfilter %}
846 {% endfor %}
847 {% endmacro %}
850 {##############################################################################}
851 {% block to_active_dom_object %}
852 {% if is_active_dom_object %}
853 ActiveDOMObject* {{v8_class}}::toActiveDOMObject(v8::Local<v8::Object> wrapper)
855 return toImpl(wrapper);
858 {% endif %}
859 {% endblock %}
862 {##############################################################################}
863 {% block ref_object_and_deref_object %}
864 void {{v8_class}}::refObject(ScriptWrappable* scriptWrappable)
866 {% if gc_type == 'WillBeGarbageCollectedObject' %}
867 #if !ENABLE(OILPAN)
868 scriptWrappable->toImpl<{{cpp_class}}>()->ref();
869 #endif
870 {% elif gc_type == 'RefCountedObject' %}
871 scriptWrappable->toImpl<{{cpp_class}}>()->ref();
872 {% endif %}
875 void {{v8_class}}::derefObject(ScriptWrappable* scriptWrappable)
877 {% if gc_type == 'WillBeGarbageCollectedObject' %}
878 #if !ENABLE(OILPAN)
879 scriptWrappable->toImpl<{{cpp_class}}>()->deref();
880 #endif
881 {% elif gc_type == 'RefCountedObject' %}
882 scriptWrappable->toImpl<{{cpp_class}}>()->deref();
883 {% endif %}
886 {% endblock %}
888 {##############################################################################}
889 {% block partial_interface %}
890 {% if has_partial_interface %}
891 InstallTemplateFunction {{v8_class}}::install{{v8_class}}TemplateFunction = (InstallTemplateFunction)&{{v8_class}}::install{{v8_class}}Template;
893 void {{v8_class}}::updateWrapperTypeInfo(InstallTemplateFunction installTemplateFunction, PreparePrototypeObjectFunction preparePrototypeObjectFunction)
895 {{v8_class}}::install{{v8_class}}TemplateFunction = installTemplateFunction;
896 if (preparePrototypeObjectFunction)
897 {{v8_class}}::wrapperTypeInfo.preparePrototypeObjectFunction = preparePrototypeObjectFunction;
900 {% for method in methods if method.overloads and method.overloads.has_partial_overloads %}
901 void {{v8_class}}::register{{method.name | blink_capitalize}}MethodForPartialInterface(void (*method)(const v8::FunctionCallbackInfo<v8::Value>&))
903 {{cpp_class}}V8Internal::{{method.name}}MethodForPartialInterface = method;
905 {% endfor %}
906 {% endif %}
907 {% endblock %}