Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 {% from 'utilities.cpp.tmpl' import declare_enum_validation_variable, v8_value_t o_local_cpp_value %} | 1 {% from 'utilities.cpp.tmpl' import declare_enum_validation_variable, v8_value_t o_local_cpp_value %} |
| 2 | 2 |
| 3 {##############################################################################} | 3 {##############################################################################} |
| 4 {% macro attribute_getter(attribute, world_suffix) %} | 4 {% macro attribute_getter(attribute, world_suffix) %} |
| 5 static void {{attribute.name}}AttributeGetter{{world_suffix}}( | 5 static void {{attribute.name}}AttributeGetter{{world_suffix}}( |
| 6 {%- if attribute.is_data_type_property %} | 6 {%- if attribute.is_data_type_property %} |
| 7 const v8::PropertyCallbackInfo<v8::Value>& info | 7 const v8::PropertyCallbackInfo<v8::Value>& info |
| 8 {%- else %} | 8 {%- else %} |
| 9 const v8::FunctionCallbackInfo<v8::Value>& info | 9 const v8::FunctionCallbackInfo<v8::Value>& info |
| 10 {%- endif %}) { | 10 {%- endif %}) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 // safe to downcast here. | 53 // safe to downcast here. |
| 54 LocalDOMWindow* impl = toLocalDOMWindow({{v8_class}}::toImpl(holder)); | 54 LocalDOMWindow* impl = toLocalDOMWindow({{v8_class}}::toImpl(holder)); |
| 55 {% endif %}{# attribute.is_check_security_for_receiver #} | 55 {% endif %}{# attribute.is_check_security_for_receiver #} |
| 56 {% else %} | 56 {% else %} |
| 57 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder); | 57 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder); |
| 58 {% endif %}{# local_dom_window_only #} | 58 {% endif %}{# local_dom_window_only #} |
| 59 {% endif %}{# not attribute.is_static #} | 59 {% endif %}{# not attribute.is_static #} |
| 60 | 60 |
| 61 {% if attribute.cached_attribute_validation_method %} | 61 {% if attribute.cached_attribute_validation_method %} |
| 62 // [CachedAttribute] | 62 // [CachedAttribute] |
| 63 v8::Local<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attr ibute.name}}"); | 63 V8PrivateProperty::Symbol propertySymbol = |
| 64 V8PrivateProperty::createSymbol(info.GetIsolate(), "{{cpp_class}}#{{attrib ute.name.capitalize()}}"); | |
| 64 if (!impl->{{attribute.cached_attribute_validation_method}}()) { | 65 if (!impl->{{attribute.cached_attribute_validation_method}}()) { |
| 65 v8::Local<v8::Value> v8Value = V8HiddenValue::getHiddenValue(ScriptState::fo rFunctionObject(info), holder, propertyName); | 66 v8::Local<v8::Value> v8Value = propertySymbol.getOrUndefined(holder); |
| 66 if (!v8Value.IsEmpty() && !v8Value->IsUndefined()) { | 67 if (!v8Value->IsUndefined()) { |
|
Yuki
2017/03/31 13:38:29
With this change, we can no longer cache the value
peria
2017/04/03 04:58:43
IIUC, the old code also did not cache "undefined".
| |
| 67 v8SetReturnValue(info, v8Value); | 68 v8SetReturnValue(info, v8Value); |
| 68 return; | 69 return; |
| 69 } | 70 } |
| 70 } | 71 } |
| 71 {% endif %} | 72 {% endif %} |
| 72 | 73 |
| 73 {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_ property %} | 74 {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_ property %} |
| 74 // Perform a security check for the receiver object. | 75 // Perform a security check for the receiver object. |
| 75 {{define_exception_state}} | 76 {{define_exception_state}} |
| 76 {% if local_dom_window_only %} | 77 {% if local_dom_window_only %} |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 {% if attribute.reflect_only %} | 130 {% if attribute.reflect_only %} |
| 130 {{release_only_check(attribute.reflect_only, attribute.reflect_missing, | 131 {{release_only_check(attribute.reflect_only, attribute.reflect_missing, |
| 131 attribute.reflect_invalid, attribute.reflect_empty, | 132 attribute.reflect_invalid, attribute.reflect_empty, |
| 132 attribute.cpp_value) | 133 attribute.cpp_value) |
| 133 | indent(2)}} | 134 | indent(2)}} |
| 134 {% endif %} | 135 {% endif %} |
| 135 | 136 |
| 136 {% if attribute.cached_attribute_validation_method %} | 137 {% if attribute.cached_attribute_validation_method %} |
| 137 // [CachedAttribute] | 138 // [CachedAttribute] |
| 138 v8::Local<v8::Value> v8Value({{attribute.cpp_value_to_v8_value}}); | 139 v8::Local<v8::Value> v8Value({{attribute.cpp_value_to_v8_value}}); |
| 139 V8HiddenValue::setHiddenValue(ScriptState::forFunctionObject(info), holder, pr opertyName, v8Value); | 140 propertySymbol.set(holder, v8Value); |
| 140 {% endif %} | 141 {% endif %} |
| 141 | 142 |
| 142 {% if attribute.is_explicit_nullable %} | 143 {% if attribute.is_explicit_nullable %} |
| 143 if (isNull) { | 144 if (isNull) { |
| 144 v8SetReturnValueNull(info); | 145 v8SetReturnValueNull(info); |
| 145 return; | 146 return; |
| 146 } | 147 } |
| 147 {% endif %} | 148 {% endif %} |
| 148 | 149 |
| 149 {% if attribute.is_keep_alive_for_gc %} | 150 {% if attribute.is_keep_alive_for_gc %} |
| 150 // Keep the wrapper object for the return value alive as long as |this| | 151 // Keep the wrapper object for the return value alive as long as |this| |
| 151 // object is alive in order to save creation time of the wrapper object. | 152 // object is alive in order to save creation time of the wrapper object. |
| 152 if ({{attribute.cpp_value}} && DOMDataStore::setReturnValue{{world_suffix}}(in fo.GetReturnValue(), {{attribute.cpp_value}})) | 153 if ({{attribute.cpp_value}} && DOMDataStore::setReturnValue{{world_suffix}}(in fo.GetReturnValue(), {{attribute.cpp_value}})) |
| 153 return; | 154 return; |
| 154 v8::Local<v8::Value> v8Value(ToV8({{attribute.cpp_value}}, holder, info.GetIso late())); | 155 v8::Local<v8::Value> v8Value(ToV8({{attribute.cpp_value}}, holder, info.GetIso late())); |
| 155 V8HiddenValue::setHiddenValue(ScriptState::current(info.GetIsolate()), holder, v8AtomicString(info.GetIsolate(), "KeepAlive#{{interface_name}}#{{attribute.nam e}}"), v8Value); | 156 V8PrivateProperty::createSymbol( |
| 157 info.GetIsolate(), "KeepAlive#{{interface_name}}#{{attribute.name}}") | |
| 158 .set(holder, v8Value); | |
| 156 {% endif %} | 159 {% endif %} |
| 157 | 160 |
| 158 {% if world_suffix %} | 161 {% if world_suffix %} |
| 159 {{attribute.v8_set_return_value_for_main_world}}; | 162 {{attribute.v8_set_return_value_for_main_world}}; |
| 160 {% else %} | 163 {% else %} |
| 161 {{attribute.v8_set_return_value}}; | 164 {{attribute.v8_set_return_value}}; |
| 162 {% endif %} | 165 {% endif %} |
| 163 | 166 |
| 164 {% if attribute.is_save_same_object %} | 167 {% if attribute.is_save_same_object %} |
| 165 // [SaveSameObject] | 168 // [SaveSameObject] |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 {% macro attribute_setter(attribute, world_suffix) %} | 277 {% macro attribute_setter(attribute, world_suffix) %} |
| 275 static void {{attribute.name}}AttributeSetter{{world_suffix}}( | 278 static void {{attribute.name}}AttributeSetter{{world_suffix}}( |
| 276 {%- if attribute.has_cross_origin_setter %} | 279 {%- if attribute.has_cross_origin_setter %} |
| 277 v8::Local<v8::Value> v8Value, const V8CrossOriginSetterInfo& info | 280 v8::Local<v8::Value> v8Value, const V8CrossOriginSetterInfo& info |
| 278 {%- elif attribute.is_data_type_property %} | 281 {%- elif attribute.is_data_type_property %} |
| 279 v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info | 282 v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info |
| 280 {%- else %} | 283 {%- else %} |
| 281 v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info | 284 v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info |
| 282 {%- endif %}) { | 285 {%- endif %}) { |
| 283 {% filter format_remove_duplicates(['ExceptionState exceptionState']) %} | 286 {% filter format_remove_duplicates(['ExceptionState exceptionState']) %} |
| 287 v8::Isolate* isolate = info.GetIsolate(); | |
| 288 ALLOW_UNUSED_LOCAL(isolate); | |
| 289 | |
| 284 {% set define_exception_state -%} | 290 {% set define_exception_state -%} |
| 285 ExceptionState exceptionState(info.GetIsolate(), ExceptionState::SetterContext , "{{interface_name}}", "{{attribute.name}}"); | 291 ExceptionState exceptionState(isolate, ExceptionState::SetterContext, "{{inter face_name}}", "{{attribute.name}}"); |
| 286 {%- endset %} | 292 {%- endset %} |
| 287 | 293 |
| 288 {% if attribute.is_lenient_this %} | 294 {% if attribute.is_lenient_this %} |
| 289 // [LenientThis] | 295 // [LenientThis] |
| 290 // Make sure that info.Holder() really points to an instance if [LenientThis]. | 296 // Make sure that info.Holder() really points to an instance if [LenientThis]. |
| 291 if (!{{v8_class}}::hasInstance(info.Holder(), info.GetIsolate())) | 297 if (!{{v8_class}}::hasInstance(info.Holder(), isolate)) |
| 292 return; // Return silently because of [LenientThis]. | 298 return; // Return silently because of [LenientThis]. |
| 293 {% endif %} | 299 {% endif %} |
| 294 | 300 |
| 295 {% if not attribute.is_static and not attribute.is_replaceable %} | 301 {% if not attribute.is_static and not attribute.is_replaceable %} |
| 296 v8::Local<v8::Object> holder = info.Holder(); | 302 v8::Local<v8::Object> holder = info.Holder(); |
| 297 {% if attribute.is_put_forwards %} | 303 {% if attribute.is_put_forwards %} |
| 298 {{cpp_class}}* proxyImpl = {{v8_class}}::toImpl(holder); | 304 {{cpp_class}}* proxyImpl = {{v8_class}}::toImpl(holder); |
| 299 {{attribute.cpp_type}} impl = WTF::getPtr(proxyImpl->{{attribute.name}}()); | 305 {{attribute.cpp_type}} impl = WTF::getPtr(proxyImpl->{{attribute.name}}()); |
| 300 if (!impl) | 306 if (!impl) |
| 301 return; | 307 return; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 313 {% else %} | 319 {% else %} |
| 314 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder); | 320 {{cpp_class}}* impl = {{v8_class}}::toImpl(holder); |
| 315 {% endif %}{# local_dom_window_only #} | 321 {% endif %}{# local_dom_window_only #} |
| 316 {% endif %} | 322 {% endif %} |
| 317 {% endif %} | 323 {% endif %} |
| 318 | 324 |
| 319 {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_ property %} | 325 {% if attribute.is_check_security_for_receiver and not attribute.is_data_type_ property %} |
| 320 // Perform a security check for the receiver object. | 326 // Perform a security check for the receiver object. |
| 321 {{define_exception_state}} | 327 {{define_exception_state}} |
| 322 {% if local_dom_window_only %} | 328 {% if local_dom_window_only %} |
| 323 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()), uncheckedImpl, exceptionState)) { | 329 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(isolate), unchecked Impl, exceptionState)) { |
| 324 {% else %} | 330 {% else %} |
| 325 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(info.GetIsolate()), impl, exceptionState)) { | 331 if (!BindingSecurity::shouldAllowAccessTo(currentDOMWindow(isolate), impl, exc eptionState)) { |
| 326 {% endif %}{# local_dom_window_only #} | 332 {% endif %}{# local_dom_window_only #} |
| 327 v8SetReturnValue(info, v8Value); | 333 v8SetReturnValue(info, v8Value); |
| 328 return; | 334 return; |
| 329 } | 335 } |
| 330 {% if local_dom_window_only %} | 336 {% if local_dom_window_only %} |
| 331 LocalDOMWindow* impl = toLocalDOMWindow(uncheckedImpl); | 337 LocalDOMWindow* impl = toLocalDOMWindow(uncheckedImpl); |
| 332 {% endif %}{# local_dom_window_only #} | 338 {% endif %}{# local_dom_window_only #} |
| 333 {% endif %} | 339 {% endif %} |
| 334 | 340 |
| 335 {% if attribute.is_check_security_for_return_value %} | 341 {% if attribute.is_check_security_for_return_value %} |
| 336 #error Attribute setter with the security check for the return value is not supp orted. Since the return value is the given value to be set, it\'s meaningless t o perform the security check for the return value. | 342 #error Attribute setter with the security check for the return value is not supp orted. Since the return value is the given value to be set, it\'s meaningless t o perform the security check for the return value. |
| 337 {% endif %} | 343 {% endif %} |
| 338 | 344 |
| 339 {% if attribute.is_custom_element_callbacks or | 345 {% if attribute.is_custom_element_callbacks or |
| 340 (attribute.is_reflect and not (attribute.idl_type == 'DOMString' and is_ node)) %} | 346 (attribute.is_reflect and not (attribute.idl_type == 'DOMString' and is_ node)) %} |
| 341 // Skip on compact node DOMString getters. | 347 // Skip on compact node DOMString getters. |
| 342 V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope; | 348 V0CustomElementProcessingStack::CallbackDeliveryScope deliveryScope; |
| 343 {% endif %} | 349 {% endif %} |
| 344 | 350 |
| 345 {% if attribute.has_setter_exception_state %} | 351 {% if attribute.has_setter_exception_state %} |
| 346 {{define_exception_state}} | 352 {{define_exception_state}} |
| 347 {% endif %} | 353 {% endif %} |
| 348 | 354 |
| 349 // Prepare the value to be set. | 355 // Prepare the value to be set. |
| 350 {% if attribute.idl_type == 'EventHandler' %} | 356 {% if attribute.idl_type == 'EventHandler' %} |
| 351 {% if not is_node %} | 357 {% if not is_node %} |
| 352 moveEventListenerToNewWrapper(info.GetIsolate(), holder, {{attribute.event_han dler_getter_expression}}, v8Value, {{v8_class}}::eventListenerCacheIndex); | 358 moveEventListenerToNewWrapper(isolate, holder, {{attribute.event_handler_gette r_expression}}, v8Value, {{v8_class}}::eventListenerCacheIndex); |
| 353 {% endif %} | 359 {% endif %} |
| 354 {% else %}{# not EventHandler #} | 360 {% else %}{# not EventHandler #} |
| 355 {{v8_value_to_local_cpp_value(attribute) | indent(2)}} | 361 {{v8_value_to_local_cpp_value(attribute) | indent(2)}} |
| 356 {% endif %} | 362 {% endif %} |
| 357 | 363 |
| 358 {% if attribute.has_type_checking_interface %} | 364 {% if attribute.has_type_checking_interface %} |
| 359 // Type check per: http://heycam.github.io/webidl/#es-interface | 365 // Type check per: http://heycam.github.io/webidl/#es-interface |
| 360 if (!cppValue{% if attribute.is_nullable %} && !isUndefinedOrNull(v8Value){% e ndif %}) { | 366 if (!cppValue{% if attribute.is_nullable %} && !isUndefinedOrNull(v8Value){% e ndif %}) { |
| 361 exceptionState.throwTypeError("The provided value is not of type '{{attribut e.idl_type}}'."); | 367 exceptionState.throwTypeError("The provided value is not of type '{{attribut e.idl_type}}'."); |
| 362 return; | 368 return; |
| 363 } | 369 } |
| 364 {% endif %} | 370 {% endif %} |
| 365 | 371 |
| 366 {% if attribute.enum_values %} | 372 {% if attribute.enum_values %} |
| 367 // Type check per: http://heycam.github.io/webidl/#dfn-attribute-setter | 373 // Type check per: http://heycam.github.io/webidl/#dfn-attribute-setter |
| 368 // Returns undefined without setting the value if the value is invalid. | 374 // Returns undefined without setting the value if the value is invalid. |
| 369 DummyExceptionStateForTesting dummyExceptionState; | 375 DummyExceptionStateForTesting dummyExceptionState; |
| 370 {{declare_enum_validation_variable(attribute.enum_values) | indent(2)}} | 376 {{declare_enum_validation_variable(attribute.enum_values) | indent(2)}} |
| 371 if (!isValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "{{attr ibute.enum_type}}", dummyExceptionState)) { | 377 if (!isValidEnum(cppValue, validValues, WTF_ARRAY_LENGTH(validValues), "{{attr ibute.enum_type}}", dummyExceptionState)) { |
| 372 currentExecutionContext(info.GetIsolate())->addConsoleMessage(ConsoleMessage ::create(JSMessageSource, WarningMessageLevel, dummyExceptionState.message())); | 378 currentExecutionContext(isolate)->addConsoleMessage(ConsoleMessage::create(J SMessageSource, WarningMessageLevel, dummyExceptionState.message())); |
| 373 return; | 379 return; |
| 374 } | 380 } |
| 375 {% endif %} | 381 {% endif %} |
| 376 | 382 |
| 377 {% if attribute.is_call_with_execution_context or attribute.is_setter_call_wit h_execution_context %} | 383 {% if attribute.is_call_with_execution_context or attribute.is_setter_call_wit h_execution_context %} |
| 378 ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate() ); | 384 ExecutionContext* executionContext = currentExecutionContext(isolate); |
| 379 {% endif %} | 385 {% endif %} |
| 380 | 386 |
| 381 {% if attribute.is_call_with_script_state %} | 387 {% if attribute.is_call_with_script_state %} |
| 382 {% if attribute.is_static %} | 388 {% if attribute.is_static %} |
| 383 ScriptState* scriptState = ScriptState::forFunctionObject(info); | 389 ScriptState* scriptState = ScriptState::forFunctionObject(info); |
| 384 {% else %} | 390 {% else %} |
| 385 ScriptState* scriptState = ScriptState::forReceiverObject(info); | 391 ScriptState* scriptState = ScriptState::forReceiverObject(info); |
| 386 {% endif %} | 392 {% endif %} |
| 387 {% endif %} | 393 {% endif %} |
| 388 | 394 |
| 389 {% if attribute.is_replaceable %} | 395 {% if attribute.is_replaceable %} |
| 390 v8::Local<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attr ibute.name}}"); | 396 v8::Local<v8::String> propertyName = v8AtomicString(isolate, "{{attribute.name }}"); |
| 391 {% endif %} | 397 {% endif %} |
| 392 {{attribute.cpp_setter}}; | 398 {{attribute.cpp_setter}}; |
| 393 | 399 |
| 394 {% if attribute.cached_attribute_validation_method %} | 400 {% if attribute.cached_attribute_validation_method %} |
| 395 // [CachedAttribute] | 401 // [CachedAttribute] |
| 396 // Invalidate the cached value. | 402 // Invalidate the cached value. Actually deleting the attribute would make |
| 397 V8HiddenValue::deleteHiddenValue(ScriptState::forFunctionObject(info), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}")); | 403 // force the object into dictionary mode which is unnecessarily slow. |
| 404 // Instead, we replace the cached value with "undefined". | |
|
Yuki
2017/03/31 13:38:29
Is this really happening so often? I'd expect tha
peria
2017/04/03 04:58:43
I agree. It happens rarely.
| |
| 405 V8PrivateProperty::createSymbol( | |
| 406 isolate, "{{cpp_class}}#{{attribute.name.capitalize()}}") | |
| 407 .set(holder, v8::Undefined(isolate)); | |
| 398 {% endif %} | 408 {% endif %} |
| 399 } | 409 } |
| 400 {% endfilter %}{# format_remove_duplicates #} | 410 {% endfilter %}{# format_remove_duplicates #} |
| 401 {% endmacro %} | 411 {% endmacro %} |
| 402 | 412 |
| 403 | 413 |
| 404 {##############################################################################} | 414 {##############################################################################} |
| 405 {% macro attribute_setter_callback(attribute, world_suffix) %} | 415 {% macro attribute_setter_callback(attribute, world_suffix) %} |
| 406 void {{v8_class_or_partial}}::{{attribute.name}}AttributeSetterCallback{{world_s uffix}}( | 416 void {{v8_class_or_partial}}::{{attribute.name}}AttributeSetterCallback{{world_s uffix}}( |
| 407 {%- if attribute.is_data_type_property %} | 417 {%- if attribute.is_data_type_property %} |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 static const V8DOMConfiguration::AccessorConfiguration accessorConfiguration[] = { | 516 static const V8DOMConfiguration::AccessorConfiguration accessorConfiguration[] = { |
| 507 {{attribute_configuration(attribute)}} | 517 {{attribute_configuration(attribute)}} |
| 508 }; | 518 }; |
| 509 for (const auto& accessorConfig : accessorConfiguration) | 519 for (const auto& accessorConfig : accessorConfiguration) |
| 510 V8DOMConfiguration::installAccessor(isolate, world, v8::Local<v8::Object>(), p rototypeObject, interfaceObject, signature, accessorConfig); | 520 V8DOMConfiguration::installAccessor(isolate, world, v8::Local<v8::Object>(), p rototypeObject, interfaceObject, signature, accessorConfig); |
| 511 {% endfilter %}{# runtime_enabled #} | 521 {% endfilter %}{# runtime_enabled #} |
| 512 {% endfilter %}{# secure_context #} | 522 {% endfilter %}{# secure_context #} |
| 513 {% endfilter %}{# exposed #} | 523 {% endfilter %}{# exposed #} |
| 514 {% endfor %} | 524 {% endfor %} |
| 515 {% endmacro %} | 525 {% endmacro %} |
| OLD | NEW |