| OLD | NEW |
| (Empty) |
| 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::Prop
ertyCallbackInfo<v8::Value>& info) | |
| 8 { | |
| 9 v8::Handle<v8::Value> data = info.Data(); | |
| 10 ASSERT(data->IsExternal()); | |
| 11 V8PerContextData* perContextData = V8PerContextData::from(info.Holder()->Cre
ationContext()); | |
| 12 if (!perContextData) | |
| 13 return; | |
| 14 v8SetReturnValue(info, perContextData->constructorForType(WrapperTypeInfo::u
nwrap(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}}::toNative(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->fram
e(), 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> n
ame, 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::Access
Type type, v8::Local<v8::Value>) | |
| 52 { | |
| 53 {{cpp_class}}* impl = {{v8_class}}::toNative(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}}::toNative(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}}::toNative(info.Holder()); | |
| 74 {% if getter.is_raises_exception %} | |
| 75 ExceptionState exceptionState(ExceptionState::IndexedGetterContext, "{{inter
face_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::PropertyCall
backInfo<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}}::toNative(info.Holder()); | |
| 120 {{setter.v8_value_to_local_cpp_value}}; | |
| 121 {% if setter.has_exception_state %} | |
| 122 ExceptionState exceptionState(ExceptionState::IndexedSetterContext, "{{inter
face_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(v8Val
ue, info.GetIsolate())) { | |
| 128 exceptionState.throwTypeError("The provided value is not of type '{{sett
er.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> v
8Value, 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::PropertyCallbackInf
o<v8::Boolean>& info) | |
| 174 { | |
| 175 {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder()); | |
| 176 {% if deleter.is_raises_exception %} | |
| 177 ExceptionState exceptionState(ExceptionState::IndexedDeletionContext, "{{int
erface_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::PropertyCal
lbackInfo<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::PropertyCa
llbackInfo<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}}::toNative(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::Pr
opertyCallbackInfo<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 {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder()); | |
| 285 {# v8_value_to_local_cpp_value('DOMString', 'name', 'propertyName') #} | |
| 286 TOSTRING_VOID(V8StringResource<>, propertyName, name); | |
| 287 {{setter.v8_value_to_local_cpp_value}}; | |
| 288 {% if setter.has_exception_state %} | |
| 289 v8::String::Utf8Value namedProperty(name); | |
| 290 ExceptionState exceptionState(ExceptionState::SetterContext, *namedProperty,
"{{interface_name}}", info.Holder(), info.GetIsolate()); | |
| 291 {% endif %} | |
| 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::PropertyCal
lbackInfo<v8::Integer>& info) | |
| 337 { | |
| 338 {{cpp_class}}* impl = {{v8_class}}::toNative(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::Pro
pertyCallbackInfo<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::PropertyC
allbackInfo<v8::Boolean>& info) | |
| 378 { | |
| 379 {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder()); | |
| 380 AtomicString propertyName = toCoreAtomicString(name); | |
| 381 {% if deleter.is_raises_exception %} | |
| 382 v8::String::Utf8Value namedProperty(name); | |
| 383 ExceptionState exceptionState(ExceptionState::DeletionContext, *namedPropert
y, "{{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::P
ropertyCallbackInfo<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>& i
nfo) | |
| 425 { | |
| 426 {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder()); | |
| 427 Vector<String> names; | |
| 428 ExceptionState exceptionState(ExceptionState::EnumerationContext, "{{interfa
ce_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.GetIs
olate(), 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::A
rray>& 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(i
nfo.This(), info.GetIsolate()); | |
| 467 if (holder.IsEmpty()) | |
| 468 return; | |
| 469 {{cpp_class}}* impl = {{v8_class}}::toNative(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->fram
e(), exceptionState)) { | |
| 473 exceptionState.throwIfNeeded(); | |
| 474 return; | |
| 475 } | |
| 476 | |
| 477 {# The findInstanceInPrototypeChain() call above only returns a non-empty ha
ndle if info.This() is an Object. #} | |
| 478 V8HiddenValue::setHiddenValue(info.GetIsolate(), v8::Handle<v8::Object>::Cas
t(info.This()), name, v8Value); | |
| 479 } | |
| 480 | |
| 481 static void {{cpp_class}}OriginSafeMethodSetterCallback(v8::Local<v8::String> na
me, 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::kEmbedde
rBlink, {{v8_class}}Constructor::domTemplate, {{v8_class}}::refObject, {{v8_clas
s}}::derefObject, {{to_active_dom_object}}, {{to_event_target}}, 0, {{v8_class}}
::installConditionallyEnabledMethods, {{v8_class}}::installConditionallyEnabledP
roperties, 0, WrapperTypeInfo::WrapperTypeObjectPrototype, WrapperTypeInfo::{{wr
apper_class_id}}, WrapperTypeInfo::{{lifetime}} }; | |
| 501 | |
| 502 {{generate_constructor(named_constructor)}} | |
| 503 v8::Handle<v8::FunctionTemplate> {{v8_class}}Constructor::domTemplate(v8::Isolat
e* 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(&domTempl
ateKey); | |
| 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, "{{interf
ace_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_meth
ods %} | |
| 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}}(i
nfo); | |
| 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_a
rities}}", info.Length()); | |
| 551 return; | |
| 552 } | |
| 553 {% endif %} | |
| 554 {# Otherwise just report "not enough arguments" #} | |
| 555 exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{co
nstructor_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, "{{interf
ace_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 TONATIVE_VOID(Dictionary, options, Dictionary(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(), v8At
omicString(info.GetIsolate(), "{{attribute.name}}"), {{attribute.name}}); | |
| 597 {% endfor %} | |
| 598 } | |
| 599 {% if is_constructor_raises_exception %} | |
| 600 RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit, excepti
onState); | |
| 601 if (exceptionState.throwIfNeeded()) | |
| 602 return; | |
| 603 {% else %} | |
| 604 RefPtr<{{cpp_class}}> event = {{cpp_class}}::create(type, eventInit); | |
| 605 {% endif %} | |
| 606 | |
| 607 v8::Handle<v8::Object> wrapper = info.Holder(); | |
| 608 V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(event.release(), &{{v
8_class}}::wrapperTypeInfo, wrapper, info.GetIsolate()); | |
| 609 v8SetReturnValue(info, wrapper); | |
| 610 } | |
| 611 | |
| 612 {% endif %} | |
| 613 {% endblock %} | |
| 614 | |
| 615 | |
| 616 {##############################################################################} | |
| 617 {% block visit_dom_wrapper %} | |
| 618 {% if reachable_node_function or set_wrapper_reference_to_list %} | |
| 619 void {{v8_class}}::visitDOMWrapper(ScriptWrappableBase* internalPointer, const v
8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate) | |
| 620 { | |
| 621 {{cpp_class}}* impl = fromInternalPointer(internalPointer); | |
| 622 {% if set_wrapper_reference_to_list %} | |
| 623 v8::Local<v8::Object> creationContext = v8::Local<v8::Object>::New(isolate,
wrapper); | |
| 624 V8WrapperInstantiationScope scope(creationContext, isolate); | |
| 625 {% for set_wrapper_reference_to in set_wrapper_reference_to_list %} | |
| 626 {{set_wrapper_reference_to.cpp_type}} {{set_wrapper_reference_to.name}} = im
pl->{{set_wrapper_reference_to.name}}(); | |
| 627 if ({{set_wrapper_reference_to.name}}) { | |
| 628 if (!DOMDataStore::containsWrapper<{{set_wrapper_reference_to.v8_type}}>
({{set_wrapper_reference_to.name}}, isolate)) | |
| 629 wrap({{set_wrapper_reference_to.name}}, creationContext, isolate); | |
| 630 DOMDataStore::setWrapperReference<{{set_wrapper_reference_to.v8_type}}>(
wrapper, {{set_wrapper_reference_to.name}}, isolate); | |
| 631 } | |
| 632 {% endfor %} | |
| 633 {% endif %} | |
| 634 {% if reachable_node_function %} | |
| 635 // The {{reachable_node_function}}() method may return a reference or a poin
ter. | |
| 636 if (Node* owner = WTF::getPtr(impl->{{reachable_node_function}}())) { | |
| 637 Node* root = V8GCController::opaqueRootForGC(owner, isolate); | |
| 638 isolate->SetReferenceFromGroup(v8::UniqueId(reinterpret_cast<intptr_t>(r
oot)), wrapper); | |
| 639 return; | |
| 640 } | |
| 641 {% endif %} | |
| 642 setObjectGroup(internalPointer, wrapper, isolate); | |
| 643 } | |
| 644 | |
| 645 {% endif %} | |
| 646 {% endblock %} | |
| 647 | |
| 648 | |
| 649 {##############################################################################} | |
| 650 {% from 'attributes.cpp' import attribute_configuration with context %} | |
| 651 {% block shadow_attributes %} | |
| 652 {% if interface_name == 'Window' %} | |
| 653 static const V8DOMConfiguration::AttributeConfiguration shadowAttributes[] = { | |
| 654 {% for attribute in attributes if attribute.is_unforgeable and attribute.sho
uld_be_exposed_to_script %} | |
| 655 {{attribute_configuration(attribute)}}, | |
| 656 {% endfor %} | |
| 657 }; | |
| 658 | |
| 659 {% endif %} | |
| 660 {% endblock %} | |
| 661 | |
| 662 | |
| 663 {##############################################################################} | |
| 664 {% block install_attributes %} | |
| 665 {% if has_attribute_configuration %} | |
| 666 static const V8DOMConfiguration::AttributeConfiguration {{v8_class}}Attributes[]
= { | |
| 667 {% for attribute in attributes | |
| 668 if not (attribute.is_expose_js_accessors or | |
| 669 attribute.is_static or | |
| 670 attribute.runtime_enabled_function or | |
| 671 attribute.exposed_test or | |
| 672 (interface_name == 'Window' and attribute.is_unforgeable)) | |
| 673 and attribute.should_be_exposed_to_script %} | |
| 674 {% filter conditional(attribute.conditional_string) %} | |
| 675 {{attribute_configuration(attribute)}}, | |
| 676 {% endfilter %} | |
| 677 {% endfor %} | |
| 678 }; | |
| 679 | |
| 680 {% endif %} | |
| 681 {% endblock %} | |
| 682 | |
| 683 | |
| 684 {##############################################################################} | |
| 685 {% block install_accessors %} | |
| 686 {% if has_accessors %} | |
| 687 static const V8DOMConfiguration::AccessorConfiguration {{v8_class}}Accessors[] =
{ | |
| 688 {% for attribute in attributes if attribute.is_expose_js_accessors and attri
bute.should_be_exposed_to_script %} | |
| 689 {{attribute_configuration(attribute)}}, | |
| 690 {% endfor %} | |
| 691 }; | |
| 692 | |
| 693 {% endif %} | |
| 694 {% endblock %} | |
| 695 | |
| 696 | |
| 697 {##############################################################################} | |
| 698 {% from 'methods.cpp' import method_configuration with context %} | |
| 699 {% block install_methods %} | |
| 700 {% if method_configuration_methods %} | |
| 701 static const V8DOMConfiguration::MethodConfiguration {{v8_class}}Methods[] = { | |
| 702 {% for method in method_configuration_methods %} | |
| 703 {% filter conditional(method.conditional_string) %} | |
| 704 {{method_configuration(method)}}, | |
| 705 {% endfilter %} | |
| 706 {% endfor %} | |
| 707 }; | |
| 708 | |
| 709 {% endif %} | |
| 710 {% endblock %} | |
| 711 | |
| 712 | |
| 713 {##############################################################################} | |
| 714 {% block initialize_event %} | |
| 715 {% if has_event_constructor %} | |
| 716 bool initialize{{cpp_class}}({{cpp_class}}Init& eventInit, const Dictionary& opt
ions, ExceptionState& exceptionState, const v8::FunctionCallbackInfo<v8::Value>&
info, const String& forEventName) | |
| 717 { | |
| 718 Dictionary::ConversionContext conversionContext(forEventName.isEmpty() ? Str
ing("{{interface_name}}") : forEventName, "", exceptionState); | |
| 719 {% if parent_interface %}{# any Event interface except Event itself #} | |
| 720 if (!initialize{{parent_interface}}(eventInit, options, exceptionState, info
, forEventName.isEmpty() ? String("{{interface_name}}") : forEventName)) | |
| 721 return false; | |
| 722 | |
| 723 {% endif %} | |
| 724 {% for attribute in attributes | |
| 725 if (attribute.is_initialized_by_event_constructor and | |
| 726 not attribute.idl_type == 'any')%} | |
| 727 {% set is_nullable = 'true' if attribute.is_nullable else 'false' %} | |
| 728 if (!DictionaryHelper::convert(options, conversionContext.setConversionType(
"{{attribute.idl_type}}", {{is_nullable}}), "{{attribute.name}}", eventInit.{{at
tribute.cpp_name}})) | |
| 729 return false; | |
| 730 {% endfor %} | |
| 731 return true; | |
| 732 } | |
| 733 | |
| 734 {% endif %} | |
| 735 {% endblock %} | |
| 736 | |
| 737 | |
| 738 {##############################################################################} | |
| 739 {% block constructor_callback %} | |
| 740 {% if constructors or has_custom_constructor or has_event_constructor %} | |
| 741 void {{v8_class}}::constructorCallback(const v8::FunctionCallbackInfo<v8::Value>
& info) | |
| 742 { | |
| 743 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "DOMConstructor"); | |
| 744 if (!info.IsConstructCall()) { | |
| 745 V8ThrowException::throwTypeError(ExceptionMessages::constructorNotCallab
leAsFunction("{{interface_name}}"), info.GetIsolate()); | |
| 746 return; | |
| 747 } | |
| 748 | |
| 749 if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExis
tingObject) { | |
| 750 v8SetReturnValue(info, info.Holder()); | |
| 751 return; | |
| 752 } | |
| 753 | |
| 754 {% if has_custom_constructor %} | |
| 755 {{v8_class}}::constructorCustom(info); | |
| 756 {% else %} | |
| 757 {{cpp_class}}V8Internal::constructor(info); | |
| 758 {% endif %} | |
| 759 } | |
| 760 | |
| 761 {% endif %} | |
| 762 {% endblock %} | |
| 763 | |
| 764 | |
| 765 {##############################################################################} | |
| 766 {% block configure_shadow_object_template %} | |
| 767 {% if interface_name == 'Window' %} | |
| 768 static void configureShadowObjectTemplate(v8::Handle<v8::ObjectTemplate> templ,
v8::Isolate* isolate) | |
| 769 { | |
| 770 V8DOMConfiguration::installAttributes(templ, v8::Handle<v8::ObjectTemplate>(
), shadowAttributes, WTF_ARRAY_LENGTH(shadowAttributes), isolate); | |
| 771 | |
| 772 // Install a security handler with V8. | |
| 773 templ->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom, V8Window:
:indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<WrapperTypeIn
fo*>(&V8Window::wrapperTypeInfo))); | |
| 774 templ->SetInternalFieldCount(V8Window::internalFieldCount); | |
| 775 } | |
| 776 | |
| 777 {% endif %} | |
| 778 {% endblock %} | |
| 779 | |
| 780 | |
| 781 {##############################################################################} | |
| 782 {% from 'methods.cpp' import install_custom_signature with context %} | |
| 783 {% from 'constants.cpp' import install_constants with context %} | |
| 784 {% block install_dom_template %} | |
| 785 static void install{{v8_class}}Template(v8::Handle<v8::FunctionTemplate> functio
nTemplate, v8::Isolate* isolate) | |
| 786 { | |
| 787 functionTemplate->ReadOnlyPrototype(); | |
| 788 | |
| 789 v8::Local<v8::Signature> defaultSignature; | |
| 790 {% set parent_template = | |
| 791 'V8%s::domTemplate(isolate)' % parent_interface | |
| 792 if parent_interface else 'v8::Local<v8::FunctionTemplate>()' %} | |
| 793 {% if runtime_enabled_function %} | |
| 794 if (!{{runtime_enabled_function}}()) | |
| 795 defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionT
emplate, "", {{parent_template}}, {{v8_class}}::internalFieldCount, 0, 0, 0, 0,
0, 0, isolate); | |
| 796 else | |
| 797 {% endif %} | |
| 798 {% set runtime_enabled_indent = 4 if runtime_enabled_function else 0 %} | |
| 799 {% filter indent(runtime_enabled_indent, true) %} | |
| 800 defaultSignature = V8DOMConfiguration::installDOMClassTemplate(functionTempl
ate, "{{interface_name}}", {{parent_template}}, {{v8_class}}::internalFieldCount
, | |
| 801 {# Test needed as size 0 arrays definitions are not allowed per standard | |
| 802 (so objects have distinct addresses), which is enforced by MSVC. | |
| 803 8.5.1 Aggregates [dcl.init.aggr] | |
| 804 An array of unknown size initialized with a brace-enclosed | |
| 805 initializer-list containing n initializer-clauses, where n shall be | |
| 806 greater than zero, is defined as having n elements (8.3.4). #} | |
| 807 {% set attributes_name, attributes_length = | |
| 808 ('%sAttributes' % v8_class, | |
| 809 'WTF_ARRAY_LENGTH(%sAttributes)' % v8_class) | |
| 810 if has_attribute_configuration else (0, 0) %} | |
| 811 {% set accessors_name, accessors_length = | |
| 812 ('%sAccessors' % v8_class, | |
| 813 'WTF_ARRAY_LENGTH(%sAccessors)' % v8_class) | |
| 814 if has_accessors else (0, 0) %} | |
| 815 {% set methods_name, methods_length = | |
| 816 ('%sMethods' % v8_class, | |
| 817 'WTF_ARRAY_LENGTH(%sMethods)' % v8_class) | |
| 818 if method_configuration_methods else (0, 0) %} | |
| 819 {{attributes_name}}, {{attributes_length}}, | |
| 820 {{accessors_name}}, {{accessors_length}}, | |
| 821 {{methods_name}}, {{methods_length}}, | |
| 822 isolate); | |
| 823 {% endfilter %} | |
| 824 | |
| 825 {% if constructors or has_custom_constructor or has_event_constructor %} | |
| 826 functionTemplate->SetCallHandler({{v8_class}}::constructorCallback); | |
| 827 functionTemplate->SetLength({{interface_length}}); | |
| 828 {% endif %} | |
| 829 v8::Local<v8::ObjectTemplate> instanceTemplate ALLOW_UNUSED = functionTempla
te->InstanceTemplate(); | |
| 830 v8::Local<v8::ObjectTemplate> prototypeTemplate ALLOW_UNUSED = functionTempl
ate->PrototypeTemplate(); | |
| 831 {% if has_access_check_callbacks %} | |
| 832 instanceTemplate->SetAccessCheckCallbacks({{cpp_class}}V8Internal::namedSecu
rityCheck, {{cpp_class}}V8Internal::indexedSecurityCheck, v8::External::New(isol
ate, const_cast<WrapperTypeInfo*>(&{{v8_class}}::wrapperTypeInfo))); | |
| 833 {% endif %} | |
| 834 {% for attribute in attributes | |
| 835 if attribute.runtime_enabled_function and | |
| 836 not attribute.exposed_test and | |
| 837 not attribute.is_static %} | |
| 838 {% filter conditional(attribute.conditional_string) %} | |
| 839 if ({{attribute.runtime_enabled_function}}()) { | |
| 840 static const V8DOMConfiguration::AttributeConfiguration attributeConfigu
ration =\ | |
| 841 {{attribute_configuration(attribute)}}; | |
| 842 V8DOMConfiguration::installAttribute(instanceTemplate, prototypeTemplate
, attributeConfiguration, isolate); | |
| 843 } | |
| 844 {% endfilter %} | |
| 845 {% endfor %} | |
| 846 {% if constants %} | |
| 847 {{install_constants() | indent}} | |
| 848 {% endif %} | |
| 849 {# Special operations #} | |
| 850 {# V8 has access-check callback API and it's used on Window instead of | |
| 851 deleters or enumerators; see ObjectTemplate::SetAccessCheckCallbacks. | |
| 852 In addition, the getter should be set on the prototype template, to get | |
| 853 the implementation straight out of the Window prototype, regardless of | |
| 854 what prototype is actually set on the object. #} | |
| 855 {% set set_on_template = 'PrototypeTemplate' if interface_name == 'Window' | |
| 856 else 'InstanceTemplate' %} | |
| 857 {% if indexed_property_getter %} | |
| 858 {# if have indexed properties, MUST have an indexed property getter #} | |
| 859 {% set indexed_property_getter_callback = | |
| 860 '%sV8Internal::indexedPropertyGetterCallback' % cpp_class %} | |
| 861 {% set indexed_property_setter_callback = | |
| 862 '%sV8Internal::indexedPropertySetterCallback' % cpp_class | |
| 863 if indexed_property_setter else '0' %} | |
| 864 {% set indexed_property_query_callback = '0' %}{# Unused #} | |
| 865 {% set indexed_property_deleter_callback = | |
| 866 '%sV8Internal::indexedPropertyDeleterCallback' % cpp_class | |
| 867 if indexed_property_deleter else '0' %} | |
| 868 {% set indexed_property_enumerator_callback = | |
| 869 'indexedPropertyEnumerator<%s>' % cpp_class | |
| 870 if indexed_property_getter.is_enumerable else '0' %} | |
| 871 functionTemplate->{{set_on_template}}()->SetIndexedPropertyHandler({{indexed
_property_getter_callback}}, {{indexed_property_setter_callback}}, {{indexed_pro
perty_query_callback}}, {{indexed_property_deleter_callback}}, {{indexed_propert
y_enumerator_callback}}); | |
| 872 {% endif %} | |
| 873 {% if named_property_getter %} | |
| 874 {# if have named properties, MUST have a named property getter #} | |
| 875 {% set named_property_getter_callback = | |
| 876 '%sV8Internal::namedPropertyGetterCallback' % cpp_class %} | |
| 877 {% set named_property_setter_callback = | |
| 878 '%sV8Internal::namedPropertySetterCallback' % cpp_class | |
| 879 if named_property_setter else '0' %} | |
| 880 {% set named_property_query_callback = | |
| 881 '%sV8Internal::namedPropertyQueryCallback' % cpp_class | |
| 882 if named_property_getter.is_enumerable else '0' %} | |
| 883 {% set named_property_deleter_callback = | |
| 884 '%sV8Internal::namedPropertyDeleterCallback' % cpp_class | |
| 885 if named_property_deleter else '0' %} | |
| 886 {% set named_property_enumerator_callback = | |
| 887 '%sV8Internal::namedPropertyEnumeratorCallback' % cpp_class | |
| 888 if named_property_getter.is_enumerable else '0' %} | |
| 889 functionTemplate->{{set_on_template}}()->SetNamedPropertyHandler({{named_pro
perty_getter_callback}}, {{named_property_setter_callback}}, {{named_property_qu
ery_callback}}, {{named_property_deleter_callback}}, {{named_property_enumerator
_callback}}); | |
| 890 {% endif %} | |
| 891 {% if iterator_method %} | |
| 892 static const V8DOMConfiguration::SymbolKeyedMethodConfiguration symbolKeyedI
teratorConfiguration = { v8::Symbol::GetIterator, {{cpp_class}}V8Internal::itera
torMethodCallback, 0, V8DOMConfiguration::ExposedToAllScripts }; | |
| 893 V8DOMConfiguration::installMethod(prototypeTemplate, defaultSignature, v8::D
ontDelete, symbolKeyedIteratorConfiguration, isolate); | |
| 894 {% endif %} | |
| 895 {# End special operations #} | |
| 896 {% if has_custom_legacy_call_as_function %} | |
| 897 functionTemplate->InstanceTemplate()->SetCallAsFunctionHandler({{v8_class}}:
:legacyCallCustom); | |
| 898 {% endif %} | |
| 899 {% for method in custom_registration_methods %} | |
| 900 {# install_custom_signature #} | |
| 901 {% filter conditional(method.conditional_string) %} | |
| 902 {% filter runtime_enabled(method.overloads.runtime_enabled_function_all | |
| 903 if method.overloads else | |
| 904 method.runtime_enabled_function) %} | |
| 905 {% if method.is_do_not_check_security %} | |
| 906 {{install_do_not_check_security_signature(method) | indent}} | |
| 907 {% else %}{# is_do_not_check_security #} | |
| 908 {{install_custom_signature(method) | indent}} | |
| 909 {% endif %}{# is_do_not_check_security #} | |
| 910 {% endfilter %}{# runtime_enabled() #} | |
| 911 {% endfilter %}{# conditional() #} | |
| 912 {% endfor %} | |
| 913 {% for attribute in attributes if attribute.is_static %} | |
| 914 {% set getter_callback = '%sV8Internal::%sAttributeGetterCallback' % | |
| 915 (cpp_class, attribute.name) %} | |
| 916 {% filter conditional(attribute.conditional_string) %} | |
| 917 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::Acces
sorSignature>(), static_cast<v8::AccessControl>(v8::DEFAULT)); | |
| 918 {% endfilter %} | |
| 919 {% endfor %} | |
| 920 {# Special interfaces #} | |
| 921 {% if interface_name == 'Window' %} | |
| 922 | |
| 923 prototypeTemplate->SetInternalFieldCount(V8Window::internalFieldCount); | |
| 924 functionTemplate->SetHiddenPrototype(true); | |
| 925 instanceTemplate->SetInternalFieldCount(V8Window::internalFieldCount); | |
| 926 // Set access check callbacks, but turned off initially. | |
| 927 // When a context is detached from a frame, turn on the access check. | |
| 928 // Turning on checks also invalidates inline caches of the object. | |
| 929 instanceTemplate->SetAccessCheckCallbacks(V8Window::namedSecurityCheckCustom
, V8Window::indexedSecurityCheckCustom, v8::External::New(isolate, const_cast<Wr
apperTypeInfo*>(&V8Window::wrapperTypeInfo)), false); | |
| 930 {% endif %} | |
| 931 | |
| 932 // Custom toString template | |
| 933 functionTemplate->Set(v8AtomicString(isolate, "toString"), V8PerIsolateData:
:from(isolate)->toStringTemplate()); | |
| 934 } | |
| 935 | |
| 936 {% endblock %} | |
| 937 | |
| 938 | |
| 939 {######################################} | |
| 940 {% macro install_do_not_check_security_signature(method, world_suffix) %} | |
| 941 {# Methods that are [DoNotCheckSecurity] are always readable, but if they are | |
| 942 changed and then accessed from a different origin, we do not return the | |
| 943 underlying value, but instead return a new copy of the original function. | |
| 944 This is achieved by storing the changed value as a hidden property. #} | |
| 945 {% set getter_callback = | |
| 946 '%sV8Internal::%sOriginSafeMethodGetterCallback%s' % | |
| 947 (cpp_class, method.name, world_suffix) %} | |
| 948 {% set setter_callback = | |
| 949 '{0}V8Internal::{0}OriginSafeMethodSetterCallback'.format(cpp_class) | |
| 950 if not method.is_read_only else '0' %} | |
| 951 {% if method.is_per_world_bindings %} | |
| 952 {% set getter_callback_for_main_world = '%sForMainWorld' % getter_callback %} | |
| 953 {% set setter_callback_for_main_world = '%sForMainWorld' % setter_callback | |
| 954 if not method.is_read_only else '0' %} | |
| 955 {% else %} | |
| 956 {% set getter_callback_for_main_world = '0' %} | |
| 957 {% set setter_callback_for_main_world = '0' %} | |
| 958 {% endif %} | |
| 959 {% set property_attribute = | |
| 960 'static_cast<v8::PropertyAttribute>(%s)' % | |
| 961 ' | '.join(method.property_attributes or ['v8::DontDelete']) %} | |
| 962 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivat
eScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::Expo
sedToAllScripts' %} | |
| 963 static const V8DOMConfiguration::AttributeConfiguration {{method.name}}OriginSaf
eAttributeConfiguration = { | |
| 964 "{{method.name}}", {{getter_callback}}, {{setter_callback}}, {{getter_callba
ck_for_main_world}}, {{setter_callback_for_main_world}}, &{{v8_class}}::wrapperT
ypeInfo, v8::ALL_CAN_READ, {{property_attribute}}, {{only_exposed_to_private_scr
ipt}}, V8DOMConfiguration::OnInstance, | |
| 965 }; | |
| 966 V8DOMConfiguration::installAttribute({{method.function_template}}, v8::Handle<v8
::ObjectTemplate>(), {{method.name}}OriginSafeAttributeConfiguration, isolate); | |
| 967 {%- endmacro %} | |
| 968 | |
| 969 | |
| 970 {##############################################################################} | |
| 971 {% block get_dom_template %} | |
| 972 v8::Handle<v8::FunctionTemplate> {{v8_class}}::domTemplate(v8::Isolate* isolate) | |
| 973 { | |
| 974 return V8DOMConfiguration::domClassTemplate(isolate, const_cast<WrapperTypeI
nfo*>(&wrapperTypeInfo), install{{v8_class}}Template); | |
| 975 } | |
| 976 | |
| 977 {% endblock %} | |
| 978 | |
| 979 | |
| 980 {##############################################################################} | |
| 981 {% block has_instance %} | |
| 982 bool {{v8_class}}::hasInstance(v8::Handle<v8::Value> v8Value, v8::Isolate* isola
te) | |
| 983 { | |
| 984 return V8PerIsolateData::from(isolate)->hasInstance(&wrapperTypeInfo, v8Valu
e); | |
| 985 } | |
| 986 | |
| 987 v8::Handle<v8::Object> {{v8_class}}::findInstanceInPrototypeChain(v8::Handle<v8:
:Value> v8Value, v8::Isolate* isolate) | |
| 988 { | |
| 989 return V8PerIsolateData::from(isolate)->findInstanceInPrototypeChain(&wrappe
rTypeInfo, v8Value); | |
| 990 } | |
| 991 | |
| 992 {% endblock %} | |
| 993 | |
| 994 | |
| 995 {##############################################################################} | |
| 996 {% block to_native_with_type_check %} | |
| 997 {{cpp_class}}* {{v8_class}}::toNativeWithTypeCheck(v8::Isolate* isolate, v8::Han
dle<v8::Value> value) | |
| 998 { | |
| 999 return hasInstance(value, isolate) ? fromInternalPointer(blink::toScriptWrap
pableBase(v8::Handle<v8::Object>::Cast(value))) : 0; | |
| 1000 } | |
| 1001 | |
| 1002 {% endblock %} | |
| 1003 | |
| 1004 | |
| 1005 {##############################################################################} | |
| 1006 {% block install_conditional_attributes %} | |
| 1007 {% if has_conditional_attributes %} | |
| 1008 void {{v8_class}}::installConditionallyEnabledProperties(v8::Handle<v8::Object>
instanceObject, v8::Isolate* isolate) | |
| 1009 { | |
| 1010 v8::Local<v8::Object> prototypeObject = v8::Local<v8::Object>::Cast(instance
Object->GetPrototype()); | |
| 1011 ExecutionContext* context = toExecutionContext(prototypeObject->CreationCont
ext()); | |
| 1012 | |
| 1013 {% for attribute in attributes if attribute.exposed_test %} | |
| 1014 {% filter exposed(attribute.exposed_test) %} | |
| 1015 static const V8DOMConfiguration::AttributeConfiguration attributeConfigurati
on =\ | |
| 1016 {{attribute_configuration(attribute)}}; | |
| 1017 V8DOMConfiguration::installAttribute(instanceObject, prototypeObject, attrib
uteConfiguration, isolate); | |
| 1018 {% endfilter %} | |
| 1019 {% endfor %} | |
| 1020 } | |
| 1021 | |
| 1022 {% endif %} | |
| 1023 {% endblock %} | |
| 1024 | |
| 1025 | |
| 1026 {##############################################################################} | |
| 1027 {% block install_conditional_methods %} | |
| 1028 {% if conditionally_enabled_methods %} | |
| 1029 void {{v8_class}}::installConditionallyEnabledMethods(v8::Handle<v8::Object> pro
totypeObject, v8::Isolate* isolate) | |
| 1030 { | |
| 1031 {# Define per-context enabled operations #} | |
| 1032 v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domT
emplate(isolate)); | |
| 1033 ExecutionContext* context = toExecutionContext(prototypeObject->CreationCont
ext()); | |
| 1034 ASSERT(context); | |
| 1035 | |
| 1036 {% for method in conditionally_enabled_methods %} | |
| 1037 {% filter exposed(method.exposed_test) %} | |
| 1038 prototypeObject->Set(v8AtomicString(isolate, "{{method.name}}"), v8::Functio
nTemplate::New(isolate, {{cpp_class}}V8Internal::{{method.name}}MethodCallback,
v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFu
nction()); | |
| 1039 {% endfilter %} | |
| 1040 {% endfor %} | |
| 1041 } | |
| 1042 | |
| 1043 {% endif %} | |
| 1044 {% endblock %} | |
| 1045 | |
| 1046 | |
| 1047 {##############################################################################} | |
| 1048 {% block to_active_dom_object %} | |
| 1049 {% if is_active_dom_object %} | |
| 1050 ActiveDOMObject* {{v8_class}}::toActiveDOMObject(v8::Handle<v8::Object> wrapper) | |
| 1051 { | |
| 1052 return toNative(wrapper); | |
| 1053 } | |
| 1054 | |
| 1055 {% endif %} | |
| 1056 {% endblock %} | |
| 1057 | |
| 1058 | |
| 1059 {##############################################################################} | |
| 1060 {% block to_event_target %} | |
| 1061 {% if is_event_target %} | |
| 1062 EventTarget* {{v8_class}}::toEventTarget(v8::Handle<v8::Object> object) | |
| 1063 { | |
| 1064 return toNative(object); | |
| 1065 } | |
| 1066 | |
| 1067 {% endif %} | |
| 1068 {% endblock %} | |
| 1069 | |
| 1070 | |
| 1071 {##############################################################################} | |
| 1072 {% block get_shadow_object_template %} | |
| 1073 {% if interface_name == 'Window' %} | |
| 1074 v8::Handle<v8::ObjectTemplate> V8Window::getShadowObjectTemplate(v8::Isolate* is
olate) | |
| 1075 { | |
| 1076 if (DOMWrapperWorld::current(isolate).isMainWorld()) { | |
| 1077 DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowOb
jectCacheForMainWorld, ()); | |
| 1078 if (V8WindowShadowObjectCacheForMainWorld.IsEmpty()) { | |
| 1079 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BuildDOMTemplate"); | |
| 1080 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isola
te); | |
| 1081 configureShadowObjectTemplate(templ, isolate); | |
| 1082 V8WindowShadowObjectCacheForMainWorld.Reset(isolate, templ); | |
| 1083 return templ; | |
| 1084 } | |
| 1085 return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectC
acheForMainWorld); | |
| 1086 } else { | |
| 1087 DEFINE_STATIC_LOCAL(v8::Persistent<v8::ObjectTemplate>, V8WindowShadowOb
jectCacheForNonMainWorld, ()); | |
| 1088 if (V8WindowShadowObjectCacheForNonMainWorld.IsEmpty()) { | |
| 1089 TRACE_EVENT_SCOPED_SAMPLING_STATE("blink", "BuildDOMTemplate"); | |
| 1090 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isola
te); | |
| 1091 configureShadowObjectTemplate(templ, isolate); | |
| 1092 V8WindowShadowObjectCacheForNonMainWorld.Reset(isolate, templ); | |
| 1093 return templ; | |
| 1094 } | |
| 1095 return v8::Local<v8::ObjectTemplate>::New(isolate, V8WindowShadowObjectC
acheForNonMainWorld); | |
| 1096 } | |
| 1097 } | |
| 1098 | |
| 1099 {% endif %} | |
| 1100 {% endblock %} | |
| 1101 | |
| 1102 | |
| 1103 {##############################################################################} | |
| 1104 {% block wrap %} | |
| 1105 {% if special_wrap_for or is_document %} | |
| 1106 v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creation
Context, v8::Isolate* isolate) | |
| 1107 { | |
| 1108 ASSERT(impl); | |
| 1109 {% for special_wrap_interface in special_wrap_for %} | |
| 1110 if (impl->is{{special_wrap_interface}}()) | |
| 1111 return wrap(to{{special_wrap_interface}}(impl), creationContext, isolate
); | |
| 1112 {% endfor %} | |
| 1113 v8::Handle<v8::Object> wrapper = {{v8_class}}::createWrapper(impl, creationC
ontext, isolate); | |
| 1114 {% if is_document %} | |
| 1115 if (wrapper.IsEmpty()) | |
| 1116 return wrapper; | |
| 1117 DOMWrapperWorld& world = DOMWrapperWorld::current(isolate); | |
| 1118 if (world.isMainWorld()) { | |
| 1119 if (LocalFrame* frame = impl->frame()) | |
| 1120 frame->script().windowProxy(world)->updateDocumentWrapper(wrapper); | |
| 1121 } | |
| 1122 {% endif %} | |
| 1123 return wrapper; | |
| 1124 } | |
| 1125 | |
| 1126 {% elif not has_custom_to_v8 and not has_custom_wrap %} | |
| 1127 v8::Handle<v8::Object> wrap({{cpp_class}}* impl, v8::Handle<v8::Object> creation
Context, v8::Isolate* isolate) | |
| 1128 { | |
| 1129 ASSERT(impl); | |
| 1130 ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl, isolate)); | |
| 1131 return {{v8_class}}::createWrapper(impl, creationContext, isolate); | |
| 1132 } | |
| 1133 | |
| 1134 {% endif %} | |
| 1135 {% endblock %} | |
| 1136 | |
| 1137 | |
| 1138 {##############################################################################} | |
| 1139 {% block create_wrapper %} | |
| 1140 {% if not has_custom_to_v8 %} | |
| 1141 v8::Handle<v8::Object> {{v8_class}}::createWrapper({{pass_cpp_type}} impl, v8::H
andle<v8::Object> creationContext, v8::Isolate* isolate) | |
| 1142 { | |
| 1143 ASSERT(impl); | |
| 1144 ASSERT(!DOMDataStore::containsWrapper<{{v8_class}}>(impl.get(), isolate)); | |
| 1145 {% if is_script_wrappable %} | |
| 1146 const WrapperTypeInfo* actualInfo = impl->wrapperTypeInfo(); | |
| 1147 // Might be a XXXConstructor::wrapperTypeInfo instead of an XXX::wrapperType
Info. These will both have | |
| 1148 // the same object de-ref functions, though, so use that as the basis of the
check. | |
| 1149 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(actualInfo->derefObjectFunction ==
wrapperTypeInfo.derefObjectFunction); | |
| 1150 {% endif %} | |
| 1151 | |
| 1152 {% if is_document %} | |
| 1153 if (LocalFrame* frame = impl->frame()) { | |
| 1154 if (frame->script().initializeMainWorld()) { | |
| 1155 // initializeMainWorld may have created a wrapper for the object, re
try from the start. | |
| 1156 v8::Handle<v8::Object> wrapper = DOMDataStore::getWrapper<{{v8_class
}}>(impl.get(), isolate); | |
| 1157 if (!wrapper.IsEmpty()) | |
| 1158 return wrapper; | |
| 1159 } | |
| 1160 } | |
| 1161 {% endif %} | |
| 1162 v8::Handle<v8::Object> wrapper = V8DOMWrapper::createWrapper(creationContext
, &wrapperTypeInfo, toScriptWrappableBase(impl.get()), isolate); | |
| 1163 if (UNLIKELY(wrapper.IsEmpty())) | |
| 1164 return wrapper; | |
| 1165 | |
| 1166 installConditionallyEnabledProperties(wrapper, isolate); | |
| 1167 V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl, &wrapperTypeInf
o, wrapper, isolate); | |
| 1168 return wrapper; | |
| 1169 } | |
| 1170 | |
| 1171 {% endif %} | |
| 1172 {% endblock %} | |
| 1173 | |
| 1174 | |
| 1175 {##############################################################################} | |
| 1176 {% block deref_object_and_to_v8_no_inline %} | |
| 1177 | |
| 1178 void {{v8_class}}::refObject(ScriptWrappableBase* internalPointer) | |
| 1179 { | |
| 1180 fromInternalPointer(internalPointer)->ref(); | |
| 1181 } | |
| 1182 | |
| 1183 void {{v8_class}}::derefObject(ScriptWrappableBase* internalPointer) | |
| 1184 { | |
| 1185 fromInternalPointer(internalPointer)->deref(); | |
| 1186 } | |
| 1187 | |
| 1188 template<> | |
| 1189 v8::Handle<v8::Value> toV8NoInline({{cpp_class}}* impl, v8::Handle<v8::Object> c
reationContext, v8::Isolate* isolate) | |
| 1190 { | |
| 1191 return toV8(impl, creationContext, isolate); | |
| 1192 } | |
| 1193 | |
| 1194 {% endblock %} | |
| OLD | NEW |