• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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