summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp')
-rw-r--r--chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp271
1 files changed, 205 insertions, 66 deletions
diff --git a/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp b/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
index cbbe4192db6..c25e298e314 100644
--- a/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
+++ b/chromium/third_party/WebKit/Source/bindings/templates/attributes.cpp
@@ -8,71 +8,104 @@ const v8::FunctionCallbackInfo<v8::Value>& info
const v8::PropertyCallbackInfo<v8::Value>& info
{%- endif %})
{
- {% if attribute.is_unforgeable %}
- v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
+ {% if attribute.is_reflect and not attribute.is_url and
+ attribute.idl_type == 'DOMString' and is_node %}
+ {% set cpp_class, v8_class = 'Element', 'V8Element' %}
+ {% endif %}
+ {# holder #}
+ {% if attribute.is_unforgeable and interface_name != 'Window' %}
+ {# perform lookup first #}
+ {# FIXME: can we remove this lookup? #}
+ v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
if (holder.IsEmpty())
return;
- {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
+ {% elif not attribute.is_static %}
+ v8::Handle<v8::Object> holder = info.Holder();
{% endif %}
+ {# impl #}
{% if attribute.cached_attribute_validation_method %}
- v8::Handle<v8::String> propertyName = v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString);
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
- if (!imp->{{attribute.cached_attribute_validation_method}}()) {
- v8::Handle<v8::Value> jsValue = info.Holder()->GetHiddenValue(propertyName);
- if (!jsValue.IsEmpty()) {
- v8SetReturnValue(info, jsValue);
+ v8::Handle<v8::String> propertyName = v8AtomicString(info.GetIsolate(), "{{attribute.name}}");
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
+ if (!impl->{{attribute.cached_attribute_validation_method}}()) {
+ v8::Handle<v8::Value> v8Value = V8HiddenValue::getHiddenValue(info.GetIsolate(), holder, propertyName);
+ if (!v8Value.IsEmpty()) {
+ v8SetReturnValue(info, v8Value);
return;
}
}
- {% elif not (attribute.is_static or attribute.is_unforgeable) %}
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
+ {% elif not attribute.is_static %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
+ {% endif %}
+ {% if interface_name == 'Window' and attribute.idl_type == 'EventHandler' %}
+ if (!impl->document())
+ return;
{% endif %}
+ {# Local variables #}
{% if attribute.is_call_with_execution_context %}
- ExecutionContext* scriptContext = getExecutionContext();
+ ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
+ {% endif %}
+ {% if attribute.is_call_with_script_state %}
+ ScriptState* scriptState = ScriptState::current(info.GetIsolate());
{% endif %}
- {# Special cases #}
{% if attribute.is_check_security_for_node or
attribute.is_getter_raises_exception %}
- ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
+ ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
+ {% endif %}
+ {% if attribute.is_nullable and not attribute.has_type_checking_nullable %}
+ bool isNull = false;
+ {% endif %}
+ {# FIXME: consider always using a local variable for value #}
+ {% if attribute.cached_attribute_validation_method or
+ attribute.is_getter_raises_exception or
+ attribute.is_nullable or
+ attribute.reflect_only or
+ attribute.idl_type == 'EventHandler' %}
+ {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
+ {% endif %}
+ {# Checks #}
+ {% if attribute.is_getter_raises_exception %}
+ if (UNLIKELY(exceptionState.throwIfNeeded()))
+ return;
{% endif %}
{% if attribute.is_check_security_for_node %}
- {# FIXME: consider using a local variable to not call getter twice #}
- if (!BindingSecurity::shouldAllowAccessToNode({{attribute.cpp_value}}, exceptionState)) {
+ {# FIXME: use a local variable to not call getter twice #}
+ if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), {{attribute.cpp_value}}, exceptionState)) {
v8SetReturnValueNull(info);
exceptionState.throwIfNeeded();
return;
}
{% endif %}
- {% if attribute.is_getter_raises_exception %}
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
- if (UNLIKELY(exceptionState.throwIfNeeded()))
- return;
+ {% if attribute.reflect_only %}
+ {{release_only_check(attribute.reflect_only, attribute.reflect_missing,
+ attribute.reflect_invalid, attribute.reflect_empty)
+ | indent}}
{% endif %}
{% if attribute.is_nullable %}
- bool isNull = false;
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
+ {% if attribute.has_type_checking_nullable %}
+ if (!{{attribute.cpp_value}}) {
+ {% else %}
if (isNull) {
+ {% endif %}
v8SetReturnValueNull(info);
return;
}
- {% elif attribute.idl_type == 'EventHandler' or
- attribute.cached_attribute_validation_method %}
- {# FIXME: consider merging all these assign to local variable statements #}
- {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
{% endif %}
{% if attribute.cached_attribute_validation_method %}
- info.Holder()->SetHiddenValue(propertyName, {{attribute.cpp_value}}.v8Value());
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, propertyName, {{attribute.cpp_value_to_v8_value}});
{% endif %}
- {# End special cases #}
+ {# v8SetReturnValue #}
{% if attribute.is_keep_alive_for_gc %}
- {{attribute.cpp_type}} result = {{attribute.cpp_value}};
- if (result && DOMDataStore::setReturnValueFromWrapper<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
+ {# FIXME: merge local variable assignment with above #}
+ {{attribute.cpp_type}} result({{attribute.cpp_value}});
+ if (result && DOMDataStore::setReturnValueFromWrapper{{world_suffix}}<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
return;
- v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());
+ v8::Handle<v8::Value> wrapper = toV8(result.get(), holder, info.GetIsolate());
if (!wrapper.IsEmpty()) {
- V8HiddenPropertyName::setNamedHiddenReference(info.Holder(), "{{attribute.name}}", wrapper);
+ V8HiddenValue::setHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}"), wrapper);
{{attribute.v8_set_return_value}};
}
+ {% elif world_suffix %}
+ {{attribute.v8_set_return_value_for_main_world}};
{% else %}
{{attribute.v8_set_return_value}};
{% endif %}
@@ -80,6 +113,39 @@ const v8::PropertyCallbackInfo<v8::Value>& info
{% endfilter %}
{% endmacro %}
+{######################################}
+{% macro release_only_check(reflect_only_values, reflect_missing,
+ reflect_invalid, reflect_empty) %}
+{# Attribute is limited to only known values: check that the attribute value is
+ one of those. If not, set it to the empty string.
+ http://www.whatwg.org/specs/web-apps/current-work/#limited-to-only-known-values #}
+{% if reflect_empty %}
+if (v8Value.isNull()) {
+{% if reflect_missing %}
+ v8Value = "{{reflect_missing}}";
+{% else %}
+ ;
+{% endif %}
+} else if (v8Value.isEmpty()) {
+ v8Value = "{{reflect_empty}}";
+{% else %}
+if (v8Value.isEmpty()) {
+{# FIXME: should use [ReflectEmpty] instead; need to change IDL files #}
+{% if reflect_missing %}
+ v8Value = "{{reflect_missing}}";
+{% else %}
+ ;
+{% endif %}
+{% endif %}
+{% for value in reflect_only_values %}
+} else if (equalIgnoringCase(v8Value, "{{value}}")) {
+ v8Value = "{{value}}";
+{% endfor %}
+} else {
+ v8Value = "{{reflect_invalid}}";
+}
+{% endmacro %}
+
{##############################################################################}
{% macro attribute_getter_callback(attribute, world_suffix) %}
@@ -93,22 +159,46 @@ v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
{
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
{% if attribute.deprecate_as %}
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
{% endif %}
{% if attribute.measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
{% endif %}
{% if world_suffix in attribute.activity_logging_world_list_for_getter %}
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
+ ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
+ V8PerContextData* contextData = scriptState->perContextData();
+ {% if attribute.activity_logging_world_check %}
+ if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
+ {% else %}
if (contextData && contextData->activityLogger())
- contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 0, 0, "Getter");
+ {% endif %}
+ contextData->activityLogger()->logGetter("{{interface_name}}.{{attribute.name}}");
{% endif %}
{% if attribute.has_custom_getter %}
{{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
{% else %}
{{cpp_class}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
{% endif %}
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
+}
+{% endfilter %}
+{% endmacro %}
+
+
+{##############################################################################}
+{% macro constructor_getter_callback(attribute, world_suffix) %}
+{% filter conditional(attribute.conditional_string) %}
+static void {{attribute.name}}ConstructorGetterCallback{{world_suffix}}(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
+ {% if attribute.deprecate_as %}
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
+ {% endif %}
+ {% if attribute.measure_as %}
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
+ {% endif %}
+ {{cpp_class}}V8Internal::{{cpp_class}}ConstructorGetter{{world_suffix}}(property, info);
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endfilter %}
{% endmacro %}
@@ -119,54 +209,88 @@ v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
{% filter conditional(attribute.conditional_string) %}
static void {{attribute.name}}AttributeSetter{{world_suffix}}(
{%- if attribute.is_expose_js_accessors %}
-v8::Local<v8::Value> jsValue, const v8::FunctionCallbackInfo<v8::Value>& info
+v8::Local<v8::Value> v8Value, const v8::FunctionCallbackInfo<v8::Value>& info
{%- else %}
-v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
+v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- endif %})
{
- {% if attribute.is_setter_raises_exception or
- attribute.has_strict_type_checking %}
- ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
+ {% if attribute.is_reflect and attribute.idl_type == 'DOMString' and
+ is_node %}
+ {% set cpp_class, v8_class = 'Element', 'V8Element' %}
+ {% endif %}
+ {# Local variables #}
+ {% if not attribute.is_static %}
+ v8::Handle<v8::Object> holder = info.Holder();
{% endif %}
- {% if attribute.has_strict_type_checking %}
+ {% if attribute.has_setter_exception_state %}
+ ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", holder, info.GetIsolate());
+ {% endif %}
+ {# Type checking #}
+ {% if attribute.has_type_checking_interface %}
{# Type checking for interface types (if interface not implemented, throw
TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
- if (!isUndefinedOrNull(jsValue) && !V8{{attribute.idl_type}}::hasInstance(jsValue, info.GetIsolate(), worldType(info.GetIsolate()))) {
+ if ({% if attribute.is_nullable %}!isUndefinedOrNull(v8Value) && {% endif %}!V8{{attribute.idl_type}}::hasInstance(v8Value, info.GetIsolate())) {
exceptionState.throwTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
exceptionState.throwIfNeeded();
return;
}
{% endif %}
- {% if not attribute.is_static %}
- {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
+ {# impl #}
+ {% if attribute.put_forwards %}
+ {{cpp_class}}* proxyImpl = {{v8_class}}::toNative(holder);
+ {{attribute.cpp_type}} impl = WTF::getPtr(proxyImpl->{{attribute.name}}());
+ if (!impl)
+ return;
+ {% elif not attribute.is_static %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(holder);
{% endif %}
{% if attribute.idl_type == 'EventHandler' and interface_name == 'Window' %}
- if (!imp->document())
+ if (!impl->document())
return;
{% endif %}
+ {# Convert JS value to C++ value #}
{% if attribute.idl_type != 'EventHandler' %}
{{attribute.v8_value_to_local_cpp_value}};
- {% else %}{# EventHandler hack #}
- transferHiddenDependency(info.Holder(), {{attribute.event_handler_getter_expression}}, jsValue, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
+ {% elif not is_node %}{# EventHandler hack #}
+ moveEventListenerToNewWrapper(holder, {{attribute.event_handler_getter_expression}}, v8Value, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
{% endif %}
- {% if attribute.enum_validation_expression %}
- {# Setter ignores invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
+ {# Type checking, possibly throw a TypeError, per:
+ http://www.w3.org/TR/WebIDL/#es-type-mapping #}
+ {% if attribute.has_type_checking_unrestricted %}
+ {# Non-finite floating point values (NaN, +Infinity or −Infinity), per:
+ http://heycam.github.io/webidl/#es-float
+ http://heycam.github.io/webidl/#es-double #}
+ if (!std::isfinite(cppValue)) {
+ exceptionState.throwTypeError("The provided {{attribute.idl_type}} value is non-finite.");
+ exceptionState.throwIfNeeded();
+ return;
+ }
+ {% elif attribute.enum_validation_expression %}
+ {# Setter ignores invalid enum values:
+ http://www.w3.org/TR/WebIDL/#idl-enums #}
String string = cppValue;
if (!({{attribute.enum_validation_expression}}))
return;
{% endif %}
- {% if attribute.is_reflect %}
+ {# Pre-set context #}
+ {% if attribute.is_custom_element_callbacks or
+ (attribute.is_reflect and
+ not(attribute.idl_type == 'DOMString' and is_node)) %}
+ {# Skip on compact node DOMString getters #}
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
{% endif %}
- {% if attribute.is_call_with_execution_context %}
- ExecutionContext* scriptContext = getExecutionContext();
+ {% if attribute.is_call_with_execution_context or
+ attribute.is_setter_call_with_execution_context %}
+ ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
{% endif %}
+ {# Set #}
{{attribute.cpp_setter}};
+ {# Post-set #}
{% if attribute.is_setter_raises_exception %}
exceptionState.throwIfNeeded();
{% endif %}
{% if attribute.cached_attribute_validation_method %}
- info.Holder()->DeleteHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString)); // Invalidate the cached value.
+ V8HiddenValue::deleteHiddenValue(info.GetIsolate(), holder, v8AtomicString(info.GetIsolate(), "{{attribute.name}}")); // Invalidate the cached value.
{% endif %}
}
{% endfilter %}
@@ -180,35 +304,50 @@ static void {{attribute.name}}AttributeSetterCallback{{world_suffix}}(
{%- if attribute.is_expose_js_accessors %}
const v8::FunctionCallbackInfo<v8::Value>& info
{%- else %}
-v8::Local<v8::String>, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
+v8::Local<v8::String>, v8::Local<v8::Value> v8Value, const v8::PropertyCallbackInfo<void>& info
{%- endif %})
{
{% if attribute.is_expose_js_accessors %}
- v8::Local<v8::Value> jsValue = info[0];
+ v8::Local<v8::Value> v8Value = info[0];
{% endif %}
TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
{% if attribute.deprecate_as %}
- UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
+ UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.deprecate_as}});
{% endif %}
{% if attribute.measure_as %}
- UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
+ UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{attribute.measure_as}});
{% endif %}
{% if world_suffix in attribute.activity_logging_world_list_for_setter %}
- V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
+ ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
+ V8PerContextData* contextData = scriptState->perContextData();
+ {% if attribute.activity_logging_world_check %}
+ if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger()) {
+ {% else %}
if (contextData && contextData->activityLogger()) {
- v8::Handle<v8::Value> loggerArg[] = { jsValue };
- contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 1, &loggerArg[0], "Setter");
+ {% endif %}
+ {% if attribute.activity_logging_include_old_value_for_setter %}
+ {{cpp_class}}* impl = {{v8_class}}::toNative(info.Holder());
+ {% if attribute.cpp_value_original %}
+ {{attribute.cpp_type}} original = {{attribute.cpp_value_original}};
+ {% else %}
+ {{attribute.cpp_type}} original = {{attribute.cpp_value}};
+ {% endif %}
+ v8::Handle<v8::Value> originalValue = {{attribute.cpp_value_to_v8_value}};
+ contextData->activityLogger()->logSetter("{{interface_name}}.{{attribute.name}}", v8Value, originalValue);
+ {% else %}
+ contextData->activityLogger()->logSetter("{{interface_name}}.{{attribute.name}}", v8Value);
+ {% endif %}
}
{% endif %}
- {% if attribute.is_reflect %}
+ {% if attribute.is_custom_element_callbacks or attribute.is_reflect %}
CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
{% endif %}
{% if attribute.has_custom_setter %}
- {{v8_class}}::{{attribute.name}}AttributeSetterCustom(jsValue, info);
+ {{v8_class}}::{{attribute.name}}AttributeSetterCustom(v8Value, info);
{% else %}
- {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(jsValue, info);
+ {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(v8Value, info);
{% endif %}
- TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
+ TRACE_EVENT_SET_SAMPLING_STATE("V8", "V8Execution");
}
{% endfilter %}
{% endmacro %}