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());
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
%}
20 {% if getter
.is_raises_exception
%}
21 {% set getter_arguments
= getter_arguments
+ ['exceptionState'] %}
23 {{getter
.cpp_type
}} result
= impl
->{{getter_name
}}({{getter_arguments
| join(', ')}});
24 {% if getter
.is_raises_exception
%}
25 if (exceptionState
.throwIfNeeded())
28 if ({{getter
.is_null_expression
}})
30 {{getter
.v8_set_return_value
}};
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
);
47 {{cpp_class
}}V8Internal::indexedPropertyGetter(index
, info
);
49 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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());
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();
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
%}
83 {% if setter
.is_raises_exception
%}
84 {% set setter_arguments
= setter_arguments
+ ['exceptionState'] %}
86 bool result
= impl
->{{setter_name
}}({{setter_arguments
| join(', ')}});
87 {% if setter
.is_raises_exception
%}
88 if (exceptionState
.throwIfNeeded())
93 v8SetReturnValue(info
, v8Value
);
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
);
110 {{cpp_class
}}V8Internal::indexedPropertySetter(index
, v8Value
, info
);
112 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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());
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
%}
135 {% if deleter
.is_raises_exception
%}
136 {% set deleter_arguments
= deleter_arguments
+ ['exceptionState'] %}
138 DeleteResult result
= impl
->{{deleter_name
}}({{deleter_arguments
| join(', ')}});
139 {% if deleter
.is_raises_exception
%}
140 if (exceptionState
.throwIfNeeded())
143 if (result
!= DeleteUnknownProperty
)
144 return v8SetReturnValueBool(info
, result
== DeleteSuccess
);
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
);
161 {{cpp_class
}}V8Internal::indexedPropertyDeleter(index
, info
);
163 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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());
183 {% if getter
.is_call_with_script_state
%}
184 ScriptState
* scriptState
= ScriptState::current(info
.GetIsolate());
186 {% if getter
.use_output_parameter_for_result
%}
187 {{getter
.cpp_type
}} result
;
188 {{getter
.cpp_value
}};
190 {{getter
.cpp_type
}} result
= {{getter
.cpp_value
}};
192 {% if getter
.is_raises_exception
%}
193 if (exceptionState
.throwIfNeeded())
196 if ({{getter
.is_null_expression
}})
198 {{getter
.v8_set_return_value
}};
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
);
215 {{cpp_class
}}V8Internal::namedPropertyGetter(name
, info
);
217 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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());
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())
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();
251 {% if setter
.is_call_with_script_state
%}
252 ScriptState
* scriptState
= ScriptState::current(info
.GetIsolate());
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
%}
259 {% if setter
.is_raises_exception
%}
260 {% set setter_arguments
= setter_arguments
+ ['exceptionState'] %}
262 bool result
= impl
->{{setter_name
}}({{setter_arguments
| join(', ')}});
263 {% if setter
.is_raises_exception
%}
264 if (exceptionState
.throwIfNeeded())
269 v8SetReturnValue(info
, v8Value
);
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
);
286 {{cpp_class
}}V8Internal::namedPropertySetter(name
, v8Value
, info
);
288 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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
%}
313 bool result
= impl
->namedPropertyQuery({{getter_arguments
| join(', ')}});
314 if (exceptionState
.throwIfNeeded())
318 v8SetReturnValueInt(info
, v8::None
);
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
);
335 {{cpp_class
}}V8Internal::namedPropertyQuery(name
, info
);
337 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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());
356 {% if deleter
.is_call_with_script_state
%}
357 ScriptState
* scriptState
= ScriptState::current(info
.GetIsolate());
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
%}
364 {% if deleter
.is_raises_exception
%}
365 {% set deleter_arguments
= deleter_arguments
+ ['exceptionState'] %}
367 DeleteResult result
= impl
->{{deleter_name
}}({{deleter_arguments
| join(', ')}});
368 {% if deleter
.is_raises_exception
%}
369 if (exceptionState
.throwIfNeeded())
372 if (result
!= DeleteUnknownProperty
)
373 return v8SetReturnValueBool(info
, result
== DeleteSuccess
);
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
);
390 {{cpp_class
}}V8Internal::namedPropertyDeleter(name
, info
);
392 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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())
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
]))))
416 v8SetReturnValue(info
, v8names
);
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
);
433 {{cpp_class
}}V8Internal::namedPropertyEnumerator(info
);
435 TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
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())
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();
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");
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"
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
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())
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
);
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
%}
523 {# Then resolve by testing argument #}
524 {% for test
, constructor in tests_constructors
%}
525 {# 10. If i = d, then: #}
527 {{cpp_class
}}V8Internal::constructor
{{constructor
.overload_index
}}(info
);
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());
542 {# Otherwise just report "not enough arguments" #}
543 exceptionState
.throwTypeError(ExceptionMessages::notEnoughArguments({{constructor_overloads
.length
}}, info
.Length()));
544 exceptionState
.throwIfNeeded();
547 {# No match, throw error #}
548 exceptionState
.throwTypeError("No matching constructor signature.");
549 exceptionState
.throwIfNeeded();
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
);
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
);
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");
592 UseCounter::countIfNotPrivateScript(info
.GetIsolate(), callingExecutionContext(info
.GetIsolate()), UseCounter::{{measure_as('Constructor')}});
594 if (!info
.IsConstructCall()) {
595 V8ThrowException::throwTypeError(info
.GetIsolate(), ExceptionMessages::constructorNotCallableAsFunction("{{interface_name}}"));
599 if (ConstructorMode::current(info
.GetIsolate()) == ConstructorMode::WrapExistingObject
) {
600 v8SetReturnValue(info
, info
.Holder());
604 {% if has_custom_constructor
%}
605 {{v8_class
}}::constructorCustom(info
);
607 {{cpp_class
}}V8Internal::constructor(info
);
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' %}
633 {% set getter_callback_for_main_world
= '0' %}
634 {% set setter_callback_for_main_world
= '0' %}
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
);
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
);
657 {% set installTemplateFunction
= 'install%sTemplate' % v8_class
%}
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
}});
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
}}();
674 return V8PerIsolateData::from(isolate
)->hasInstance(&wrapperTypeInfo
, v8Value
);
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
);
688 {##############################################################################}
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
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
);
713 {% elif interface_name
== 'ArrayBufferView' %}
714 {{cpp_class
}}* V8ArrayBufferView::toImpl(v8::Local
<v8::Object
> object
)
716 ASSERT(object
->IsArrayBufferView());
717 ScriptWrappable
* scriptWrappable
= toScriptWrappable(object
);
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();
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
);
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());
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
}}>();
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;
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
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
}}
806 {% if has_conditional_attributes_on_prototype
%}
807 {{install_conditionally_enabled_attributes_on_prototype() | indent
}}
809 {% if conditionally_enabled_methods
%}
810 {{install_conditionally_enabled_methods() | indent
}}
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
>();
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();
832 prototypeObject
->CreateDataProperty(v8Context
, unscopablesSymbol
, unscopeables
).FromJust();
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
);
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
);
862 {##############################################################################}
863 {% block ref_object_and_deref_object
%}
864 void {{v8_class
}}::refObject(ScriptWrappable
* scriptWrappable
)
866 {% if gc_type
== 'WillBeGarbageCollectedObject' %}
868 scriptWrappable
->toImpl
<{{cpp_class
}}>()->ref();
870 {% elif gc_type
== 'RefCountedObject' %}
871 scriptWrappable
->toImpl
<{{cpp_class
}}>()->ref();
875 void {{v8_class
}}::derefObject(ScriptWrappable
* scriptWrappable
)
877 {% if gc_type
== 'WillBeGarbageCollectedObject' %}
879 scriptWrappable
->toImpl
<{{cpp_class
}}>()->deref();
881 {% elif gc_type
== 'RefCountedObject' %}
882 scriptWrappable
->toImpl
<{{cpp_class
}}>()->deref();
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
;