| {% filter format_blink_cpp_source_code %} |
| |
| {% from 'utilities.cpp.tmpl' import declare_enum_validation_variable %} |
| {% include 'copyright_block.txt' %} |
| #include "{{this_include_header_name}}" |
| |
| {% for filename in cpp_includes if filename != '%s.h' % v8_class %} |
| #include "{{filename}}" |
| {% endfor %} |
| |
| namespace blink { |
| |
| {% if members %} |
| static const v8::Eternal<v8::Name>* eternal{{v8_class}}Keys(v8::Isolate* isolate) { |
| static const char* const kKeys[] = { |
| {% for member in members %} |
| "{{member.name}}", |
| {% endfor %} |
| }; |
| return V8PerIsolateData::From(isolate)->FindOrCreateEternalNameCache( |
| kKeys, kKeys, WTF_ARRAY_LENGTH(kKeys)); |
| } |
| {% endif %} |
| |
| {% from 'utilities.cpp.tmpl' import v8_value_to_local_cpp_value %} |
| void {{v8_class}}::ToImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, {{cpp_class}}& impl, ExceptionState& exceptionState) { |
| if (IsUndefinedOrNull(v8Value)) { |
| {% if required_member_names %} |
| exceptionState.ThrowTypeError("Missing required member(s): {{required_member_names|join(', ')}}."); |
| {% endif %} |
| return; |
| } |
| if (!v8Value->IsObject()) { |
| {% if use_permissive_dictionary_conversion %} |
| // Do nothing. |
| return; |
| {% else %} |
| exceptionState.ThrowTypeError("cannot convert to dictionary."); |
| return; |
| {% endif %} |
| } |
| v8::Local<v8::Object> v8Object = v8Value.As<v8::Object>(); |
| ALLOW_UNUSED_LOCAL(v8Object); |
| |
| {% if parent_v8_class %} |
| {{parent_v8_class}}::ToImpl(isolate, v8Value, impl, exceptionState); |
| if (exceptionState.HadException()) |
| return; |
| |
| {% endif %} |
| {# Declare local variables only when the dictionary has members to avoid unused variable warnings. #} |
| {% if members %} |
| const v8::Eternal<v8::Name>* keys = eternal{{v8_class}}Keys(isolate); |
| v8::TryCatch block(isolate); |
| v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| {% if has_origin_trial_members %} |
| ExecutionContext* executionContext = ToExecutionContext(context); |
| DCHECK(executionContext); |
| {% endif %}{# has_origin_trial_members #} |
| {% endif %}{# members #} |
| {% for origin_trial_test, origin_trial_member_list in members | groupby('origin_trial_feature_name') %} |
| {% filter origin_trial_enabled(origin_trial_test, "executionContext") %} |
| {% for feature_name, member_list in origin_trial_member_list | groupby('runtime_enabled_feature_name') %} |
| {% filter runtime_enabled(feature_name) %} |
| {% for member in member_list %} |
| v8::Local<v8::Value> {{member.name}}Value; |
| if (!v8Object->Get(context, keys[{{members.index(member)}}].Get(isolate)).ToLocal(&{{member.name}}Value)) { |
| exceptionState.RethrowV8Exception(block.Exception()); |
| return; |
| } |
| if ({{member.name}}Value.IsEmpty() || {{member.name}}Value->IsUndefined()) { |
| {% if member.is_required %} |
| exceptionState.ThrowTypeError("required member {{member.name}} is undefined."); |
| return; |
| {% else %} |
| // Do nothing. |
| {% endif %} |
| {% if member.is_nullable %} |
| } else if ({{member.name}}Value->IsNull()) { |
| impl.{{member.null_setter_name}}(); |
| {% endif %} |
| } else { |
| {% if member.deprecate_as %} |
| Deprecation::CountDeprecation(CurrentExecutionContext(isolate), WebFeature::k{{member.deprecate_as}}); |
| {% endif %} |
| {{v8_value_to_local_cpp_value(member) | indent}} |
| {% if member.is_interface_type %} |
| if (!{{member.name}}CppValue) { |
| exceptionState.ThrowTypeError("member {{member.name}} is not of type {{member.idl_type}}."); |
| return; |
| } |
| {% endif %} |
| {% if member.enum_values %} |
| {{declare_enum_validation_variable(member.enum_values) | indent}} |
| if (!IsValidEnum({{member.name}}CppValue, validValues, WTF_ARRAY_LENGTH(validValues), "{{member.enum_type}}", exceptionState)) |
| return; |
| {% elif member.is_object %} |
| if (!{{member.name}}CppValue.IsObject()) { |
| exceptionState.ThrowTypeError("member {{member.name}} is not an object."); |
| return; |
| } |
| {% endif %} |
| impl.{{member.setter_name}}({{member.name}}CppValue); |
| } |
| |
| {% endfor %} |
| {% endfilter %}{# runtime_enabled #} |
| |
| {% endfor %}{# origin_trial_member_list grouped by runtime_enabled #} |
| {% endfilter %}{# origin_trial_enabled #} |
| |
| {% endfor %}{# members grouped by origin_trial_enabled #} |
| } |
| |
| v8::Local<v8::Value> {{cpp_class}}::ToV8Impl(v8::Local<v8::Object> creationContext, v8::Isolate* isolate) const { |
| v8::Local<v8::Object> v8Object = v8::Object::New(isolate); |
| if (!toV8{{cpp_class}}(*this, v8Object, creationContext, isolate)) |
| return v8::Undefined(isolate); |
| return v8Object; |
| } |
| |
| bool toV8{{cpp_class}}(const {{cpp_class}}& impl, v8::Local<v8::Object> dictionary, v8::Local<v8::Object> creationContext, v8::Isolate* isolate) { |
| {% if parent_v8_class %} |
| if (!toV8{{parent_cpp_class}}(impl, dictionary, creationContext, isolate)) |
| return false; |
| |
| {% endif %} |
| {% if members %} |
| const v8::Eternal<v8::Name>* keys = eternal{{v8_class}}Keys(isolate); |
| v8::Local<v8::Context> context = isolate->GetCurrentContext(); |
| {% if has_origin_trial_members %} |
| ExecutionContext* executionContext = ToExecutionContext(context); |
| DCHECK(executionContext); |
| {% endif %}{# has_origin_trial_members #} |
| {% endif %}{# members #} |
| {% for origin_trial_test, origin_trial_member_list in members | groupby('origin_trial_feature_name') %} |
| {% filter origin_trial_enabled(origin_trial_test, "executionContext") %} |
| {% for feature_name, member_list in origin_trial_member_list | groupby('runtime_enabled_feature_name') %} |
| {% filter runtime_enabled(feature_name) %} |
| {% for member in member_list %} |
| v8::Local<v8::Value> {{member.name}}Value; |
| bool {{member.name}}HasValueOrDefault = false; |
| if (impl.{{member.has_method_name}}()) { |
| {% if member.is_object %} |
| DCHECK(impl.{{member.getter_name}}().IsObject()); |
| {% endif %} |
| {{member.name}}Value = {{member.cpp_value_to_v8_value}}; |
| {{member.name}}HasValueOrDefault = true; |
| {% if member.v8_default_value %} |
| } else { |
| {{member.name}}Value = {{member.v8_default_value}}; |
| {{member.name}}HasValueOrDefault = true; |
| {% elif member.is_nullable %} |
| } else { |
| {{member.name}}Value = v8::Null(isolate); |
| {{member.name}}HasValueOrDefault = true; |
| {% elif member.is_required %} |
| } else { |
| NOTREACHED(); |
| {% endif %} |
| } |
| {# The HasValueOrDefault variable will be optimized out. |
| If there is a default value, the compiler will notice that all branches set it to true. |
| If there is not, then the compiler will inline this call into the only branch that sets it to true. |
| Either way, the code is efficient and the variable is completely elided. #} |
| if ({{member.name}}HasValueOrDefault && |
| !V8CallBoolean(dictionary->CreateDataProperty(context, keys[{{members.index(member)}}].Get(isolate), {{member.name}}Value))) { |
| return false; |
| } |
| |
| {% endfor %} |
| {% endfilter %}{# runtime_enabled #} |
| |
| {% endfor %}{# origin_trial_member_list grouped by runtime_enabled #} |
| {% endfilter %}{# origin_trial_enabled #} |
| |
| {% endfor %}{# members grouped by origin_trial_enabled #} |
| return true; |
| } |
| |
| {{cpp_class}} NativeValueTraits<{{cpp_class}}>::NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exceptionState) { |
| {{cpp_class}} impl; |
| {{v8_class}}::ToImpl(isolate, value, impl, exceptionState); |
| return impl; |
| } |
| |
| } // namespace blink |
| |
| {% endfilter %}{# format_blink_cpp_source_code #} |