Home | History | Annotate | Download | only in templates
      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.is_constructor %}
    237 {{method.cpp_type}} impl = {{cpp_value}};
    238 {% elif method.use_local_result and not method.union_arguments %}
    239 {{method.cpp_type}} result = {{cpp_value}};
    240 {% endif %}
    241 {# Post-call #}
    242 {% if method.is_raises_exception %}
    243 if (exceptionState.hadException()) {
    244     {{throw_from_exception_state(method)}};
    245     return;
    246 }
    247 {% endif %}
    248 {# Set return value #}
    249 {% if method.is_constructor %}
    250 {{generate_constructor_wrapper(method)}}
    251 {%- elif method.union_arguments %}
    252 {{union_type_method_call_and_set_return_value(method)}}
    253 {%- elif v8_set_return_value %}
    254 {% if method.is_explicit_nullable %}
    255 if (result.isNull())
    256     v8SetReturnValueNull(info);
    257 else
    258     {{v8_set_return_value}};
    259 {% else %}
    260 {{v8_set_return_value}};
    261 {% endif %}
    262 {%- endif %}{# None for void #}
    263 {# Post-set #}
    264 {% if interface_name in ('EventTarget', 'MediaQueryList')
    265     and method.name in ('addEventListener', 'removeEventListener', 'addListener', 'removeListener') %}
    266 {% set hidden_dependency_action = 'addHiddenValueToArray'
    267        if method.name in ('addEventListener', 'addListener') else 'removeHiddenValueFromArray' %}
    268 {% set argument_index = '1' if interface_name == 'EventTarget' else '0' %}
    269 {# Length check needed to skip action on legacy calls without enough arguments.
    270    http://crbug.com/353484 #}
    271 if (info.Length() >= {{argument_index}} + 1 && listener && !impl->toNode())
    272     {{hidden_dependency_action}}(info.Holder(), info[{{argument_index}}], {{v8_class}}::eventListenerCacheIndex, info.GetIsolate());
    273 {% endif %}
    274 {% endmacro %}
    275 
    276 
    277 {######################################}
    278 {% macro union_type_method_call_and_set_return_value(method) %}
    279 {% for argument in method.union_arguments %}
    280 {{argument.cpp_type}} {{argument.cpp_value}}{{argument.cpp_type_initializer}};
    281 {% endfor %}
    282 {{method.cpp_value}};
    283 {% if method.is_null_expression %}{# used by getters #}
    284 if ({{method.is_null_expression}})
    285     return;
    286 {% endif %}
    287 {% for argument in method.union_arguments %}
    288 if ({{argument.null_check_value}}) {
    289     {{argument.v8_set_return_value}};
    290     return;
    291 }
    292 {% endfor %}
    293 {# Fall back to null if none of the union members results are returned #}
    294 {% if method.is_null_expression %}
    295 ASSERT_NOT_REACHED();
    296 {% else %}
    297 v8SetReturnValueNull(info);
    298 {% endif %}
    299 {% endmacro %}
    300 
    301 
    302 {######################################}
    303 {% macro throw_type_error(method, error_message) %}
    304 {% if method.has_exception_state %}
    305 exceptionState.throwTypeError({{error_message}});
    306 {{throw_from_exception_state(method)}};
    307 {% elif method.idl_type == 'Promise' %}
    308 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), V8ThrowException::createTypeError({{type_error_message(method, error_message)}}, info.GetIsolate())));
    309 {% else %}
    310 V8ThrowException::throwTypeError({{type_error_message(method, error_message)}}, info.GetIsolate());
    311 {% endif %}{# method.has_exception_state #}
    312 {% endmacro %}
    313 
    314 
    315 {######################################}
    316 {% macro type_error_message(method, error_message) %}
    317 {% if method.is_constructor %}
    318 ExceptionMessages::failedToConstruct("{{interface_name}}", {{error_message}})
    319 {%- else %}
    320 ExceptionMessages::failedToExecute("{{method.name}}", "{{interface_name}}", {{error_message}})
    321 {%- endif %}
    322 {%- endmacro %}
    323 
    324 
    325 {######################################}
    326 {% macro throw_from_exception_state(method) %}
    327 {% if method.idl_type == 'Promise' %}
    328 v8SetReturnValue(info, exceptionState.reject(ScriptState::current(info.GetIsolate())).v8Value())
    329 {%- else %}
    330 exceptionState.throwIfNeeded()
    331 {%- endif %}
    332 {%- endmacro %}
    333 
    334 
    335 {######################################}
    336 {% macro throw_minimum_arity_type_error(method, number_of_required_arguments) %}
    337 {% if method.has_exception_state %}
    338 setMinimumArityTypeError(exceptionState, {{number_of_required_arguments}}, info.Length());
    339 {{throw_from_exception_state(method)}};
    340 {%- elif method.idl_type == 'Promise' %}
    341 v8SetReturnValue(info, ScriptPromise::rejectRaw(info.GetIsolate(), {{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}));
    342 {%- else %}
    343 V8ThrowException::throwException({{create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments)}}, info.GetIsolate());
    344 {%- endif %}
    345 {%- endmacro %}
    346 
    347 
    348 {######################################}
    349 {% macro create_minimum_arity_type_error_without_exception_state(method, number_of_required_arguments) %}
    350 {% if method.is_constructor %}
    351 createMinimumArityTypeErrorForConstructor("{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
    352 {%- else %}
    353 createMinimumArityTypeErrorForMethod("{{method.name}}", "{{interface_name}}", {{number_of_required_arguments}}, info.Length(), info.GetIsolate())
    354 {%- endif %}
    355 {%- endmacro %}
    356 
    357 
    358 {##############################################################################}
    359 {# FIXME: We should return a rejected Promise if an error occurs in this
    360 function when ALL methods in this overload return Promise. In order to do so,
    361 we must ensure either ALL or NO methods in this overload return Promise #}
    362 {% macro overload_resolution_method(overloads, world_suffix) %}
    363 static void {{overloads.name}}Method{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
    364 {
    365     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{overloads.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
    366     {% if overloads.measure_all_as %}
    367     UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.measure_all_as}});
    368     {% endif %}
    369     {% if overloads.deprecate_all_as %}
    370     UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{overloads.deprecate_all_as}});
    371     {% endif %}
    372     {# First resolve by length #}
    373     {# 2. Initialize argcount to be min(maxarg, n). #}
    374     switch (std::min({{overloads.maxarg}}, info.Length())) {
    375     {# 3. Remove from S all entries whose type list is not of length argcount. #}
    376     {% for length, tests_methods in overloads.length_tests_methods %}
    377     {# 10. If i = d, then: #}
    378     case {{length}}:
    379         {# Then resolve by testing argument #}
    380         {% for test, method in tests_methods %}
    381         {% filter runtime_enabled(not overloads.runtime_enabled_function_all and
    382                                   method.runtime_enabled_function) %}
    383         if ({{test}}) {
    384             {% if method.measure_as and not overloads.measure_all_as %}
    385             UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
    386             {% endif %}
    387             {% if method.deprecate_as and not overloads.deprecate_all_as %}
    388             UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
    389             {% endif %}
    390             {{method.name}}{{method.overload_index}}Method{{world_suffix}}(info);
    391             return;
    392         }
    393         {% endfilter %}
    394         {% endfor %}
    395         break;
    396     {% endfor %}
    397     default:
    398         {# Invalid arity, throw error #}
    399         {# Report full list of valid arities if gaps and above minimum #}
    400         {% if overloads.valid_arities %}
    401         if (info.Length() >= {{overloads.minarg}}) {
    402             setArityTypeError(exceptionState, "{{overloads.valid_arities}}", info.Length());
    403             exceptionState.throwIfNeeded();
    404             return;
    405         }
    406         {% endif %}
    407         {# Otherwise just report "not enough arguments" #}
    408         exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments({{overloads.minarg}}, info.Length()));
    409         exceptionState.throwIfNeeded();
    410         return;
    411     }
    412     {# No match, throw error #}
    413     exceptionState.throwTypeError("No function was found that matched the signature provided.");
    414     exceptionState.throwIfNeeded();
    415 }
    416 {% endmacro %}
    417 
    418 
    419 {##############################################################################}
    420 {% macro method_callback(method, world_suffix) %}
    421 {% filter conditional(method.conditional_string) %}
    422 static void {{method.name}}MethodCallback{{world_suffix}}(const v8::FunctionCallbackInfo<v8::Value>& info)
    423 {
    424     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMMethod");
    425     {% if not method.overloads %}{# Overloaded methods are measured in overload_resolution_method() #}
    426     {% if method.measure_as %}
    427     UseCounter::count(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.measure_as}});
    428     {% endif %}
    429     {% if method.deprecate_as %}
    430     UseCounter::countDeprecation(callingExecutionContext(info.GetIsolate()), UseCounter::{{method.deprecate_as}});
    431     {% endif %}
    432     {% endif %}{# not method.overloads #}
    433     {% if world_suffix in method.activity_logging_world_list %}
    434     ScriptState* scriptState = ScriptState::from(info.GetIsolate()->GetCurrentContext());
    435     V8PerContextData* contextData = scriptState->perContextData();
    436     {% if method.activity_logging_world_check %}
    437     if (scriptState->world().isIsolatedWorld() && contextData && contextData->activityLogger())
    438     {% else %}
    439     if (contextData && contextData->activityLogger()) {
    440     {% endif %}
    441         ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{interface_name}}", info.Holder(), info.GetIsolate());
    442         Vector<v8::Handle<v8::Value> > loggerArgs = toImplArguments<v8::Handle<v8::Value> >(info, 0, exceptionState);
    443         contextData->activityLogger()->logMethod("{{interface_name}}.{{method.name}}", info.Length(), loggerArgs.data());
    444     }
    445     {% endif %}
    446     {% if method.is_custom %}
    447     {{v8_class}}::{{method.name}}MethodCustom(info);
    448     {% else %}
    449     {{cpp_class}}V8Internal::{{method.name}}Method{{world_suffix}}(info);
    450     {% endif %}
    451     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
    452 }
    453 {% endfilter %}
    454 {% endmacro %}
    455 
    456 
    457 {##############################################################################}
    458 {% macro origin_safe_method_getter(method, world_suffix) %}
    459 static void {{method.name}}OriginSafeMethodGetter{{world_suffix}}(const v8::PropertyCallbackInfo<v8::Value>& info)
    460 {
    461     {% set signature = 'v8::Local<v8::Signature>()'
    462                        if method.is_do_not_check_signature else
    463                        'v8::Signature::New(info.GetIsolate(), %s::domTemplate(info.GetIsolate()))' % v8_class %}
    464     static int domTemplateKey; // This address is used for a key to look up the dom template.
    465     V8PerIsolateData* data = V8PerIsolateData::from(info.GetIsolate());
    466     {# FIXME: 1 case of [DoNotCheckSignature] in Window.idl may differ #}
    467     v8::Handle<v8::FunctionTemplate> privateTemplate = data->domTemplate(&domTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
    468 
    469     v8::Handle<v8::Object> holder = {{v8_class}}::findInstanceInPrototypeChain(info.This(), info.GetIsolate());
    470     if (holder.IsEmpty()) {
    471         // This is only reachable via |object.__proto__.func|, in which case it
    472         // has already passed the same origin security check
    473         v8SetReturnValue(info, privateTemplate->GetFunction());
    474         return;
    475     }
    476     {{cpp_class}}* impl = {{v8_class}}::toImpl(holder);
    477     if (!BindingSecurity::shouldAllowAccessToFrame(info.GetIsolate(), impl->frame(), DoNotReportSecurityError)) {
    478         static int sharedTemplateKey; // This address is used for a key to look up the dom template.
    479         v8::Handle<v8::FunctionTemplate> sharedTemplate = data->domTemplate(&sharedTemplateKey, {{cpp_class}}V8Internal::{{method.name}}MethodCallback{{world_suffix}}, v8Undefined(), {{signature}}, {{method.length}});
    480         v8SetReturnValue(info, sharedTemplate->GetFunction());
    481         return;
    482     }
    483 
    484     {# The findInstanceInPrototypeChain() call above only returns a non-empty handle if info.This() is an Object. #}
    485     v8::Local<v8::Value> hiddenValue = v8::Handle<v8::Object>::Cast(info.This())->GetHiddenValue(v8AtomicString(info.GetIsolate(), "{{method.name}}"));
    486     if (!hiddenValue.IsEmpty()) {
    487         v8SetReturnValue(info, hiddenValue);
    488         return;
    489     }
    490 
    491     v8SetReturnValue(info, privateTemplate->GetFunction());
    492 }
    493 
    494 static void {{method.name}}OriginSafeMethodGetterCallback{{world_suffix}}(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
    495 {
    496     TRACE_EVENT_SET_SAMPLING_STATE("blink", "DOMGetter");
    497     {{cpp_class}}V8Internal::{{method.name}}OriginSafeMethodGetter{{world_suffix}}(info);
    498     TRACE_EVENT_SET_SAMPLING_STATE("v8", "V8Execution");
    499 }
    500 {% endmacro %}
    501 
    502 
    503 {##############################################################################}
    504 {% macro method_implemented_in_private_script(method) %}
    505 bool {{v8_class}}::PrivateScript::{{method.name}}Method({{method.argument_declarations_for_private_script | join(', ')}})
    506 {
    507     if (!frame)
    508         return false;
    509     v8::HandleScope handleScope(toIsolate(frame));
    510     ScriptForbiddenScope::AllowUserAgentScript script;
    511     v8::Handle<v8::Context> contextInPrivateScript = toV8Context(frame, DOMWrapperWorld::privateScriptIsolatedWorld());
    512     if (contextInPrivateScript.IsEmpty())
    513         return false;
    514     ScriptState* scriptState = ScriptState::from(contextInPrivateScript);
    515     ScriptState* scriptStateInUserScript = ScriptState::forMainWorld(frame);
    516     if (!scriptState->executionContext())
    517         return false;
    518 
    519     ScriptState::Scope scope(scriptState);
    520     v8::Handle<v8::Value> holder = toV8(holderImpl, scriptState->context()->Global(), scriptState->isolate());
    521 
    522     {% for argument in method.arguments %}
    523     v8::Handle<v8::Value> {{argument.handle}} = {{argument.private_script_cpp_value_to_v8_value}};
    524     {% endfor %}
    525     {% if method.arguments %}
    526     v8::Handle<v8::Value> argv[] = { {{method.arguments | join(', ', 'handle')}} };
    527     {% else %}
    528     {# Empty array initializers are illegal, and don\t compile in MSVC. #}
    529     v8::Handle<v8::Value> *argv = 0;
    530     {% endif %}
    531     ExceptionState exceptionState(ExceptionState::ExecutionContext, "{{method.name}}", "{{cpp_class}}", scriptState->context()->Global(), scriptState->isolate());
    532     v8::Handle<v8::Value> v8Value = PrivateScriptRunner::runDOMMethod(scriptState, scriptStateInUserScript, "{{cpp_class}}", "{{method.name}}", holder, {{method.arguments | length}}, argv);
    533     if (v8Value.IsEmpty())
    534         return false;
    535     {% if method.idl_type != 'void' %}
    536     {{method.private_script_v8_value_to_local_cpp_value}};
    537     *result = cppValue;
    538     {% endif %}
    539     RELEASE_ASSERT(!exceptionState.hadException());
    540     return true;
    541 }
    542 {% endmacro %}
    543 
    544 
    545 {##############################################################################}
    546 {% macro generate_constructor(constructor) %}
    547 {% set name = '%sConstructorCallback' % v8_class
    548               if constructor.is_named_constructor else
    549               'constructor%s' % (constructor.overload_index or '') %}
    550 static void {{name}}(const v8::FunctionCallbackInfo<v8::Value>& info)
    551 {
    552     {% if constructor.is_named_constructor %}
    553     if (!info.IsConstructCall()) {
    554         V8ThrowException::throwTypeError(ExceptionMessages::constructorNotCallableAsFunction("{{constructor.name}}"), info.GetIsolate());
    555         return;
    556     }
    557 
    558     if (ConstructorMode::current(info.GetIsolate()) == ConstructorMode::WrapExistingObject) {
    559         v8SetReturnValue(info, info.Holder());
    560         return;
    561     }
    562     {% endif %}
    563     {% if constructor.has_exception_state %}
    564     ExceptionState exceptionState(ExceptionState::ConstructionContext, "{{interface_name}}", info.Holder(), info.GetIsolate());
    565     {% endif %}
    566     {# Overloaded constructors have length checked during overload resolution #}
    567     {% if constructor.number_of_required_arguments and not constructor.overload_index %}
    568     if (UNLIKELY(info.Length() < {{constructor.number_of_required_arguments}})) {
    569         {{throw_minimum_arity_type_error(constructor, constructor.number_of_required_arguments) | indent(8)}}
    570         return;
    571     }
    572     {% endif %}
    573     {% if constructor.arguments %}
    574     {{generate_arguments(constructor) | indent}}
    575     {% endif %}
    576     {{cpp_method_call(constructor, constructor.v8_set_return_value, constructor.cpp_value) | indent}}
    577 }
    578 {% endmacro %}
    579 
    580 
    581 {##############################################################################}
    582 {% macro generate_constructor_wrapper(constructor) %}
    583 {% if has_custom_wrap %}
    584 v8::Handle<v8::Object> wrapper = wrap(impl.get(), info.Holder(), info.GetIsolate());
    585 {% else %}
    586 {% set constructor_class = v8_class + ('Constructor'
    587                                        if constructor.is_named_constructor else
    588                                        '') %}
    589 v8::Handle<v8::Object> wrapper = info.Holder();
    590 {% if is_script_wrappable %}
    591 impl->associateWithWrapper(&{{constructor_class}}::wrapperTypeInfo, wrapper, info.GetIsolate());
    592 {% else %}
    593 V8DOMWrapper::associateObjectWithWrapper<{{v8_class}}>(impl.release(), &{{constructor_class}}::wrapperTypeInfo, wrapper, info.GetIsolate());
    594 {% endif %}
    595 {% endif %}
    596 v8SetReturnValue(info, wrapper);
    597 {% endmacro %}
    598 
    599 
    600 {##############################################################################}
    601 {% macro method_configuration(method) %}
    602 {% set method_callback =
    603    '%sV8Internal::%sMethodCallback' % (cpp_class, method.name) %}
    604 {% set method_callback_for_main_world =
    605    '%sV8Internal::%sMethodCallbackForMainWorld' % (cpp_class, method.name)
    606    if method.is_per_world_bindings else '0' %}
    607 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
    608 {"{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}}}
    609 {%- endmacro %}
    610 
    611 
    612 {######################################}
    613 {% macro install_custom_signature(method) %}
    614 {% set method_callback = '%sV8Internal::%sMethodCallback' % (cpp_class, method.name) %}
    615 {% set method_callback_for_main_world = '%sForMainWorld' % method_callback
    616   if method.is_per_world_bindings else '0' %}
    617 {% set property_attribute =
    618   'static_cast<v8::PropertyAttribute>(%s)' % ' | '.join(method.property_attributes)
    619   if method.property_attributes else 'v8::None' %}
    620 {% set only_exposed_to_private_script = 'V8DOMConfiguration::OnlyExposedToPrivateScript' if method.only_exposed_to_private_script else 'V8DOMConfiguration::ExposedToAllScripts' %}
    621 static const V8DOMConfiguration::MethodConfiguration {{method.name}}MethodConfiguration = {
    622     "{{method.name}}", {{method_callback}}, {{method_callback_for_main_world}}, {{method.length}}, {{only_exposed_to_private_script}},
    623 };
    624 V8DOMConfiguration::installMethod({{method.function_template}}, {{method.signature}}, {{property_attribute}}, {{method.name}}MethodConfiguration, isolate);
    625 {%- endmacro %}
    626