| {# |
| # Copyright 2016 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. |
| #} |
| // Class that defines a JS Object representing this interface's prototype |
| class {{binding_class}}::Prototype : public PrototypeBase { |
| public: |
| // Get the prototype. Will create a new prototype if necessary, otherwise it |
| // will return a cached prototype. |
| static JSC::JSObject* GetInstance(JSC::JSGlobalObject* global_object); |
| DECLARE_CLASSINFO(); |
| |
| // Needed when JSC::OverridesGetOwnPropertySlot StructureFlag is set |
| // Must be public so that it can be accessible from getStaticValueSlot<>. |
| static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*, |
| JSC::PropertyName, |
| JSC::PropertySlot&); |
| |
| private: |
| typedef PrototypeBase BaseClass; |
| |
| static const unsigned StructureFlags = |
| JSC::OverridesGetOwnPropertySlot | |
| BaseClass::StructureFlags; |
| |
| Prototype(JSC::JSGlobalObject* global_object, JSC::Structure* structure) |
| : BaseClass(global_object, structure) { } |
| |
| {% if has_interface_object %} |
| static JSC::JSValue GetConstructor(JSC::ExecState* exec_state, |
| JSC::JSValue slot_base, |
| JSC::PropertyName property_name); |
| {% endif %} |
| static const JSC::HashTable* GetPropertyTable(JSC::ExecState* exec_state); |
| |
| static const JSC::HashTableValue property_table_values[]; |
| static const JSC::HashTable property_table_prototype; |
| }; |
| |
| const JSC::HashTableValue {{binding_class}}::Prototype::property_table_values[] = { |
| {% for operation in operations if not is_global_interface %} |
| {% 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 %} |
| {% if stringifier %} |
| { "toString", |
| JSC::DontDelete | JSC::Function, |
| reinterpret_cast<intptr_t>(StringifierJS), |
| static_cast<intptr_t>(0), |
| JSC::NoIntrinsic |
| }, |
| {% endif %} |
| {% for constant in constants %} |
| { "{{constant.idl_name}}", |
| JSC::DontDelete | JSC::ReadOnly, |
| reinterpret_cast<intptr_t>(getJS{{constant.idl_name}}), |
| 0, |
| JSC::NoIntrinsic |
| }, |
| {% endfor %} |
| {% if has_interface_object %} |
| { "constructor", |
| JSC::DontDelete | JSC::DontEnum, |
| reinterpret_cast<intptr_t>({{binding_class}}::Prototype::GetConstructor), |
| static_cast<intptr_t>(0), |
| JSC::NoIntrinsic |
| }, |
| {% endif %} |
| { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) } |
| }; // {{binding_class}}::Prototype::property_table_values |
| |
| // static |
| const JSC::HashTable {{binding_class}}::Prototype::property_table_prototype = { |
| {% set num_prototype_properties = constants|length %} |
| {% if not is_global_interface %} |
| {% set num_prototype_properties = num_prototype_properties + operations|length %} |
| {% endif %} |
| {% if has_interface_object %} |
| {% set num_prototype_properties = num_prototype_properties + 1 %} |
| {% endif %} |
| {% if stringifier %} |
| {% set num_prototype_properties = num_prototype_properties + 1 %} |
| {% endif %} |
| {{ calculate_jsc_lookup_size(num_prototype_properties) }}, // compactSize |
| {{ calculate_jsc_lookup_size_mask(num_prototype_properties) }}, // compactSizeMask |
| property_table_values, |
| NULL // table allocated at runtime |
| }; // {{binding_class}}::Prototype::property_table_prototype |
| |
| // static |
| const JSC::HashTable* {{binding_class}}::Prototype::GetPropertyTable( |
| JSC::ExecState* exec_state) { |
| return ThreadLocalHashTable::GetInstance()->GetHashTable( |
| {{binding_class}}::Prototype::s_classinfo(), property_table_prototype); |
| } |
| |
| const JSC::ClassInfo {{binding_class}}::Prototype::s_info = { |
| "{{interface_name}}Prototype", // 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}}::Prototype) |
| }; // {{binding_class}}::Prototype::s_info |
| |
| // Look up property slot for querying property values. |
| bool {{binding_class}}::Prototype::getOwnPropertySlot(JSC::JSCell* cell, |
| JSC::ExecState* exec, JSC::PropertyName property_name, |
| JSC::PropertySlot& slot) { |
| Prototype* this_object = JSC::jsCast<Prototype*>(cell); |
| ASSERT_GC_OBJECT_INHERITS(this_object, &s_info); |
| return JSC::getStaticPropertySlot<Prototype, JSC::JSObject>( |
| exec, GetPropertyTable(exec), this_object, property_name, slot); |
| } |
| |
| // static |
| JSC::JSObject* {{binding_class}}::Prototype::GetInstance( |
| JSC::JSGlobalObject* base_global_object) { |
| JSCGlobalObject* global_object = |
| static_cast<JSCGlobalObject*>(base_global_object); |
| ASSERT_GC_OBJECT_INHERITS(global_object, JSCGlobalObject::s_classinfo()); |
| |
| // Try to get the cached prototype, and create a new one if needed. |
| JSC::JSObject* prototype = global_object->object_cache()->GetCachedPrototype(&s_info); |
| if (prototype == NULL) { |
| JSC::JSGlobalData& global_data = global_object->globalData(); |
| JSC::JSLockHolder lock(&global_data); |
| |
| {% if parent_interface %} |
| JSC::JSObject* parent_prototype = |
| {{parent_interface}}::GetPrototype(global_object); |
| {% elif is_exception_interface %} |
| JSC::JSObject* parent_prototype = global_object->errorPrototype(); |
| {% else %} |
| JSC::JSObject* parent_prototype = global_object->objectPrototype(); |
| {% endif %} |
| JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags); |
| JSC::Structure* structure = JSC::Structure::create( |
| global_data, |
| global_object, |
| JSC::JSValue(parent_prototype), |
| type_info, |
| &s_info); |
| |
| // Create the new prototype object. |
| Prototype* new_prototype = |
| new (NotNull, JSC::allocateCell<Prototype>( |
| global_data.heap)) |
| Prototype(global_object, structure); |
| new_prototype->finishCreation(global_data); |
| // Add the prototype to the cache. |
| global_object->object_cache()->CachePrototype(&s_info, new_prototype); |
| prototype = new_prototype; |
| } |
| DCHECK_EQ(global_object->object_cache()->GetCachedPrototype(&s_info), prototype); |
| return prototype; |
| } |
| |
| // End of {{binding_class}}::Prototype class |