Index: third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl |
diff --git a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl |
index 93dd7c8e93b4aa240283c6c2d70bc6a8232ac12d..698ae1abde2c3fec61c5f3f0f2b07031e5907503 100644 |
--- a/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl |
+++ b/third_party/WebKit/Source/bindings/templates/attributes.cpp.tmpl |
@@ -257,6 +257,15 @@ v8::Local<v8::Private> {{v8_class_or_partial}}::{{attribute.name}}CachedProperty |
} |
{% endmacro %} |
+{##############################################################################} |
+{% macro attribute_cache_init_callback(attribute) %} |
+void {{attribute.name}}CacheInitCallback(v8::Isolate* isolate, v8::Local<v8::Object> holder) |
+{ |
+ auto prop = V8PrivateProperty::Get{{attribute.cached_accessor_name}}(isolate); |
+ {{cpp_class}}* impl = {{v8_class}}::toImpl(holder); |
+ prop.Set(holder, ToV8({{attribute.cpp_value}}, holder, isolate)); |
+} |
+{% endmacro %} |
{##############################################################################} |
{% macro constructor_getter_callback(attribute, world_suffix) %} |
@@ -408,6 +417,11 @@ v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info |
isolate, "{{cpp_class}}#{{attribute.name.capitalize()}}") |
.DeleteProperty(holder, v8::Undefined(isolate)); |
{% endif %} |
+ |
+ {% if attribute.is_lazy_cached_accessor %} |
+ // Call cache init callback to store the correct private property. |
+ {{attribute.name}}CacheInitCallback(info.GetIsolate(), holder); |
+ {% endif %} |
} |
{% endfilter %}{# format_remove_duplicates #} |
{% endmacro %} |
@@ -469,7 +483,7 @@ const v8::FunctionCallbackInfo<v8::Value>& info |
{##############################################################################} |
-{% macro attribute_configuration(attribute) %} |
+{% macro build_attribute_or_accessor_configuration(attribute, is_attribute_configuration) %} |
{% from 'utilities.cpp.tmpl' import property_location %} |
{% if attribute.constructor_type %} |
{% if attribute.needs_constructor_getter_callback %} |
@@ -491,10 +505,15 @@ const v8::FunctionCallbackInfo<v8::Value>& info |
if attribute.constructor_type else 'nullptr' %} |
{% set property_attribute = 'static_cast<v8::PropertyAttribute>(%s)' % |
' | '.join(attribute.property_attributes) %} |
-{% set cached_accessor_callback = |
+{% set cached_property_key = |
'%s::%sCachedPropertyKey' % (v8_class_or_partial, attribute.name) |
if attribute.is_cached_accessor else |
'nullptr' %} |
+{% set cache_init_callback = |
+ '%sV8Internal::%sCacheInitCallback' % |
+ (cpp_class_or_partial, attribute.name) |
+ if attribute.is_lazy_cached_accessor else |
+ 'nullptr' %} |
{% set holder_check = 'V8DOMConfiguration::kDoNotCheckHolder' |
if attribute.is_lenient_this else 'V8DOMConfiguration::kCheckHolder' %} |
{% if attribute.is_per_world_bindings %} |
@@ -502,12 +521,62 @@ const v8::FunctionCallbackInfo<v8::Value>& info |
{% set setter_callback_for_main_world = |
'%sForMainWorld' % setter_callback |
if attribute.has_setter else 'nullptr' %} |
-{"{{attribute.name}}", {{getter_callback_for_main_world}}, {{setter_callback_for_main_world}}, {{cached_accessor_callback}}, {{wrapper_type_info}}, {{property_attribute}}, {{property_location(attribute)}}, {{holder_check}}, V8DOMConfiguration::kMainWorld}, |
-{"{{attribute.name}}", {{getter_callback}}, {{setter_callback}}, {{cached_accessor_callback}}, {{wrapper_type_info}}, {{property_attribute}}, {{property_location(attribute)}}, {{holder_check}}, V8DOMConfiguration::kNonMainWorlds} |
-{%- else %} |
-{"{{attribute.name}}", {{getter_callback}}, {{setter_callback}}, {{cached_accessor_callback}}, {{wrapper_type_info}}, {{property_attribute}}, {{property_location(attribute)}}, {{holder_check}}, V8DOMConfiguration::kAllWorlds} |
-{%- endif %} |
-{%- endmacro %} |
+{% endif %} |
+ |
+ |
+{% set config_pre = { |
+ "main" : [ |
+ '"%s"' % attribute.name, |
+ getter_callback_for_main_world, |
+ setter_callback_for_main_world, |
+ ], |
+ "non_main" : [ |
+ '"%s"' % attribute.name, |
+ getter_callback, |
+ setter_callback, |
+ ], |
+} %} |
+ |
+{% set accessor_only_fields = [] if is_attribute_configuration else [ |
+ cached_property_key, |
+ cache_init_callback, |
+] %} |
+ |
+{% set config_post = [ |
+ wrapper_type_info, |
+ property_attribute, |
+ property_location(attribute), |
+ holder_check, |
+] %} |
+ |
+{% if attribute.is_per_world_bindings %} |
+ {% set main_config_list = config_pre["main"] + accessor_only_fields + |
+ config_post + ['V8DOMConfiguration::kMainWorld'] %} |
+ {% set non_main_config_list = config_pre["non_main"] + accessor_only_fields + |
+ config_post + ['V8DOMConfiguration::kNonMainWorlds'] %} |
+ {# Emit for main world then non-main.#} |
+ {{'{'}}{{main_config_list | join(', ')}}{{'}'}} |
+ {{','}} |
+ {{'{'}}{{non_main_config_list | join(', ')}}{{'}'}} |
+{% else %} |
+ {% set all_worlds_config_list = config_pre["non_main"] + accessor_only_fields + |
+ config_post + ['V8DOMConfiguration::kAllWorlds'] %} |
+ {# Emit only for all worlds #} |
+ {{'{'}}{{all_worlds_config_list | join(', ')}}{{'}'}} |
+{% endif %} |
+{% endmacro %} |
+ |
+{##############################################################################} |
+{% macro attribute_configuration(attribute) %} |
+{% set is_attribute_configuration = true %} |
+{{build_attribute_or_accessor_configuration(attribute, is_attribute_configuration)}} |
+{% endmacro %} |
+ |
+{##############################################################################} |
+{% macro accessor_configuration(attribute) %} |
+{% set is_attribute_configuration = false %} |
+{{build_attribute_or_accessor_configuration(attribute, is_attribute_configuration)}} |
+{% endmacro %} |
{##############################################################################} |
{% macro install_conditionally_enabled_attributes_on_prototype() %} |
@@ -516,7 +585,7 @@ const v8::FunctionCallbackInfo<v8::Value>& info |
{% filter secure_context(attribute.secure_context_test) %} |
{% filter runtime_enabled(attribute.runtime_enabled_feature_name) %} |
static const V8DOMConfiguration::AccessorConfiguration accessorConfiguration[] = { |
- {{attribute_configuration(attribute)}} |
+ {{accessor_configuration(attribute)}} |
}; |
for (const auto& accessorConfig : accessorConfiguration) |
V8DOMConfiguration::InstallAccessor(isolate, world, v8::Local<v8::Object>(), prototypeObject, interfaceObject, signature, accessorConfig); |