Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl

Issue 2794453002: [Bindings] Replace V8HiddenValue in generated code with V8PrivateProperty (Closed)
Patch Set: . Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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 %}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698