blob: 603493f6694883d588a655a3c4455e6420a3c770 [file] [log] [blame]
{#
# 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