Home | History | Annotate | Download | only in templates
      1 {##############################################################################}
      2 {% macro attribute_getter(attribute, world_suffix) %}
      3 {% filter conditional(attribute.conditional_string) %}
      4 static void {{attribute.name}}AttributeGetter{{world_suffix}}(
      5 {%- if attribute.is_expose_js_accessors %}
      6 const v8::FunctionCallbackInfo<v8::Value>& info
      7 {%- else %}
      8 const v8::PropertyCallbackInfo<v8::Value>& info
      9 {%- endif %})
     10 {
     11     {% if attribute.is_unforgeable %}
     12     v8::Handle<v8::Object> holder = info.This()->FindInstanceInPrototypeChain({{v8_class}}::domTemplate(info.GetIsolate(), worldType(info.GetIsolate())));
     13     if (holder.IsEmpty())
     14         return;
     15     {{cpp_class}}* imp = {{v8_class}}::toNative(holder);
     16     {% endif %}
     17     {% if attribute.cached_attribute_validation_method %}
     18     v8::Handle<v8::String> propertyName = v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString);
     19     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
     20     if (!imp->{{attribute.cached_attribute_validation_method}}()) {
     21         v8::Handle<v8::Value> jsValue = info.Holder()->GetHiddenValue(propertyName);
     22         if (!jsValue.IsEmpty()) {
     23             v8SetReturnValue(info, jsValue);
     24             return;
     25         }
     26     }
     27     {% elif not (attribute.is_static or attribute.is_unforgeable) %}
     28     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
     29     {% endif %}
     30     {% if attribute.is_call_with_execution_context %}
     31     ExecutionContext* scriptContext = getExecutionContext();
     32     {% endif %}
     33     {# Special cases #}
     34     {% if attribute.is_check_security_for_node or
     35           attribute.is_getter_raises_exception %}
     36     ExceptionState exceptionState(ExceptionState::GetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
     37     {% endif %}
     38     {% if attribute.is_check_security_for_node %}
     39     {# FIXME: consider using a local variable to not call getter twice #}
     40     if (!BindingSecurity::shouldAllowAccessToNode({{attribute.cpp_value}}, exceptionState)) {
     41         v8SetReturnValueNull(info);
     42         exceptionState.throwIfNeeded();
     43         return;
     44     }
     45     {% endif %}
     46     {% if attribute.is_getter_raises_exception %}
     47     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
     48     if (UNLIKELY(exceptionState.throwIfNeeded()))
     49         return;
     50     {% endif %}
     51     {% if attribute.is_nullable %}
     52     bool isNull = false;
     53     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
     54     if (isNull) {
     55         v8SetReturnValueNull(info);
     56         return;
     57     }
     58     {% elif attribute.idl_type == 'EventHandler' or
     59             attribute.cached_attribute_validation_method %}
     60     {# FIXME: consider merging all these assign to local variable statements #}
     61     {{attribute.cpp_type}} {{attribute.cpp_value}} = {{attribute.cpp_value_original}};
     62     {% endif %}
     63     {% if attribute.cached_attribute_validation_method %}
     64     info.Holder()->SetHiddenValue(propertyName, {{attribute.cpp_value}}.v8Value());
     65     {% endif %}
     66     {# End special cases #}
     67     {% if attribute.is_keep_alive_for_gc %}
     68     {{attribute.cpp_type}} result = {{attribute.cpp_value}};
     69     if (result && DOMDataStore::setReturnValueFromWrapper<{{attribute.v8_type}}>(info.GetReturnValue(), result.get()))
     70         return;
     71     v8::Handle<v8::Value> wrapper = toV8(result.get(), info.Holder(), info.GetIsolate());
     72     if (!wrapper.IsEmpty()) {
     73         V8HiddenPropertyName::setNamedHiddenReference(info.Holder(), "{{attribute.name}}", wrapper);
     74         {{attribute.v8_set_return_value}};
     75     }
     76     {% else %}
     77     {{attribute.v8_set_return_value}};
     78     {% endif %}
     79 }
     80 {% endfilter %}
     81 {% endmacro %}
     82 
     83 
     84 {##############################################################################}
     85 {% macro attribute_getter_callback(attribute, world_suffix) %}
     86 {% filter conditional(attribute.conditional_string) %}
     87 static void {{attribute.name}}AttributeGetterCallback{{world_suffix}}(
     88 {%- if attribute.is_expose_js_accessors %}
     89 const v8::FunctionCallbackInfo<v8::Value>& info
     90 {%- else %}
     91 v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info
     92 {%- endif %})
     93 {
     94     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMGetter");
     95     {% if attribute.deprecate_as %}
     96     UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
     97     {% endif %}
     98     {% if attribute.measure_as %}
     99     UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
    100     {% endif %}
    101     {% if world_suffix in attribute.activity_logging_world_list_for_getter %}
    102     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
    103     if (contextData && contextData->activityLogger())
    104         contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 0, 0, "Getter");
    105     {% endif %}
    106     {% if attribute.has_custom_getter %}
    107     {{v8_class}}::{{attribute.name}}AttributeGetterCustom(info);
    108     {% else %}
    109     {{cpp_class}}V8Internal::{{attribute.name}}AttributeGetter{{world_suffix}}(info);
    110     {% endif %}
    111     TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
    112 }
    113 {% endfilter %}
    114 {% endmacro %}
    115 
    116 
    117 {##############################################################################}
    118 {% macro attribute_setter(attribute, world_suffix) %}
    119 {% filter conditional(attribute.conditional_string) %}
    120 static void {{attribute.name}}AttributeSetter{{world_suffix}}(
    121 {%- if attribute.is_expose_js_accessors %}
    122 v8::Local<v8::Value> jsValue, const v8::FunctionCallbackInfo<v8::Value>& info
    123 {%- else %}
    124 v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
    125 {%- endif %})
    126 {
    127     {% if attribute.is_setter_raises_exception or
    128           attribute.has_strict_type_checking %}
    129     ExceptionState exceptionState(ExceptionState::SetterContext, "{{attribute.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
    130     {% endif %}
    131     {% if attribute.has_strict_type_checking %}
    132     {# Type checking for interface types (if interface not implemented, throw
    133        TypeError), per http://www.w3.org/TR/WebIDL/#es-interface #}
    134     if (!isUndefinedOrNull(jsValue) && !V8{{attribute.idl_type}}::hasInstance(jsValue, info.GetIsolate(), worldType(info.GetIsolate()))) {
    135         exceptionState.throwTypeError("The provided value is not of type '{{attribute.idl_type}}'.");
    136         exceptionState.throwIfNeeded();
    137         return;
    138     }
    139     {% endif %}
    140     {% if not attribute.is_static %}
    141     {{cpp_class}}* imp = {{v8_class}}::toNative(info.Holder());
    142     {% endif %}
    143     {% if attribute.idl_type == 'EventHandler' and interface_name == 'Window' %}
    144     if (!imp->document())
    145         return;
    146     {% endif %}
    147     {% if attribute.idl_type != 'EventHandler' %}
    148     {{attribute.v8_value_to_local_cpp_value}};
    149     {% else %}{# EventHandler hack #}
    150     transferHiddenDependency(info.Holder(), {{attribute.event_handler_getter_expression}}, jsValue, {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
    151     {% endif %}
    152     {% if attribute.enum_validation_expression %}
    153     {# Setter ignores invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
    154     String string = cppValue;
    155     if (!({{attribute.enum_validation_expression}}))
    156         return;
    157     {% endif %}
    158     {% if attribute.is_reflect %}
    159     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
    160     {% endif %}
    161     {% if attribute.is_call_with_execution_context %}
    162     ExecutionContext* scriptContext = getExecutionContext();
    163     {% endif %}
    164     {{attribute.cpp_setter}};
    165     {% if attribute.is_setter_raises_exception %}
    166     exceptionState.throwIfNeeded();
    167     {% endif %}
    168     {% if attribute.cached_attribute_validation_method %}
    169     info.Holder()->DeleteHiddenValue(v8::String::NewFromUtf8(info.GetIsolate(), "{{attribute.name}}", v8::String::kInternalizedString)); // Invalidate the cached value.
    170     {% endif %}
    171 }
    172 {% endfilter %}
    173 {% endmacro %}
    174 
    175 
    176 {##############################################################################}
    177 {% macro attribute_setter_callback(attribute, world_suffix) %}
    178 {% filter conditional(attribute.conditional_string) %}
    179 static void {{attribute.name}}AttributeSetterCallback{{world_suffix}}(
    180 {%- if attribute.is_expose_js_accessors %}
    181 const v8::FunctionCallbackInfo<v8::Value>& info
    182 {%- else %}
    183 v8::Local<v8::String>, v8::Local<v8::Value> jsValue, const v8::PropertyCallbackInfo<void>& info
    184 {%- endif %})
    185 {
    186     {% if attribute.is_expose_js_accessors %}
    187     v8::Local<v8::Value> jsValue = info[0];
    188     {% endif %}
    189     TRACE_EVENT_SET_SAMPLING_STATE("Blink", "DOMSetter");
    190     {% if attribute.deprecate_as %}
    191     UseCounter::countDeprecation(activeExecutionContext(), UseCounter::{{attribute.deprecate_as}});
    192     {% endif %}
    193     {% if attribute.measure_as %}
    194     UseCounter::count(activeDOMWindow(), UseCounter::{{attribute.measure_as}});
    195     {% endif %}
    196     {% if world_suffix in attribute.activity_logging_world_list_for_setter %}
    197     V8PerContextData* contextData = V8PerContextData::from(info.GetIsolate()->GetCurrentContext());
    198     if (contextData && contextData->activityLogger()) {
    199         v8::Handle<v8::Value> loggerArg[] = { jsValue };
    200         contextData->activityLogger()->log("{{interface_name}}.{{attribute.name}}", 1, &loggerArg[0], "Setter");
    201     }
    202     {% endif %}
    203     {% if attribute.is_reflect %}
    204     CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;
    205     {% endif %}
    206     {% if attribute.has_custom_setter %}
    207     {{v8_class}}::{{attribute.name}}AttributeSetterCustom(jsValue, info);
    208     {% else %}
    209     {{cpp_class}}V8Internal::{{attribute.name}}AttributeSetter{{world_suffix}}(jsValue, info);
    210     {% endif %}
    211     TRACE_EVENT_SET_SAMPLING_STATE("V8", "Execution");
    212 }
    213 {% endfilter %}
    214 {% endmacro %}
    215