Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / templates / methods.cpp
1 {##############################################################################}
2 {% macro generate_method(method, world_suffix) %}
3 {% filter conditional(method.conditional_string) %}
4 static void {{method.name}}{{method.overload_index}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
5 {
6     {# Local variables #}
7     {% if method.has_exception_state %}
8     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
9     {% endif %}
10     {# Overloaded methods have length checked during overload resolution #}
11     {% if method.number_of_required_arguments and not method.overload_index %}
12     if (UNLIKELY(info.Length() < {{method.number_of_required_arguments}})) {
13         {{throw_minimum_arity_type_error(method, method.number_of_required_arguments) | indent(8)}}
14         return;
15     }
16     {% endif %}
17     {% if not method.is_static %}
18     {{cpp_class}}* impl = {{v8_class}}::toImpl(info.Holder());
19     {% endif %}
20     {% if method.is_custom_element_callbacks %}
21     CustomElementProcessingStack::CallbackDeliveryScope deliveryScope;
22     {% endif %}
23     {# Security checks #}
24     {% if method.is_check_security_for_window %}
25     if (LocalDOMWindow* window = impl->toDOMWindow()) {
26         if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), window->frame(), exceptionState)) {
27             {{throw_from_exception_state(method)}};
28             return;
29         }
30         if (!window->document())
31             return;
32     }
33     {% elif method.is_check_security_for_frame %}
34     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), exceptionState)) {
35         {{throw_from_exception_state(method)}};
36         return;
37     }
38     {% endif %}
39     {% if method.is_check_security_for_node %}
40     if (!BindingSecurity::shouldAllowAccessToNode(info.GetIsolate(), impl->{{method.name}}(exceptionState), exceptionState)) {
41         v8SetReturnValueNull(info);
42         {{throw_from_exception_state(method)}};
43         return;
44     }
45     {% endif %}
46     {# Call method #}
47     {% if method.arguments %}
48     {{generate_arguments(method, world_suffix) | indent}}
49     {% endif %}
50     {% if world_suffix %}
51     {{cpp_method_call(method, method.v8_set_return_value_for_main_world, method.cpp_value) | indent}}
52     {% else %}
53     {{cpp_method_call(method, method.v8_set_return_value, method.cpp_value) | indent}}
54     {% endif %}
55 }
56 {% endfilter %}
57 {% endmacro %}
58
59
60 {######################################}
61 {% macro generate_arguments(method, world_suffix) %}
62 {% for argument in method.arguments %}
63 {{generate_argument_var_declaration(argument)}};
64 {% endfor %}
65 {
66     {% for argument in method.arguments %}
67     {% if argument.default_value %}
68     if (!info[{{argument.index}}]->IsUndefined()) {
69         {{generate_argument(method, argument, world_suffix) | indent(8)}}
70     } else {
71         {{argument.name}} = {{argument.default_value}};
72     }
73     {% else %}
74     {{generate_argument(method, argument, world_suffix) | indent}}
75     {% endif %}
76     {% endfor %}
77 }
78 {% endmacro %}
79
80
81 {######################################}
82 {% macro generate_argument_var_declaration(argument) %}
83 {# FIXME: remove EventListener special case #}
84 {% if argument.idl_type == 'EventListener' %}
85 RefPtr<{{argument.idl_type}}> {{argument.name}}
86 {%- else %}
87 {{argument.cpp_type}} {{argument.name}}
88 {%- endif %}{# argument.idl_type == 'EventListener' #}
89 {% endmacro %}
90
91
92 {######################################}
93 {% macro generate_argument(method, argument, world_suffix) %}
94 {% if argument.is_optional and not argument.has_default and
95       not argument.is_dictionary and
96       not argument.is_callback_interface %}
97 {# Optional arguments without a default value generate an early call with
98    fewer arguments if they are omitted.
99    Optional Dictionary arguments default to empty dictionary. #}
100 if (UNLIKELY(info.Length() <= {{argument.index}})) {
101     {% if world_suffix %}
102     {{cpp_method_call(method, argument.v8_set_return_value_for_main_world, argument.cpp_value) | indent}}
103     {% else %}
104     {{cpp_method_call(method, argument.v8_set_return_value, argument.cpp_value) | indent}}
105     {% endif %}
106     {% if argument.has_event_listener_argument %}
107     {{hidden_dependency_action(method.name) | indent}}
108     {% endif %}
109     return;
110 }
111 {% endif %}
112 {% if argument.has_type_checking_interface and not argument.is_variadic_wrapper_type %}
113 {# Type checking for wrapper interface types (if interface not implemented,
114    throw a TypeError), per http://www.w3.org/TR/WebIDL/#es-interface
115    Note: for variadic arguments, the type checking is done for each matched
116    argument instead; see argument.is_variadic_wrapper_type code-path below. #}
117 if (info.Length() > {{argument.index}} && {% if argument.is_nullable %}!isUndefinedOrNull(info[{{argument.index}}]) && {% endif %}!V8{{argument.idl_type}}::hasInstance(info[{{argument.index}}], info.GetIsolate())) {
118     {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
119                                (argument.index + 1, argument.idl_type)) | indent}}
120     return;
121 }
122 {% endif %}{# argument.has_type_checking_interface #}
123 {% if argument.is_callback_interface %}
124 {# FIXME: remove EventListener special case #}
125 {% if argument.idl_type == 'EventListener' %}
126 {% if method.name == 'removeEventListener' or method.name == 'removeListener' %}
127 {{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOnly);
128 {% else %}{# method.name == 'addEventListener' #}
129 {{argument.name}} = V8EventListenerList::getEventListener(ScriptState::current(info.GetIsolate()), info[{{argument.index}}], false, ListenerFindOrCreate);
130 {% endif %}{# method.name #}
131 {% else %}{# argument.idl_type == 'EventListener' #}
132 {# Callback functions must be functions:
133    http://www.w3.org/TR/WebIDL/#es-callback-function #}
134 {% if argument.is_optional %}
135 if (!isUndefinedOrNull(info[{{argument.index}}])) {
136     if (!info[{{argument.index}}]->IsFunction()) {
137         {{throw_type_error(method,
138               '"The callback provided as parameter %s is not a function."' %
139                   (argument.index + 1)) | indent(8)}}
140         return;
141     }
142     {{argument.name}} = V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
143 } else {
144     {{argument.name}} = nullptr;
145 }
146 {% else %}{# argument.is_optional #}
147 if (info.Length() <= {{argument.index}} || !{% if argument.is_nullable %}(info[{{argument.index}}]->IsFunction() || info[{{argument.index}}]->IsNull()){% else %}info[{{argument.index}}]->IsFunction(){% endif %}) {
148     {{throw_type_error(method,
149           '"The callback provided as parameter %s is not a function."' %
150               (argument.index + 1)) | indent }}
151     return;
152 }
153 {{argument.name}} = {% if argument.is_nullable %}info[{{argument.index}}]->IsNull() ? nullptr : {% endif %}V8{{argument.idl_type}}::create(v8::Handle<v8::Function>::Cast(info[{{argument.index}}]), ScriptState::current(info.GetIsolate()));
154 {% endif %}{# argument.is_optional #}
155 {% endif %}{# argument.idl_type == 'EventListener' #}
156 {% elif argument.is_variadic_wrapper_type %}
157 for (int i = {{argument.index}}; i < info.Length(); ++i) {
158     if (!V8{{argument.idl_type}}::hasInstance(info[i], info.GetIsolate())) {
159         {{throw_type_error(method, '"parameter %s is not of type \'%s\'."' %
160                                    (argument.index + 1, argument.idl_type)) | indent(8)}}
161         return;
162     }
163     {{argument.name}}.append(V8{{argument.idl_type}}::toImpl(v8::Handle<v8::Object>::Cast(info[i])));
164 }
165 {% elif argument.is_dictionary %}
166 {# Dictionaries must have type Undefined, Null or Object:
167 http://heycam.github.io/webidl/#es-dictionary #}
168 if (!isUndefinedOrNull(info[{{argument.index}}]) && !info[{{argument.index}}]->IsObject()) {
169     {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
170                                (argument.index + 1, argument.name)) | indent}}
171     return;
172 }
173 {{argument.v8_value_to_local_cpp_value}};
174 {% else %}{# argument.is_nullable #}
175 {{argument.v8_value_to_local_cpp_value}};
176 {% endif %}{# argument.is_nullable #}
177 {# Type checking, possibly throw a TypeError, per:
178    http://www.w3.org/TR/WebIDL/#es-type-mapping #}
179 {% if argument.has_type_checking_unrestricted %}
180 {# Non-finite floating point values (NaN, +Infinity or âˆ’Infinity), per:
181    http://heycam.github.io/webidl/#es-float
182    http://heycam.github.io/webidl/#es-double #}
183 if (!std::isfinite({{argument.name}})) {
184     {{throw_type_error(method, '"%s parameter %s is non-finite."' %
185                                (argument.idl_type, argument.index + 1)) | indent}}
186     return;
187 }
188 {% elif argument.enum_validation_expression %}
189 {# Invalid enum values: http://www.w3.org/TR/WebIDL/#idl-enums #}
190 String string = {{argument.name}};
191 if (!({{argument.enum_validation_expression}})) {
192     {{throw_type_error(method,
193           '"parameter %s (\'" + string + "\') is not a valid enum value."' %
194               (argument.index + 1)) | indent}}
195     return;
196 }
197 {% elif argument.idl_type == 'Promise' %}
198 {# We require this for our implementation of promises, though not in spec:
199 http://heycam.github.io/webidl/#es-promise #}
200 if (!{{argument.name}}.isUndefinedOrNull() && !{{argument.name}}.isObject()) {
201     {{throw_type_error(method, '"parameter %s (\'%s\') is not an object."' %
202                                (argument.index + 1, argument.name)) | indent}}
203     return;
204 }
205 {% endif %}
206 {% endmacro %}
207
208
209 {######################################}
210 {% macro cpp_method_call(method, v8_set_return_value, cpp_value) %}
211 {# Local variables #}
212 {% if method.is_call_with_script_state %}
213 {# [CallWith=ScriptState] #}
214 ScriptState* scriptState = ScriptState::current(info.GetIsolate());
215 {% endif %}
216 {% if method.is_call_with_execution_context %}
217 {# [ConstructorCallWith=ExecutionContext] #}
218 {# [CallWith=ExecutionContext] #}
219 ExecutionContext* executionContext = currentExecutionContext(info.GetIsolate());
220 {% endif %}
221 {% if method.is_call_with_script_arguments %}
222 {# [CallWith=ScriptArguments] #}
223 RefPtrWillBeRawPtr<ScriptArguments> scriptArguments(createScriptArguments(scriptState, info, {{method.number_of_arguments}}));
224 {% endif %}
225 {% if method.is_call_with_document %}
226 {# [ConstructorCallWith=Document] #}
227 Document& document = *toDocument(currentExecutionContext(info.GetIsolate()));
228 {% endif %}
229 {# Call #}
230 {% if method.idl_type == 'void' %}
231 {{cpp_value}};
232 {% elif method.is_implemented_in_private_script %}
233 {{method.cpp_type}} result{{method.cpp_type_initializer}};
234 if (!{{method.cpp_value}})
235     return;
236 {% elif method.use_output_parameter_for_result %}
237 {{method.cpp_type}} result;
238 {{cpp_value}};
239 {% elif method.is_constructor %}
240 {{method.cpp_type}} impl = {{cpp_value}};
241 {% elif method.use_local_result %}
242 {{method.cpp_type}} result = {{cpp_value}};
243 {% endif %}
244 {# Post-call #}
245 {% if method.is_raises_exception %}
246 if (exceptionState.hadException()) {
247     {{throw_from_exception_state(method)}};
248     return;
249 }
250 {% endif %}
251 {# Set return value #}
252 {% if method.is_constructor %}
253 {{generate_constructor_wrapper(method)}}
254 {%- elif v8_set_return_value %}
255 {% if method.is_explicit_nullable %}
256 if (result.isNull())
257     v8SetReturnValueNull(info);
258 else
259     {{v8_set_return_value}};
260 {% else %}
261 {{v8_set_return_value}};
262 {% endif %}
263 {%- endif %}{# None for void #}
264 {# Post-set #}
265 {% if interface_name in ('EventTarget', 'MediaQueryList')
266     and method.name in ('addEventListener', 'removeEventListener', 'addListener', 'removeListener') %}
267 {% set hidden_dependency_action = 'addHiddenValueToArray'
268        if method.name in ('addEventListener', 'addListener') else 'removeHiddenValueFromArray' %}
269 {% set argument_index = '1' if interface_name == 'EventTarget' else '0' %}
270 {# Length check needed to skip action on legacy calls without enough arguments.
271    http://crbug.com/353484 #}
272 if (info.Length() >= {{argument_index}} + 1 && listener && !impl->toNode())
273     {{hidden_dependency_action}}(info.GetIsolate(), info.Holder(), info[{{argument_index}}], {{v8_class}}::eventListenerCacheIndex);
274 {% endif %}
275 {% endmacro %}
276
277
278 {######################################}
279 {% macro throw_type_error(method, error_message) %}
280 {% if method.has_exception_state %}
281 exceptionState.throwTypeError({{error_message}});
282 {{throw_from_exception_state(method)}};
283 {% elif method.idl_type == 'Promise' %}
284 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), V8ThrowException::createTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}})));
285 {% else %}
286 V8ThrowException::throwTypeError(info.GetIsolate(), {{type_error_message(method, error_message)}});
287 {% endif %}{# method.has_exception_state #}
288 {% endmacro %}
289
290
291 {######################################}
292 {% macro type_error_message(method, error_message) %}
293 {% if method.is_constructor %}
294 ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}})
295 {%- else %}
296 ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}})
297 {%- endif %}
298 {%- endmacro %}
299
300
301 {######################################}
302 {% macro throw_from_exception_state(method_or_overloads) %}
303 {% if method_or_overloads.idl_type == 'Promise' or method_or_overloads.returns_promise_all %}
304 v8SetReturnValue(info, exceptionState.reject(ScriptState::current(info.GetIsolate())).v8Value())
305 {%- else %}
306 exceptionState.throwIfNeeded()
307 {%- endif %}
308 {%- endmacro %}
309
310
311 {######################################}
312 {% macro throw_minimum_arity_type_error(method, number_of_required_arguments) %}
313 {% if method.has_exception_state %}
314 setMinimumArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length());
315 {{throw_from_exception_state(method)}};
316 {%- elif method.idl_type == 'Promise' %}
317 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), {{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}));
318 {%- else %}
319 V8ThrowException::throwException({{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}, info.GetIsolate());
320 {%- endif %}
321 {%- endmacro %}
322
323
324 {######################################}
325 {% macro create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments) %}
326 {% if method.is_constructor %}
327 createMinimumArityTypeErrorForConstructor(info.GetIsolate(), "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
328 {%- else %}
329 createMinimumArityTypeErrorForMethod(info.GetIsolate(), "{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length())
330 {%- endif %}
331 {%- endmacro %}
332
333
334 {##############################################################################}
335 {# FIXME: We should return a rejected Promise if an error occurs in this
336 function when ALL methods in this overload return Promise. In order to do so,
337 we must ensure either ALL or NO methods in this overload return Promise #}
338 {% macro overload_resolution_method(overloads, world_suffix) %}
339 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
340 {
341     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
342     {% if overloads.measure_all_as %}
343     UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}});
344     {% endif %}
345     {% if overloads.deprecate_all_as %}
346     UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}});
347     {% endif %}
348     {# First resolve by length #}
349     {# 2. Initialize argcount to be min(maxarg, n). #}
350     switch (std::min({{overloads.maxarg}}, info.Length())) {
351     {# 3. Remove from S all entries whose type list is not of length argcount. #}
352     {% for length, tests_methods in overloads.length_tests_methods %}
353     {# 10. If i = d, then: #}
354     case {{length}}:
355         {# Then resolve by testing argument #}
356         {% for test, method in tests_methods %}
357         {% if method.visible %}
358         {% filter runtime_enabled(not overloads.runtime_enabled_function_all and
359                                   method.runtime_enabled_function) %}
360         if ({{test}}) {
361             {% if method.measure_as and not overloads.measure_all_as %}
362             UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
363             {% endif %}
364             {% if method.deprecate_as and not overloads.deprecate_all_as %}
365             UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
366             {% endif %}
367             {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
368             return;
369         }
370         {% endfilter %}
371         {% endif %}
372         {% endfor %}
373         break;
374     {% endfor %}
375     {% if is_partial or not overloads.has_partial_overloads %}
376     default:
377         {# If methods are overloaded between interface and partial interface #}
378         {# definitions, need to invoke methods defined in the partial #}
379         {# interface. #}
380         {# FIXME: we do not need to always generate this code. #}
381         {# Invalid arity, throw error #}
382         {# Report full list of valid arities if gaps and above minimum #}
383         {% if overloads.valid_arities %}
384         if (info.Length() >= {{overloads.minarg}}) {
385             setArityTypeError(exceptionState, "{{overloads.valid_arities}}", info.Length());
386             {{throw_from_exception_state(overloads)}};
387             return;
388         }
389         {% endif %}
390         {# Otherwise just report "not enough arguments" #}
391         exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.minarg}}, info.Length()));
392         {{throw_from_exception_state(overloads)}};
393         return;
394     {% endif %}
395     }
396     {% if not is_partial and overloads.has_partial_overloads %}
397     ASSERT({{overloads.name}}MethodForPartialInterface);
398     ({{overloads.name}}MethodForPartialInterface)(info);
399     {% else %}
400     {# No match, throw error #}
401     exceptionState.throwTypeError("No function was found that matched the signature provided.");
402     {{throw_from_exception_state(overloads)}};
403     {% endif %}
404 }
405 {% endmacro %}
406
407
408 {##############################################################################}
409 {% macro method_callback(method, world_suffix) %}
410 {% filter conditional(method.conditional_string) %}
411 static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
412 {
413     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMMethod");
414     {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
415     {% if method.measure_as %}
416     UseCounter::countIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
417     {% endif %}
418     {% if method.deprecate_as %}
419     UseCounter::countDeprecationIfNotPrivateScript(info.GetIsolate(), callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
420     {% endif %}
421     {% endif %}{# not method.overloads #}
422     {% if world_suffix in method.activity_logging_world_list %}
423     ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
424     V8PerContextData* contextData = scriptState->perContextData();
425     {% if method.activity_logging_world_check %}
426     if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
427     {% else %}
428     if (contextData && contextData->activityLogger()) {
429     {% endif %}
430         ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
431         Vector<v8::Handle<v8::Value> > loggerArgs = toImplArguments<v8::Handle<v8::Value> >(info, 0, exceptionState);
432         contextData->activityLogger()->logMethod("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data());
433     }
434     {% endif %}
435     {% if method.is_custom %}
436     {{v8_class}}::{{method.name}}MethodCustom(info);
437     {% else %}
438     {{cpp_class_or_partial}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
439     {% endif %}
440     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
441 }
442 {% endfilter %}
443 {% endmacro %}
444
445
446 {##############################################################################}
447 {% macro origin_safe_method_getter(method, world_suffix) %}
448 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info)
449 {
450     {% set signature = 'v8::Local<v8::Signature>()'
451                        if method.is_do_not_check_signature else
452                        'v8::Signature::New(info.GetIsolate(), %s::domTemplate(info.GetIsolate()))' % v8_class %}
453     static int domTemplateKey; // This address is used for a key to look up the dom template.
454     V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate());
455     {# FIXME: 1 case of [DoNotCheckSignature] in Window.idl may differ #}
456     v8::Handle<v8::FunctionTemplate> privateTemplate = data->domTemplate(&domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
457
458     v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
459     if (holder.IsEmpty()) {
460         // This is only reachable via |object.__proto__.func|, in which case it
461         // has already passed the same origin security check
462         v8SetReturnValue(info, privateTemplate->GetFunction());
463         return;
464     }
465     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
466     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), DoNotReportSecurityError)) {
467         static int sharedTemplateKey; // This address is used for a key to look up the dom template.
468         v8::Handle<v8::FunctionTemplate> sharedTemplate = data->domTemplate(&sharedTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
469         v8SetReturnValue(info, sharedTemplate->GetFunction());
470         return;
471     }
472
473     {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
474     v8::Local<v8::Value> hiddenValue = v8::Handle<v8::Object>::Cast(info.This())->GetHiddenValue(v8AtomicString(info.GetIsolate(), "{{method.name}}"));
475     if (!hiddenValue.IsEmpty()) {
476         v8SetReturnValue(info, hiddenValue);
477         return;
478     }
479
480     v8SetReturnValue(info, privateTemplate->GetFunction());
481 }
482
483 static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
484 {
485     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMGetter");
486     {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}(info);
487     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
488 }
489 {% endmacro %}
490
491
492 {##############################################################################}
493 {% macro method_implemented_in_private_script(method) %}
494 bool {{v8_class}}::PrivateScript::{{method.name}}Method({{method.argument_declarations_for_private_script | join(', ')}})
495 {
496     if (!frame)
497         return false;
498     v8::HandleScope handleScope(toIsolate(frame));
499     ScriptForbiddenScope::AllowUserAgentScript script;
500     v8::Handle<v8::Context> contextInPrivateScript = toV8Context(frame, DOMWrapperWorld::privateScriptIsolatedWorld());
501     if (contextInPrivateScript.IsEmpty())
502         return false;
503     ScriptState* scriptState = ScriptState::from(contextInPrivateScript);
504     ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame);
505     if (!scriptState->executionContext())
506         return false;
507
508     ScriptState::Scope scope(scriptState);
509     v8::Handle<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(), scriptState->isolate());
510
511     {% for argument in method.arguments %}
512     v8::Handle<v8::Value> {{argument.handle}} = {{argument.private_script_cpp_value_to_v8_value}};
513     {% endfor %}
514     {% if method.arguments %}
515     v8::Handle<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} };
516     {% else %}
517     {# Empty array initializers are illegal, and don\t compile in MSVC. #}
518     v8::Handle<v8::Value> *argv = 0;
519     {% endif %}
520     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{cpp_class}}", scriptState->context()->Global(), scriptState->isolate());
521     v8::Handle<v8::Value> v8Value = PrivateScriptRunner::runDOMMethod(scriptState, scriptStateInUserScript, "{{cpp_class}}", "{{method.name}}", holder, {{method.arguments | length}}, argv);
522     if (v8Value.IsEmpty())
523         return false;
524     {% if method.idl_type != 'void' %}
525     {{method.private_script_v8_value_to_local_cpp_value}};
526     *result = cppValue;
527     {% endif %}
528     RELEASE_ASSERT(!exceptionState.hadException());
529     return true;
530 }
531 {% endmacro %}
532
533
534 {##############################################################################}
535 {% macro generate_constructor(constructor) %}
536 {% set name = '%sConstructorCallback' % v8_class
537               if constructor.is_named_constructor else
538               'constructor%s' % (constructor.overload_index or '') %}
539 static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info)
540 {
541     {% if constructor.is_named_constructor %}
542     if (!info.IsConstructCall()) {
543         V8ThrowException::throwTypeError(info.GetIsolate(), ExceptionMessages::constructorNotCallableAsFunction("{{constructor.name}}"));
544         return;
545     }
546
547     if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
548         v8SetReturnValue(info, info.Holder());
549         return;
550     }
551     {% endif %}
552     {% if constructor.has_exception_state %}
553     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
554     {% endif %}
555     {# Overloaded constructors have length checked during overload resolution #}
556     {% if constructor.number_of_required_arguments and not constructor.overload_index %}
557     if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
558         {{throw_minimum_arity_type_error(constructor, constructor.number_of_required_arguments) | indent(8)}}
559         return;
560     }
561     {% endif %}
562     {% if constructor.arguments %}
563     {{generate_arguments(constructor) | indent}}
564     {% endif %}
565     {{cpp_method_call(constructor, constructor.v8_set_return_value, constructor.cpp_value) | indent}}
566 }
567 {% endmacro %}
568
569
570 {##############################################################################}
571 {% macro generate_constructor_wrapper(constructor) %}
572 {% if has_custom_wrap %}
573 v8::Handle<v8::Object> wrapper = wrapCustom(impl.get(), info.Holder(), info.GetIsolate());
574 {% else %}
575 {% set constructor_class = v8_class + ('Constructor'
576                                        if constructor.is_named_constructor else
577                                        '') %}
578 v8::Handle<v8::Object> wrapper = info.Holder();
579 {% if is_script_wrappable %}
580 impl->associateWithWrapper(&{{constructor_class}}::wrapperTypeInfo, wrapper, info.GetIsolate());
581 {% else %}
582 V8DOMWrapper::associateObjectWithWrapper(info.GetIsolate(), impl.get(), &{{constructor_class}}::wrapperTypeInfo, wrapper);
583 {% endif %}
584 {% endif %}
585 v8SetReturnValue(info, wrapper);
586 {% endmacro %}
587
588
589 {##############################################################################}
590 {% macro method_configuration(method) %}
591 {% set method_callback =
592    '%sV8Internal::%sMethodCallback' % (cpp_class_or_partial, method.name) %}
593 {% set method_callback_for_main_world =
594    '%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class_or_partial, method.name)
595    if method.is_per_world_bindings else '0' %}
596 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
597 {"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}}}
598 {%- endmacro %}
599
600
601 {######################################}
602 {% macro install_custom_signature(method) %}
603 {% set method_callback = '%sV8Internal::%sMethodCallback' % (cpp_class_or_partial, method.name) %}
604 {% set method_callback_for_main_world = '%sForMainWorld' % method_callback
605   if method.is_per_world_bindings else '0' %}
606 {% set property_attribute =
607   'static_cast<v8::PropertyAttribute>(%s)' % ' | '.join(method.property_attributes)
608   if method.property_attributes else 'v8::None' %}
609 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
610 static const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration = {
611     "{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}},
612 };
613 V8DOMConfiguration::installMethod({{method.function_template}}, {{method.signature}}, {{property_attribute}}, {{method.name}}MethodConfiguration, isolate);
614 {%- endmacro %}
615
616 {######################################}
617 {% macro install_conditionally_enabled_methods() %}
618 void {{v8_class_or_partial}}::installConditionallyEnabledMethods(v8::Handle<v8::Object> prototypeObject, v8::Isolate* isolate)
619 {
620     {% if is_partial %}
621     {{v8_class}}::installConditionallyEnabledMethods(prototypeObject, isolate);
622     {% endif %}
623     {% if conditionally_enabled_methods %}
624     {# Define per-context enabled operations #}
625     v8::Local<v8::Signature> defaultSignature = v8::Signature::New(isolate, domTemplate(isolate));
626     ExecutionContext* context = toExecutionContext(prototypeObject->CreationContext());
627     ASSERT(context);
628
629     {% for method in conditionally_enabled_methods %}
630     {% filter per_context_enabled(method.per_context_enabled_function) %}
631     {% filter exposed(method.exposed_test) %}
632     prototypeObject->Set(v8AtomicString(isolate, "{{method.name}}"), v8::FunctionTemplate::New(isolate, {{cpp_class_or_partial}}V8Internal::{{method.name}}MethodCallback, v8Undefined(), defaultSignature, {{method.number_of_required_arguments}})->GetFunction());
633     {% endfilter %}
634     {% endfilter %}
635     {% endfor %}
636     {% endif %}
637 }
638 {%- endmacro %}