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