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