| {% from 'callback_invoke.cc.tmpl' import callback_invoke %} |
| {% filter format_blink_cpp_source_code %} |
| |
| {% include 'copyright_block.txt' %} |
| |
| #include "{{this_include_header_path}}" |
| |
| {% for filename in cpp_includes %} |
| #include "{{filename}}" |
| {% endfor %} |
| |
| namespace blink { |
| |
| {% if is_legacy_callback_interface %} |
| // Support of "legacy callback interface" |
| |
| // Suppress warning: global constructors, because struct WrapperTypeInfo is |
| // trivial and does not depend on another global objects. |
| #if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__) |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wglobal-constructors" |
| #endif |
| const WrapperTypeInfo {{v8_class}}::wrapperTypeInfo = { |
| gin::kEmbedderBlink, |
| {{v8_class}}::DomTemplate, |
| nullptr, |
| "{{interface_name}}", |
| nullptr, |
| WrapperTypeInfo::kWrapperTypeNoPrototype, |
| WrapperTypeInfo::kObjectClassId, |
| WrapperTypeInfo::kNotInheritFromActiveScriptWrappable, |
| }; |
| #if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__) |
| #pragma clang diagnostic pop |
| #endif |
| |
| {% from 'constants.cc.tmpl' import install_constants with context %} |
| static void Install{{v8_class}}Template(v8::Isolate* isolate, const DOMWrapperWorld& world, v8::Local<v8::FunctionTemplate> interface_template) { |
| // Legacy callback interface must not have a prototype object. |
| interface_template->RemovePrototype(); |
| |
| // Initialize the interface object's template. |
| V8DOMConfiguration::InitializeDOMInterfaceTemplate( |
| isolate, interface_template, |
| {{v8_class}}::wrapperTypeInfo.interface_name, |
| v8::Local<v8::FunctionTemplate>(), |
| kV8DefaultWrapperInternalFieldCount); |
| interface_template->SetLength(0); |
| |
| // Register IDL constants. |
| {# |install_constants| requires |interfaceTemplate| and |prototypeTemplate|. #} |
| v8::Local<v8::FunctionTemplate> interfaceTemplate = interface_template; |
| v8::Local<v8::ObjectTemplate> prototypeTemplate = |
| interface_template->PrototypeTemplate(); |
| {{install_constants() | trim | indent(2)}} |
| } |
| |
| // static |
| v8::Local<v8::FunctionTemplate> {{v8_class}}::DomTemplate(v8::Isolate* isolate, const DOMWrapperWorld& world) { |
| return V8DOMConfiguration::DomClassTemplate( |
| isolate, |
| world, |
| const_cast<WrapperTypeInfo*>(&wrapperTypeInfo), |
| Install{{v8_class}}Template); |
| } |
| {% endif %}{# is_legacy_callback_interface #} |
| |
| const char* {{v8_class}}::NameInHeapSnapshot() const { |
| return "{{v8_class}}"; |
| } |
| |
| // static |
| {{v8_class}}* {{v8_class}}::CreateOrNull(v8::Local<v8::Object> callback_object) { |
| v8::Local<v8::Context> creation_context = callback_object->CreationContext(); |
| // When |callback_object| is an object in RemoteContext (i.e. RemoteInstance), |
| // the object has no creation context, and no way to proceed. |
| // TODO(crbug.com/886588): Make CreateOrNull into Create removing the early |
| // return with nullptr. |
| if (creation_context.IsEmpty()) |
| return nullptr; |
| |
| return MakeGarbageCollected<{{v8_class}}>(callback_object, creation_context); |
| } |
| |
| {% for method in methods %} |
| |
| v8::Maybe<{{method.cpp_type}}> {{v8_class}}::{{method.name}}({{method.argument_declarations | join(', ')}}) { |
| {{callback_invoke( |
| 'callback interface', None, |
| method.cpp_type, method.native_value_traits_tag, method.arguments, |
| False, False, |
| interface_name, method.name)}} |
| } |
| |
| {% endfor %} |
| |
| {% if methods|length == 1 and methods[0].idl_type == 'void' %} |
| void {{v8_class}}::InvokeAndReportException({{methods[0].argument_declarations | join(', ')}}) { |
| v8::TryCatch try_catch(GetIsolate()); |
| try_catch.SetVerbose(true); |
| |
| v8::Maybe<void> maybe_result = |
| {{methods[0].name}}({{ |
| (['callback_this_value'] + |
| (methods[0].arguments|map(attribute='name')|list) |
| )|join(', ') |
| }}); |
| // An exception if any is killed with the v8::TryCatch above. |
| ALLOW_UNUSED_LOCAL(maybe_result); |
| } |
| {% endif %} |
| |
| {% if interface_name == 'EventListener' %} |
| bool {{v8_class}}::IsRunnableOrThrowException(IgnorePause ignore_pause) { |
| ScriptState* callback_relevant_script_state = |
| CallbackRelevantScriptState(); |
| |
| bool is_runnable = |
| ignore_pause == IgnorePause::kIgnore ? |
| IsCallbackFunctionRunnableIgnoringPause( |
| callback_relevant_script_state, IncumbentScriptState()) : |
| IsCallbackFunctionRunnable( |
| callback_relevant_script_state, IncumbentScriptState()); |
| if (is_runnable) |
| return true; |
| |
| // Wrapper-tracing for the callback function makes the function object and |
| // its creation context alive. Thus it's safe to use the creation context |
| // of the callback function here. |
| ScriptState::Scope scope(callback_relevant_script_state); |
| V8ThrowException::ThrowError( |
| GetIsolate(), |
| ExceptionMessages::FailedToExecute( |
| "{{methods[0].name}}", |
| "{{interface_name}}", |
| "The provided callback is no longer runnable.")); |
| return false; |
| } |
| |
| v8::Maybe<{{methods[0].cpp_type}}> {{v8_class}}::InvokeWithoutRunnabilityCheck({{methods[0].argument_declarations | join(', ')}}) { |
| {{callback_invoke( |
| 'callback interface', None, |
| methods[0].cpp_type, methods[0].native_value_traits_tag, methods[0].arguments, |
| False, True, |
| interface_name, methods[0].name)}} |
| } |
| {% endif %} |
| |
| {% for method in methods %} |
| v8::Maybe<{{method.cpp_type}}> V8PersistentCallbackInterface<{{v8_class}}>::{{method.name}}({{method.argument_declarations | join(', ')}}) { |
| return Proxy()->{{method.name}}( |
| {{ |
| (['callback_this_value'] + |
| (method.arguments|map(attribute='name')|list) |
| )|join(', ') |
| }}); |
| } |
| |
| {% endfor %} |
| |
| {% if methods|length == 1 and methods[0].idl_type == 'void' %} |
| void V8PersistentCallbackInterface<{{v8_class}}>::InvokeAndReportException({{methods[0].argument_declarations | join(', ')}}) { |
| Proxy()->InvokeAndReportException( |
| {{ |
| (['callback_this_value'] + |
| (methods[0].arguments|map(attribute='name')|list) |
| )|join(', ') |
| }}); |
| } |
| {% endif %} |
| |
| } // namespace blink |
| |
| {% endfilter %}{# format_blink_cpp_source_code #} |