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