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