| {# |
| # Copyright 2015 Google Inc. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| #} |
| {% extends "interface-base.cc.template" %} |
| {% block includes %} |
| #include "third_party/WebKit/Source/JavaScriptCore/config.h" |
| |
| {{ super() }} |
| #include "cobalt/script/javascriptcore/constructor_base.h" |
| #include "cobalt/script/javascriptcore/conversion_helpers.h" |
| #include "cobalt/script/javascriptcore/prototype_base.h" |
| #include "cobalt/script/javascriptcore/jsc_callback_function.h" |
| #include "cobalt/script/javascriptcore/jsc_callback_interface_holder.h" |
| #include "cobalt/script/javascriptcore/jsc_exception_state.h" |
| #include "cobalt/script/javascriptcore/jsc_global_object.h" |
| #include "cobalt/script/javascriptcore/jsc_global_object_proxy.h" |
| #include "cobalt/script/javascriptcore/jsc_object_handle.h" |
| #include "cobalt/script/javascriptcore/jsc_object_handle_holder.h" |
| {% if named_property_getter %} |
| #include "cobalt/script/javascriptcore/jsc_property_enumerator.h" |
| {% endif %} |
| #include "cobalt/script/javascriptcore/type_traits.h" |
| #include "cobalt/script/javascriptcore/util/binding_helpers.h" |
| #include "cobalt/script/javascriptcore/util/exception_helpers.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/interpreter/Interpreter.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/Error.h" |
| {% if is_exception_interface %} |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/ErrorPrototype.h" |
| {% endif %} |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/FunctionPrototype.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/Identifier.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/JSFunction.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h" |
| #include "third_party/WebKit/Source/JavaScriptCore/runtime/ObjectPrototype.h" |
| {% endblock includes %} |
| {% block using_directives %} |
| {{ super() }} |
| using cobalt::script::javascriptcore::kConversionFlagNullable; |
| using cobalt::script::javascriptcore::kConversionFlagRestricted; |
| using cobalt::script::javascriptcore::kConversionFlagTreatNullAsEmptyString; |
| using cobalt::script::javascriptcore::kConversionFlagTreatUndefinedAsEmptyString; |
| using cobalt::script::javascriptcore::kNoConversionFlags; |
| using cobalt::script::javascriptcore::ConstructorBase; |
| using cobalt::script::javascriptcore::GetWrappableOrSetException; |
| using cobalt::script::javascriptcore::FromJSValue; |
| using cobalt::script::javascriptcore::FromWTFString; |
| using cobalt::script::javascriptcore::JSCCallbackFunction; |
| using cobalt::script::javascriptcore::JSCCallbackFunctionHolder; |
| using cobalt::script::javascriptcore::JSCCallbackInterfaceHolder; |
| using cobalt::script::javascriptcore::JSCEngine; |
| using cobalt::script::javascriptcore::JSCExceptionState; |
| using cobalt::script::javascriptcore::JSCObjectHandle; |
| using cobalt::script::javascriptcore::JSCObjectHandleHolder; |
| using cobalt::script::javascriptcore::JSCGlobalObject; |
| using cobalt::script::javascriptcore::JSCGlobalObjectProxy; |
| {% if named_property_getter %} |
| using cobalt::script::javascriptcore::JSCPropertyEnumerator; |
| {% endif %} |
| using cobalt::script::javascriptcore::JSObjectToWrappable; |
| using cobalt::script::javascriptcore::ScriptObjectRegistry; |
| using cobalt::script::javascriptcore::ToJSValue; |
| using cobalt::script::javascriptcore::ToWTFString; |
| using cobalt::script::javascriptcore::TypeTraits; |
| using cobalt::script::javascriptcore::PrototypeBase; |
| using cobalt::script::javascriptcore::ThreadLocalHashTable; |
| using cobalt::script::javascriptcore::WrapperBase; |
| using cobalt::script::javascriptcore::util::HasPropertyOnPrototype; |
| using cobalt::script::javascriptcore::util::GetStackTrace; |
| {% endblock using_directives %} |
| {% block enumeration_declarations %} |
| {% if enumerations|length %} |
| // Declare and define these in the same namespace that the other overloads |
| // were brought into with the using declaration. |
| {% for enumeration in enumerations %} |
| JSC::JSValue ToJSValue(JSCGlobalObject*, {{impl_class}}::{{enumeration.name}} in_enum); |
| void FromJSValue(JSC::ExecState* exec_state, JSC::JSValue jsvalue, |
| int conversion_flags, JSCExceptionState* exception_state, |
| {{impl_class}}::{{enumeration.name}}* out_enum); |
| {% endfor %} |
| {% endif %} |
| {% endblock enumeration_declarations %} |
| |
| {% from 'macros.cc.template' import add_extra_arguments %} |
| {% from 'macros.cc.template' import call_function %} |
| {% from 'macros.cc.template' import constructor_implementation with context %} |
| {% from 'macros.cc.template' import function_implementation with context %} |
| {% from 'macros.cc.template' import overload_resolution_implementation with context %} |
| {% from 'macros.cc.template' import set_attribute_implementation with context %} |
| {% from 'interface-object.template' import create_interface_object with context %} |
| |
| {% block implementation %} |
| namespace { |
| {% for constant in constants %} |
| JSC::JSValue getJS{{constant.idl_name}}( |
| JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, |
| JSC::PropertyName property_name); |
| {% endfor %} |
| {% for attribute in attributes + static_attributes %} |
| {% if attribute.conditional %} |
| #if defined({{attribute.conditional}}) |
| {% endif %} |
| JSC::JSValue getJS{{attribute.idl_name}}( |
| JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, |
| JSC::PropertyName property_name); |
| {% if attribute.has_setter %} |
| void setJS{{attribute.idl_name}}( |
| JSC::ExecState* exec, |
| JSC::JSObject* this_object, |
| JSC::JSValue value); |
| {% endif %} |
| {% if attribute.conditional %} |
| #endif // defined({{attribute.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% if constructor %} |
| JSC::EncodedJSValue constructorJS{{impl_class}}(JSC::ExecState*); |
| {% for overload in constructor.overloads if constructor.overloads|length > 1 %} |
| JSC::EncodedJSValue constructorJS{{impl_class}}{{overload.overload_index}}(JSC::ExecState*); |
| {% endfor %} |
| {% endif %} |
| {% for operation in operations + static_operations %} |
| {% if operation.conditional %} |
| #if defined({{operation.conditional}}) |
| {% endif %} |
| {% set boundFunctionPrefix = "staticFunctionJS" if operation.is_static else "functionJS" %} |
| JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}(JSC::ExecState*); |
| {% for overload in operation.overloads if operation.overloads|length > 1 %} |
| JSC::EncodedJSValue {{boundFunctionPrefix}}{{overload.idl_name}}{{overload.overload_index}}(JSC::ExecState*); |
| {% endfor %} |
| {% if operation.conditional %} |
| #endif // defined({{operation.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% if indexed_property_getter %} |
| JSC::JSValue IndexedPropertyGetter(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, uint32_t index); |
| {% endif %} |
| {% if indexed_property_setter %} |
| void IndexedPropertySetter(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, uint32_t index, JSC::JSValue value); |
| {% endif %} |
| {% if stringifier %} |
| JSC::EncodedJSValue StringifierJS(JSC::ExecState*); |
| {% endif %} |
| |
| // These are declared unconditionally, but only defined if needed by the |
| // interface. |
| JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name); |
| void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue jsc_value); |
| bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name); |
| bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name); |
| JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name); |
| bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue value); |
| |
| const bool s_has_named_getter = {{'true' if named_property_getter else 'false'}}; |
| const bool s_has_named_setter = {{'true' if named_property_setter else 'false'}}; |
| #if !defined(COBALT_BUILD_TYPE_GOLD) |
| const bool s_use_debug_missing_property_handler = {{'true' if not parent_interface else 'false'}}; |
| #else |
| const bool s_use_debug_missing_property_handler = false; |
| #endif |
| {% if get_opaque_root %} |
| scoped_refptr<Wrappable> GetOpaqueRootFromWrappable( |
| const scoped_refptr<Wrappable>& wrappable) { |
| {{impl_class}}* impl = |
| base::polymorphic_downcast<{{impl_class}}*>(wrappable.get()); |
| Wrappable* opaque_root = impl->{{get_opaque_root}}(); |
| return make_scoped_refptr<Wrappable>(opaque_root); |
| } |
| {% endif %} |
| } // namespace |
| |
| {% if has_interface_object %} |
| {{create_interface_object("InterfaceObject", impl_class)}} |
| {% endif %} |
| {% if named_constructor %} |
| {{create_interface_object("NamedInterfaceObject", named_constructor)}} |
| {% endif %} |
| {% include "prototype-object.template" %} |
| |
| const JSC::HashTableValue {{binding_class}}::property_table_values[] = { |
| {% for attribute in attributes %} |
| {% if attribute.conditional %} |
| #if defined({{attribute.conditional}}) |
| {% endif %} |
| { "{{attribute.idl_name}}", |
| JSC::DontDelete {{'| JSC::ReadOnly' if not attribute.has_setter}}, |
| reinterpret_cast<intptr_t>(getJS{{attribute.idl_name}}), |
| {% if attribute.has_setter %} |
| reinterpret_cast<intptr_t>(setJS{{attribute.idl_name}}), |
| {% else %} |
| 0, |
| {% endif %} |
| JSC::NoIntrinsic |
| }, |
| {% if attribute.conditional %} |
| #endif // defined({{attribute.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% if is_global_interface %} |
| {% for operation in operations %} |
| {% if operation.conditional %} |
| #if defined({{operation.conditional}}) |
| {% endif %} |
| { "{{operation.idl_name}}", |
| JSC::DontDelete | JSC::Function, |
| reinterpret_cast<intptr_t>(functionJS{{operation.idl_name}}), |
| static_cast<intptr_t>({{operation.length}}), |
| JSC::NoIntrinsic |
| }, |
| {% if operation.conditional %} |
| #endif // defined({{operation.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% endif %} |
| { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) } |
| }; // {{binding_class}}::property_table_values |
| |
| // static |
| const JSC::HashTable {{binding_class}}::property_table_prototype = { |
| {# This doesn't take into account disabled properties, but this is okay. This |
| value must be at least as large as the number of properties. #} |
| {% set num_properties = attributes|length %} |
| {% if is_global_interface %} |
| {% set num_properties = num_properties + operations|length %} |
| {% endif %} |
| {{ calculate_jsc_lookup_size(num_properties) }}, // compactSize |
| {{ calculate_jsc_lookup_size_mask(num_properties) }}, // compactSizeMask |
| property_table_values, |
| NULL // table allocated at runtime |
| }; // {{binding_class}}::property_table_prototype |
| |
| // static |
| const JSC::HashTable* {{binding_class}}::GetPropertyTable( |
| JSC::ExecState* exec_state) { |
| return ThreadLocalHashTable::GetInstance()->GetHashTable( |
| {{binding_class}}::s_classinfo(), property_table_prototype); |
| } |
| |
| #ifdef __LB_SHELL__FORCE_LOGGING__ |
| base::LazyInstance<{{binding_class}}::NonTrivialStaticFields> |
| {{binding_class}}::non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER; |
| #endif // __LB_SHELL__FORCE_LOGGING__ |
| |
| const JSC::ClassInfo {{binding_class}}::s_info = { |
| "{{interface_name}}", // className |
| BaseClass::s_classinfo(), // parentClass |
| NULL, // static hash-table of properties (not used) |
| GetPropertyTable, // function pointer to get hash-table of properties |
| CREATE_METHOD_TABLE({{binding_class}}) |
| }; // {{binding_class}}::s_info |
| |
| // static |
| JSC::JSObject* {{binding_class}}::GetPrototype( |
| JSC::JSGlobalObject* global_object) { |
| return Prototype::GetInstance(global_object); |
| } |
| |
| {% if has_interface_object %} |
| // static |
| JSC::JSObject* {{binding_class}}::GetConstructor( |
| JSC::ExecState* exec_state) { |
| return InterfaceObject::GetInstance(exec_state); |
| } |
| |
| // static |
| JSC::JSValue {{binding_class}}::Prototype::GetConstructor( |
| JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, |
| JSC::PropertyName property_name) { |
| return JSC::JSValue(InterfaceObject::GetInstance(exec_state)); |
| } |
| {% endif %} |
| {% if named_constructor %} |
| JSC::JSObject* {{binding_class}}::GetNamedConstructor( |
| JSC::ExecState* exec_state) { |
| return NamedInterfaceObject::GetInstance(exec_state); |
| } |
| {% endif %} |
| {% if is_global_interface %} |
| |
| // static |
| script::javascriptcore::JSCGlobalObject* {{binding_class}}::Create( |
| const scoped_refptr<{{impl_class}}>& global_interface, |
| script::EnvironmentSettings* environment_settings, |
| JSC::JSGlobalData* global_data, |
| ScriptObjectRegistry* script_object_registry) { |
| scoped_ptr<script::javascriptcore::WrapperFactory> wrapper_factory = |
| make_scoped_ptr(new script::javascriptcore::WrapperFactory()); |
| {% for interface in all_interfaces %} |
| {% if interface.conditional %} |
| #if defined({{interface.conditional}}) |
| {% endif %} |
| {# Don't register a create method for the global interface, since we do not |
| create a wrapper for it directly. #} |
| {% if interface.name != impl_class %} |
| wrapper_factory->RegisterWrappableType( |
| {{interface.name}}::{{interface.name}}WrappableType(), |
| JSC{{interface.name}}::s_classinfo(), |
| JSC{{interface.name}}::GetCreateWrapperFunction()); |
| {% endif %} |
| {% if interface.conditional %} |
| #endif // defined({{interface.conditional}}) |
| {% endif %} |
| {% endfor %} |
| |
| JSC::JSLockHolder lock(global_data); |
| JSC::Structure* structure = JSC::Structure::create( |
| *global_data, |
| NULL, // JSC::JSGlobalObject* |
| JSC::jsNull(), // prototype |
| JSC::TypeInfo(JSC::GlobalObjectType, StructureFlags), |
| &s_info); |
| {{binding_class}}* global_wrapper = |
| new (NotNull, JSC::allocateCell<{{binding_class}}>(global_data->heap)) |
| {{binding_class}}( |
| global_data, |
| structure, |
| script_object_registry, |
| wrapper_factory.Pass(), |
| environment_settings, |
| global_interface); |
| global_wrapper->finishCreation(*global_data); |
| global_data->heap.addFinalizer(global_wrapper, {{binding_class}}::destroy); |
| global_wrapper->setPrototype( |
| global_wrapper->globalData(), |
| {{binding_class}}::GetPrototype(global_wrapper)); |
| |
| return global_wrapper; |
| } |
| {% else %} |
| |
| // static |
| JSC::JSObject* {{binding_class}}::Create( |
| JSCGlobalObject* global_object, |
| const scoped_refptr<Wrappable>& wrappable) { |
| if (!(wrappable->GetWrappableType() == {{impl_class}}::{{impl_class}}WrappableType())) { |
| NOTREACHED() << "Type of wrappable does not match {{impl_class}}::{{impl_class}}WrappableType()"; |
| return NULL; |
| } |
| {{impl_class}}* impl_ptr = |
| base::polymorphic_downcast<{{impl_class}}*>(wrappable.get()); |
| |
| JSC::JSGlobalData& global_data = global_object->globalData(); |
| |
| // Get or Create the prototype object for this interface. |
| JSC::JSObject* prototype = Prototype::GetInstance(global_object); |
| DCHECK(prototype); |
| |
| JSC::JSLockHolder lock(global_data); |
| // Create a JSC::Structure object for this instance. |
| {% if is_exception_interface %} |
| JSC::TypeInfo type_info(JSC::ErrorInstanceType, StructureFlags); |
| {% else %} |
| JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags); |
| {% endif %} |
| JSC::Structure* structure = JSC::Structure::create( |
| global_data, |
| global_object, |
| JSC::JSValue(prototype), |
| type_info, |
| &s_info); |
| |
| // Instantiate a new garbage-collected wrapper object. |
| {{binding_class}}* wrapper = |
| new (NotNull, JSC::allocateCell<{{binding_class}}>(global_data.heap)) |
| {{binding_class}}( |
| &global_data, |
| structure, |
| global_object->script_object_registry(), |
| make_scoped_refptr(impl_ptr)); |
| wrapper->finishCreation(global_data); |
| {% if is_exception_interface %} |
| global_data.heap.addFinalizer(wrapper, destroy); |
| {% endif %} |
| return wrapper; |
| } |
| {% endif %} |
| {{binding_class}}::{{binding_class}}( |
| JSC::JSGlobalData* global_data, |
| JSC::Structure* structure, |
| ScriptObjectRegistry* script_object_registry, |
| {% if is_global_interface %} |
| scoped_ptr<script::javascriptcore::WrapperFactory> wrapper_factory, |
| script::EnvironmentSettings* environment_settings, |
| {% endif %} |
| const scoped_refptr<{{impl_class}}>& impl) |
| : BaseClass(global_data, structure, script_object_registry, impl{% if is_global_interface %}, |
| wrapper_factory.Pass(), environment_settings{% endif %}) { |
| {% if get_opaque_root %} |
| set_get_opaque_root_function(base::Bind(&GetOpaqueRootFromWrappable)); |
| {% endif %} |
| } |
| |
| void {{binding_class}}::finishCreation(JSC::JSGlobalData& global_data) { |
| {% if is_exception_interface %} |
| WTF::String error_message = ToWTFString(wrappable()->message()); |
| BaseClass::finishCreation(global_data, error_message); |
| {% else %} |
| BaseClass::finishCreation(global_data); |
| {% endif %} |
| DCHECK(inherits(&s_info)); |
| } |
| |
| {{binding_class}}::~{{binding_class}}() { |
| // Empty destructor |
| } |
| {% if add_opaque_roots %} |
| |
| void {{binding_class}}::visitChildren(JSC::JSCell* cell, JSC::SlotVisitor& visitor) { |
| WrapperBase<JSC::JSDestructibleObject, Wrappable>::visitChildren( |
| cell, visitor); |
| |
| JSCGlobalObject* global_object = JSC::jsCast<JSCGlobalObject*>( |
| JSC::jsCast<JSObject*>(cell)->globalObject()); |
| |
| {{impl_class}}* impl = base::polymorphic_downcast<{{impl_class}}*>( |
| JSC::jsCast<WrapperBase*>(cell)->wrappable().get()); |
| |
| {% for opaque_root in add_opaque_roots %} |
| Wrappable* opaque_root{{loop.index0}} = impl->{{opaque_root}}(); |
| if (opaque_root{{loop.index0}}) { |
| visitor.addOpaqueRoot(opaque_root{{loop.index0}}); |
| } |
| {% endfor %} |
| } |
| {% endif %} |
| |
| // Look up property slot for querying property values. |
| bool {{binding_class}}::getOwnPropertySlot(JSC::JSCell* cell, |
| JSC::ExecState* exec, JSC::PropertyName property_name, |
| JSC::PropertySlot& slot) { |
| {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell); |
| ASSERT_GC_OBJECT_INHERITS(this_object, &s_info); |
| {% if is_global_interface %} |
| // Global interface may have both operations and properties as own properties |
| // so we cannot use getStaticValueSlot. |
| bool found_property_slot = JSC::getStaticPropertySlot<{{binding_class}}, BaseClass>( |
| exec, GetPropertyTable(exec), this_object, property_name, slot); |
| {% else %} |
| bool found_property_slot = JSC::getStaticValueSlot<{{binding_class}}, BaseClass>( |
| exec, GetPropertyTable(exec), this_object, property_name, slot); |
| {% endif %} |
| if (s_has_named_getter || s_use_debug_missing_property_handler) { |
| bool found_property_on_prototype_chain = false; |
| if (!found_property_slot && cell->isObject()) { |
| JSC::JSValue prototype_value = JSC::asObject(cell)->prototype(); |
| if (prototype_value.isObject()) { |
| JSC::JSObject* prototype = JSC::asObject(prototype_value); |
| found_property_on_prototype_chain = |
| prototype->hasProperty(exec, property_name); |
| } |
| } |
| if (s_has_named_getter) { |
| if (!found_property_slot && !found_property_on_prototype_chain) { |
| if (QueryNamedProperty(this_object, exec, property_name)) { |
| slot.setCustom(cell, &NamedPropertyGetter); |
| found_property_slot = true; |
| } |
| } |
| } |
| if (s_use_debug_missing_property_handler) { |
| // The property was not found as an own-property, nor was it found on the |
| // prototype chain, so set the missing property handler to be called |
| // when getting this property value. |
| if (!found_property_slot && !found_property_on_prototype_chain) { |
| slot.setCustom(cell, &OnGetMissingProperty); |
| found_property_slot = true; |
| } |
| } |
| } |
| return found_property_slot; |
| } |
| {% if indexed_property_getter or named_property_getter %} |
| |
| // static |
| bool {{binding_class}}::getOwnPropertySlotByIndex(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, uint32_t index, JSC::PropertySlot& slot) { |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (!impl) { |
| return false; |
| } |
| {% if indexed_property_getter %} |
| if (index < impl->length()) { |
| slot.setCustomIndex(cell, index, IndexedPropertyGetter); |
| return true; |
| } |
| {% endif %} |
| if (s_has_named_getter) { |
| {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell); |
| JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index); |
| bool has_property = HasOwnPropertyOrPrototypeProperty( |
| cell, exec_state, property_name); |
| if (!has_property) { |
| if (QueryNamedProperty(this_object, exec_state, property_name)) { |
| slot.setCustom(cell, &NamedPropertyGetter); |
| return true; |
| } |
| } |
| } |
| return Base::getOwnPropertySlotByIndex(cell, exec_state, index, slot); |
| } |
| |
| void {{binding_class}}::getOwnPropertyNames(JSC::JSObject* object, |
| JSC::ExecState* exec_state, JSC::PropertyNameArray& property_names, |
| JSC::EnumerationMode mode) { |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, object); |
| if (impl) { |
| {% if indexed_property_getter %} |
| for (uint32 i = 0; i < impl->length(); ++i) { |
| property_names.add(JSC::Identifier::from(exec_state, i)); |
| } |
| {% endif %} |
| {% if named_property_getter %} |
| JSCPropertyEnumerator enumerator(exec_state, &property_names); |
| impl->EnumerateNamedProperties(&enumerator); |
| {% endif %} |
| Base::getOwnPropertyNames(object, exec_state, property_names, mode); |
| } |
| } |
| {% endif %} |
| |
| // Look up property slot and put the |value|. |
| void {{binding_class}}::put(JSC::JSCell* cell, JSC::ExecState* exec, |
| JSC::PropertyName property_name, JSC::JSValue value, |
| JSC::PutPropertySlot& slot) { |
| {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell); |
| ASSERT_GC_OBJECT_INHERITS(this_object, &s_info); |
| bool property_handled = false; |
| if (s_has_named_setter || s_use_debug_missing_property_handler) { |
| // Need to look up the property manually. |
| bool has_property = HasOwnPropertyOrPrototypeProperty( |
| cell, exec, property_name); |
| |
| if (s_has_named_setter) { |
| // We didn't find the property on the object or prototype chain, so |
| // set or create a new named property. |
| if (!has_property) { |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| NamedPropertySetter(cell, exec, property_name, value); |
| property_handled = true; |
| } |
| } |
| if (s_use_debug_missing_property_handler) { |
| if (!has_property && !property_handled) { |
| property_handled = OnSetMissingProperty(cell, exec, property_name, value); |
| } |
| } |
| {% if not is_global_interface and not parent_interface %} |
| #ifdef __LB_SHELL__FORCE_LOGGING__ |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| |
| base::AutoLock lock(non_trivial_static_fields.Get().lock_); |
| base::hash_set<std::string>& properties_warned_about = |
| non_trivial_static_fields.Get().properties_warned_about; |
| |
| if (properties_warned_about.find(property_name_utf8) == |
| properties_warned_about.end()) { |
| properties_warned_about.insert(property_name_utf8); |
| WTF::String class_name = cell->className(); |
| DLOG_IF(WARNING, !has_property) << "Did not find property named " << |
| property_name_utf8 << " to set on wrapper for " |
| << FromWTFString(class_name) |
| << std::endl << StackTraceToString(GetStackTrace(exec, 32)) |
| << std::endl; |
| } |
| #endif // __LB_SHELL__FORCE_LOGGING__ |
| {% endif %} |
| } |
| |
| if (!property_handled) { |
| JSC::lookupPut<{{binding_class}}, BaseClass>( |
| exec, property_name, value, GetPropertyTable(exec), this_object, slot); |
| } |
| } |
| {% if indexed_property_setter or named_property_setter %} |
| |
| // static |
| void {{binding_class}}::putByIndex(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, uint32_t index, JSC::JSValue value, |
| bool should_throw) { |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (impl) { |
| bool property_handled = false; |
| {% if indexed_property_setter %} |
| if (index < impl->length()) { |
| IndexedPropertySetter(cell, exec_state, index, value); |
| property_handled = true; |
| } |
| {% endif %} |
| if (s_has_named_setter) { |
| if (!property_handled) { |
| JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index); |
| bool has_property = HasOwnPropertyOrPrototypeProperty( |
| cell, exec_state, property_name); |
| if (!has_property) { |
| NamedPropertySetter(cell, exec_state, property_name, value); |
| property_handled = true; |
| } |
| } |
| } |
| if (!property_handled) { |
| Base::putByIndex(cell, exec_state, index, value, should_throw); |
| } |
| } |
| } |
| |
| {% endif %} |
| {% if supports_named_properties %} |
| |
| bool {{binding_class}}::deleteProperty(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, |
| JSC::PropertyName property_name) { |
| TRACE_EVENT1("{{binding_class}}", "deleteProperty", "property", |
| TRACE_STR_COPY(WTF::String(property_name.publicName()).utf8().data())); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (impl) { |
| bool has_property = HasOwnPropertyOrPrototypeProperty( |
| cell, exec_state, property_name); |
| if (!has_property && |
| QueryNamedProperty(cell, exec_state, property_name)) { |
| return NamedPropertyDeleter(cell, exec_state, property_name); |
| } |
| return Base::deleteProperty(cell, exec_state, property_name); |
| } |
| return false; |
| } |
| {% endif %} |
| {% if supports_named_properties or supports_indexed_properties %} |
| |
| bool {{binding_class}}::deletePropertyByIndex(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, |
| uint32_t index) { |
| TRACE_EVENT0("{{binding_class}}", "deletePropertyByIndex"); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (impl) { |
| {% if supports_indexed_properties %} |
| // https://heycam.github.io/webidl/#delete |
| // Return true if index is not a supported property index. |
| return index >= impl->length(); |
| {% elif supports_named_properties %} |
| JSC::PropertyName property_name = JSC::Identifier::from(exec_state, index); |
| bool has_property = HasOwnPropertyOrPrototypeProperty( |
| cell, exec_state, property_name); |
| if (!has_property && |
| QueryNamedProperty(cell, exec_state, property_name)) { |
| return NamedPropertyDeleter(cell, exec_state, property_name); |
| } |
| return Base::deletePropertyByIndex(cell, exec_state, index); |
| {% endif %} |
| } |
| return false; |
| } |
| {% endif %} |
| |
| bool {{binding_class}}::HasOwnPropertyOrPrototypeProperty( |
| JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name) { |
| {{binding_class}}* this_object = JSC::jsCast<{{binding_class}}*>(cell); |
| JSC::PropertySlot lookup_slot; |
| bool has_property = JSC::getStaticPropertySlot<{{binding_class}}, BaseClass>( |
| exec_state, GetPropertyTable(exec_state), this_object, property_name, |
| lookup_slot); |
| return has_property || HasPropertyOnPrototype(exec_state, cell, property_name); |
| } |
| |
| namespace { |
| {% for constant in constants %} |
| |
| JSC::JSValue getJS{{constant.idl_name}}( |
| JSC::ExecState* exec_state, JSC::JSValue, JSC::PropertyName) { |
| TRACE_EVENT0("{{binding_class}}", "get {{constant.idl_name}}"); |
| {% if constant.can_use_compile_assert %} |
| COMPILE_ASSERT({{impl_class}}::{{constant.name}} == {{constant.value}}, |
| ValueFor{{impl_class}}_{{constant.name}}DoesNotMatchIDL); |
| {% else %} |
| DCHECK_EQ({{constant.value}}, {{impl_class}}::{{constant.name}}) << |
| "The value for {{impl_class}}::{{constant.name}} does not match " |
| "the value in the interface definition."; |
| {% endif %} |
| // JSCGlobalObject* is only needed for non-primitive types. |
| return ToJSValue(NULL, {{constant.value}}); |
| } |
| {% endfor %} |
| {% for attribute in attributes + static_attributes %} |
| |
| {% if attribute.conditional %} |
| #if defined({{attribute.conditional}}) |
| {% endif %} |
| JSC::JSValue getJS{{attribute.idl_name}}( |
| JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, |
| JSC::PropertyName property_name) { |
| TRACE_EVENT0("{{binding_class}}", "get {{attribute.idl_name}}"); |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| {% if not attribute.is_static %} |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base); |
| if (!impl) { |
| return exec_state->exception(); |
| } |
| {% endif %} |
| {% if attribute.raises_exception %} |
| JSCExceptionState exception_state(global_object); |
| {% endif %} |
| |
| {% if attribute.is_named_constructor_attribute %} |
| JSC::JSObject* constructor_object = |
| JSC{{attribute.interface_name}}::GetNamedConstructor( |
| global_object->globalExec()); |
| DCHECK(constructor_object) |
| << "NULL constructor returned for {{attribute.interface_name}}."; |
| return JSC::JSValue(constructor_object); |
| {% elif attribute.is_constructor_attribute %} |
| JSC::JSObject* constructor_object = |
| JSC{{attribute.interface_name}}::GetConstructor( |
| global_object->globalExec()); |
| DCHECK(constructor_object) |
| << "NULL constructor returned for {{attribute.interface_name}}."; |
| return JSC::JSValue(constructor_object); |
| {% else %} |
| {% call(arguments_list) add_extra_arguments('global_object', [], attribute) %} |
| JSC::JSValue result = ToJSValue( |
| global_object, |
| {{ call_function("impl", impl_class, attribute.getter_function_name, arguments_list, attribute.is_static) -}}); |
| {% if attribute.raises_exception %} |
| if (exception_state.is_exception_set()) { |
| return JSC::throwError(exec_state, exception_state.exception_object()); |
| } |
| {% endif %} |
| return result; |
| {% endcall %} |
| {% endif %} |
| } |
| {% if attribute.has_setter %} |
| |
| void setJS{{attribute.idl_name}}( |
| JSC::ExecState* exec_state, |
| JSC::JSObject* this_object, |
| JSC::JSValue value) { |
| TRACE_EVENT0("{{binding_class}}", "set {{attribute.idl_name}}"); |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSCExceptionState exception_state(global_object); |
| {% if not attribute.is_static %} |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, this_object); |
| if (!impl) { |
| return; |
| } |
| {% endif %} |
| {{ set_attribute_implementation(attribute, impl_class, "impl") }} |
| } |
| {% endif %} |
| {% if attribute.conditional %} |
| #endif // defined({{attribute.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% if constructor %} |
| |
| JSC::EncodedJSValue constructorJS{{impl_class}}(JSC::ExecState* exec_state) { |
| {% if constructor.overloads|length == 1 %} |
| {{constructor_implementation(constructor.overloads[0])}} |
| {% else %} |
| {{overload_resolution_implementation(constructor, 'constructorJS' + impl_class)}} |
| {% endif %} |
| } |
| {% for overload in constructor.overloads if constructor.overloads|length > 1 %} |
| |
| JSC::EncodedJSValue constructorJS{{impl_class}}{{overload.overload_index}}(JSC::ExecState* exec_state) { |
| {{constructor_implementation(overload)}} |
| } |
| {% endfor %} |
| {% endif %} |
| {% for operation in operations + static_operations %} |
| {% if operation.conditional %} |
| #if defined({{operation.conditional}}) |
| {% endif %} |
| |
| {% set boundFunctionPrefix = "staticFunctionJS" if operation.is_static else "functionJS" %} |
| JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}( |
| JSC::ExecState* exec_state) { |
| TRACE_EVENT0("{{binding_class}}", "call {{operation.idl_name}}"); |
| {% if operation.overloads|length == 1 %} |
| {{function_implementation(operation.overloads[0])}} |
| {% else %} |
| {{overload_resolution_implementation(operation, boundFunctionPrefix + operation.idl_name)}} |
| {% endif %} |
| } |
| {% for overload in operation.overloads if operation.overloads|length > 1 %} |
| |
| JSC::EncodedJSValue {{boundFunctionPrefix}}{{operation.idl_name}}{{overload.overload_index}}( |
| JSC::ExecState* exec_state) { |
| {{function_implementation(overload)}} |
| } |
| {% endfor %} |
| {% if operation.conditional %} |
| #endif // defined({{operation.conditional}}) |
| {% endif %} |
| {% endfor %} |
| {% if indexed_property_getter %} |
| |
| JSC::JSValue IndexedPropertyGetter(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, uint32_t index) { |
| TRACE_EVENT0("{{binding_class}}", "IndexedPropertyGetter"); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base); |
| if (!impl) { |
| return exec_state->exception(); |
| } |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSCExceptionState exception_state(global_object); |
| {% call(arguments_list) |
| add_extra_arguments('global_object', ['index'], indexed_property_getter) %} |
| JSC::JSValue result = ToJSValue( |
| global_object, |
| {{ call_function("impl", impl_class, indexed_property_getter.name, |
| arguments_list, False) -}}); |
| {% if indexed_property_getter.raises_exception %} |
| if (exception_state.is_exception_set()) { |
| return JSC::throwError(exec_state, exception_state.exception_object()); |
| } |
| {% endif %} |
| return result; |
| {% endcall %} |
| } |
| {% endif %} |
| {% if indexed_property_setter %} |
| |
| void IndexedPropertySetter(JSC::JSCell* cell, |
| JSC::ExecState* exec_state, uint32_t index, JSC::JSValue jsc_value) { |
| TRACE_EVENT0("{{binding_class}}", "IndexedPropertySetter"); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (!impl) { |
| return; |
| } |
| |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSCExceptionState exception_state(global_object); |
| {{indexed_property_setter.type}} value; |
| FromJSValue(exec_state, jsc_value, |
| {{indexed_property_setter.conversion_flags}}, |
| &exception_state, &value); |
| if (exception_state.is_exception_set()) { |
| JSC::throwError(exec_state, exception_state.exception_object()); |
| return; |
| } |
| {% call(arguments_list) add_extra_arguments( |
| 'global_object', ['index', 'value'], indexed_property_setter) %} |
| {{ call_function("impl", impl_class, indexed_property_setter.name, |
| arguments_list, False) -}}; |
| {% if indexed_property_setter.raises_exception %} |
| if (exception_state.is_exception_set()) { |
| JSC::throwError(exec_state, exception_state.exception_object()); |
| } |
| {% endif %} |
| {% endcall %} |
| } |
| {% endif %} |
| {% if named_property_getter %} |
| |
| JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name) { |
| TRACE_EVENT0("{{binding_class}}", "NamedPropertyGetter"); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, slot_base); |
| if (!impl) { |
| return exec_state->exception(); |
| } |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSCExceptionState exception_state(global_object); |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| {% call(arguments_list) add_extra_arguments('global_object', ['property_name_utf8'], named_property_getter) %} |
| JSC::JSValue result = ToJSValue( |
| global_object, |
| {{ call_function("impl", impl_class, named_property_getter.name, arguments_list, False) -}}); |
| {% if named_property_getter.raises_exception %} |
| if (exception_state.is_exception_set()) { |
| return JSC::throwError(exec_state, exception_state.exception_object()); |
| } |
| {% endif %} |
| return result; |
| {% endcall %} |
| } |
| |
| bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name) { |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (!impl) { |
| return false; |
| } |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| return impl->CanQueryNamedProperty(property_name_utf8); |
| } |
| {% else %} |
| JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name) { |
| NOTREACHED(); |
| return JSC::jsUndefined(); |
| } |
| bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name) { |
| NOTREACHED(); |
| return false; |
| } |
| {% endif %} |
| {% if named_property_setter %} |
| |
| void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue jsc_value) { |
| TRACE_EVENT0("{{binding_class}}", "NamedPropertySetter"); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (!impl) { |
| return; |
| } |
| |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSCExceptionState exception_state(global_object); |
| |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| {{named_property_setter.type}} value; |
| FromJSValue(exec_state, jsc_value, |
| {{named_property_setter.conversion_flags}}, |
| &exception_state, &value); |
| if (exception_state.is_exception_set()) { |
| JSC::throwError(exec_state, exception_state.exception_object()); |
| return; |
| } |
| {% call(arguments_list) add_extra_arguments( |
| 'global_object', ['property_name_utf8', 'value'], named_property_setter) %} |
| {{ call_function( |
| "impl", impl_class, named_property_setter.name, arguments_list, False) -}}; |
| {% if named_property_setter.raises_exception %} |
| if (exception_state.is_exception_set()) { |
| JSC::throwError(exec_state, exception_state.exception_object()); |
| } |
| {% endif %} |
| {% endcall %} |
| } |
| {% else %} |
| void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue jsc_value) { |
| NOTREACHED(); |
| } |
| {% endif %} |
| |
| bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name) { |
| {% if named_property_deleter %} |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, cell); |
| if (impl) { |
| std::string property_name_utf8 = FromWTFString(property_name.publicName()); |
| impl->{{named_property_deleter.name}}(property_name_utf8); |
| return true; |
| } |
| {% endif %} |
| return false; |
| } |
| {% if stringifier %} |
| |
| JSC::EncodedJSValue StringifierJS(JSC::ExecState* exec_state) { |
| JSC::JSObject* this_object = |
| exec_state->hostThisValue().toThisObject(exec_state); |
| {{impl_class}}* impl = |
| GetWrappableOrSetException<{{impl_class}}>(exec_state, this_object); |
| if (!impl) { |
| return JSC::JSValue::encode(exec_state->exception()); |
| } |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| |
| JSC::JSValue result = ToJSValue(global_object, impl->{{stringifier.name}}()); |
| return JSC::JSValue::encode(result); |
| } |
| {% endif %} |
| |
| #if !defined(COBALT_BUILD_TYPE_GOLD) |
| JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name) { |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSC::JSValue callable = global_object->get( |
| exec_state, JSC::Identifier(exec_state, "__onGetMissingProperty")); |
| if (!callable.isUndefined()) { |
| JSC::CallData call_data; |
| JSC::CallType call_type = JSC::getCallData(callable, call_data); |
| if (call_type != JSC::CallTypeNone) { |
| // The function called __onGetMissingProperty exists, so call this and |
| // return the result as the value for this property. |
| JSC::MarkedArgumentBuffer args; |
| args.append(slot_base); |
| args.append(JSC::JSValue( |
| JSC::JSString::create( |
| global_object->globalData(), property_name.publicName()))); |
| JSC::JSValue retval = JSC::call( |
| exec_state, callable, call_type, call_data, global_object, args); |
| return retval; |
| } |
| } |
| return JSC::jsUndefined(); |
| } |
| |
| bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue value) { |
| JSCGlobalObject* global_object = |
| JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject()); |
| JSC::JSValue callable = global_object->get( |
| exec_state, JSC::Identifier(exec_state, "__onSetMissingProperty")); |
| if (!callable.isUndefined()) { |
| JSC::CallData call_data; |
| JSC::CallType call_type = JSC::getCallData(callable, call_data); |
| if (call_type != JSC::CallTypeNone) { |
| // The function called __onSetMissingProperty exists, so call this with |
| // the value to be set. The missing property handler returns true if it |
| // has handled the setting of this property. |
| JSC::MarkedArgumentBuffer args; |
| args.append(cell); |
| args.append(JSC::JSValue( |
| JSC::JSString::create( |
| global_object->globalData(), property_name.publicName()))); |
| args.append(value); |
| JSC::JSValue retval = JSC::call( |
| exec_state, callable, call_type, call_data, global_object, args); |
| return retval.toBoolean(exec_state); |
| } |
| } |
| return false; |
| } |
| #else |
| JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, JSC::PropertyName property_name) { |
| NOTREACHED(); |
| return JSC::jsUndefined(); |
| } |
| bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state, |
| JSC::PropertyName property_name, JSC::JSValue value) { |
| NOTREACHED(); |
| return false; |
| } |
| #endif |
| } // namespace |
| {% endblock implementation %} |
| |
| {% block create_global_object_impl %} |
| JSCGlobalObjectProxy* jsc_global_object_proxy = |
| base::polymorphic_downcast<JSCGlobalObjectProxy*>(this); |
| JSCEngine* jsc_engine = jsc_global_object_proxy->engine(); |
| |
| JSCGlobalObject* global_object = {{binding_class}}::Create( |
| global_interface, environment_settings, |
| jsc_engine->global_data(), jsc_engine->script_object_registry()); |
| jsc_global_object_proxy->SetGlobalObject(global_object); |
| {% endblock create_global_object_impl %} |
| |
| {% block enumeration_definitions %} |
| {% for enumeration in enumerations %} |
| JSC::JSValue ToJSValue(JSCGlobalObject* global_object, {{impl_class}}::{{enumeration.name}} in_enum) { |
| JSC::JSGlobalData* global_data = &(global_object->globalData()); |
| switch (in_enum) { |
| {% for value, idl_value in enumeration.value_pairs %} |
| case {{impl_class}}::{{value}}: return JSC::jsString(global_data, "{{idl_value}}"); |
| {% endfor %} |
| default: |
| NOTREACHED(); |
| return JSC::jsUndefined(); |
| } |
| } |
| void FromJSValue(JSC::ExecState* exec_state, JSC::JSValue jsvalue, |
| int conversion_flags, JSCExceptionState* exception_state, |
| {{impl_class}}::{{enumeration.name}}* out_enum) { |
| DCHECK_EQ(0, conversion_flags) << "Unexpected conversion flags."; |
| // JSValue -> IDL enum algorithm described here: |
| // http://heycam.github.io/webidl/#es-enumeration |
| |
| // 1. Let S be the result of calling ToString(V). |
| JSC::JSString* js_string = jsvalue.toString(exec_state); |
| if (exec_state->hadException()) { |
| DLOG(WARNING) << "Exception converting value to string"; |
| return; |
| } |
| const WTF::String& wtf_string = js_string->tryGetValue(); |
| // 3. Return the enumeration value of type E that is equal to S. |
| {% for value, idl_value in enumeration.value_pairs %} |
| {{-" else " if not loop.first}}if (wtf_string == "{{idl_value}}") { |
| *out_enum = {{impl_class}}::{{value}}; |
| }{% endfor %} else { |
| // 2. If S is not one of E's enumeration values, then throw a TypeError. |
| JSC::throwTypeError(exec_state); |
| } |
| } |
| {% endfor %} |
| {% endblock enumeration_definitions %} |