blob: c598c0ed19fb7a3d07e1dcaddd8e19bfb122a92a [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once
namespace Js
{
class DeferredTypeHandlerBase : public DynamicTypeHandler
{
public:
DEFINE_GETCPPNAME();
protected:
DeferredTypeHandlerBase(bool isPrototype, uint16 inlineSlotCapacity, uint16 offsetOfInlineSlots) :
DynamicTypeHandler(0, inlineSlotCapacity, offsetOfInlineSlots, DefaultFlags | IsLockedFlag | MayBecomeSharedFlag | IsSharedFlag | (isPrototype ? IsPrototypeFlag : 0))
{
SetIsInlineSlotCapacityLocked();
this->ClearHasOnlyWritableDataProperties(); // Until the type handler is initialized, we cannot
// be certain that the type has only writable data properties.
}
DeferredTypeHandlerBase(DeferredTypeHandlerBase * typeHandler) : DynamicTypeHandler(typeHandler)
{
Assert(this->GetIsInlineSlotCapacityLocked() == typeHandler->GetIsInlineSlotCapacityLocked());
Assert(this->GetHasOnlyWritableDataProperties() == typeHandler->GetHasOnlyWritableDataProperties());
}
public:
void ConvertFunction(JavascriptFunction * instance, DynamicTypeHandler * handler);
void Convert(DynamicObject * instance, DeferredInitializeMode mode, int initSlotCapacity, BOOL hasAccessor = false);
virtual void SetAllPropertiesToUndefined(DynamicObject* instance, bool invalidateFixedFields) override {};
virtual void MarshalAllPropertiesToScriptContext(DynamicObject* instance, ScriptContext* targetScriptContext, bool invalidateFixedFields) override {};
virtual BOOL IsDeferredTypeHandler() const override { return TRUE; }
virtual void SetIsPrototype(DynamicObject* instance) override { Assert(false); }
#if DBG
virtual bool SupportsPrototypeInstances() const { Assert(false); return false; }
virtual bool RespectsIsolatePrototypes() const { return false; }
virtual bool RespectsChangeTypeOnProto() const { return false; }
#endif
private:
template <typename T>
T* ConvertToTypeHandler(DynamicObject* instance, int initSlotCapacity, BOOL isProto = FALSE);
DictionaryTypeHandler * ConvertToDictionaryType(DynamicObject* instance, int initSlotCapacity, BOOL isProto);
SimpleDictionaryTypeHandler * ConvertToSimpleDictionaryType(DynamicObject* instance, int initSlotCapacity, BOOL isProto);
ES5ArrayTypeHandler * ConvertToES5ArrayType(DynamicObject* instance, int initSlotCapacity);
#if ENABLE_TTD
public:
virtual void MarkObjectSlots_TTD(TTD::SnapshotExtractor* extractor, DynamicObject* obj) const override
{
;
}
virtual uint32 ExtractSlotInfo_TTD(TTD::NSSnapType::SnapHandlerPropertyEntry* entryInfo, ThreadContext* threadContext, TTD::SlabAllocator& alloc) const override
{
return 0;
}
#endif
};
class DefaultDeferredTypeFilter
{
public:
static bool HasFilter() { return false; }
static bool HasProperty(PropertyId propertyId) { Assert(false); return false; }
};
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter = DefaultDeferredTypeFilter, bool isPrototypeTemplate = false, uint16 _inlineSlotCapacity = 0, uint16 _offsetOfInlineSlots = 0>
class DeferredTypeHandler : public DeferredTypeHandlerBase
{
friend class DynamicTypeHandler;
public:
DEFINE_GETCPPNAME();
private:
DeferredTypeHandler() : DeferredTypeHandlerBase(isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots), m_initializer(initializer) { }
DeferredTypeHandler(DeferredTypeHandler * typeHandler) :
DeferredTypeHandlerBase(typeHandler),
m_initializer(typeHandler->m_initializer)
{}
public:
static DeferredTypeHandler *GetDefaultInstance() { return &defaultInstance; }
virtual DynamicTypeHandler * Clone(Recycler* recycler);
virtual BOOL IsLockable() const override { return true; }
virtual BOOL IsSharable() const override { return true; }
virtual int GetPropertyCount() override;
virtual PropertyId GetPropertyId(ScriptContext* scriptContext, PropertyIndex index) override;
virtual PropertyId GetPropertyId(ScriptContext* scriptContext, BigPropertyIndex index) override;
virtual BOOL FindNextProperty(ScriptContext* scriptContext, PropertyIndex& index, JavascriptString** propertyString,
PropertyId* propertyId, PropertyAttributes* attributes, Type* type, DynamicType *typeToEnumerate, EnumeratorFlags flags, DynamicObject* instance, PropertyValueInfo* info) override;
virtual PropertyIndex GetPropertyIndex(PropertyRecord const* propertyRecord) override;
#if ENABLE_NATIVE_CODEGEN
virtual bool GetPropertyEquivalenceInfo(PropertyRecord const* propertyRecord, PropertyEquivalenceInfo& info) override;
virtual bool IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex) override;
virtual bool IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry) override;
#endif
virtual bool EnsureObjectReady(DynamicObject* instance) override;
virtual BOOL HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl = nullptr, _Inout_opt_ PropertyValueInfo* info = nullptr) override;
virtual BOOL HasProperty(DynamicObject* instance, JavascriptString* propertyNameString) override;
virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
virtual BOOL GetProperty(DynamicObject* instance, Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
virtual BOOL SetProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
virtual BOOL SetProperty(DynamicObject* instance, JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
virtual BOOL SetInternalProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags) override;
virtual DescriptorFlags GetSetter(DynamicObject* instance, PropertyId propertyId, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
virtual DescriptorFlags GetSetter(DynamicObject* instance, JavascriptString* propertyNameString, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
virtual BOOL DeleteProperty(DynamicObject* instance, PropertyId propertyId, PropertyOperationFlags flags) override;
virtual BOOL HasItem(DynamicObject* instance, uint32 index);
virtual BOOL SetItem(DynamicObject* instance, uint32 index, Var value, PropertyOperationFlags flags) override;
virtual BOOL SetItemWithAttributes(DynamicObject* instance, uint32 index, Var value, PropertyAttributes attributes) override;
virtual BOOL SetItemAttributes(DynamicObject* instance, uint32 index, PropertyAttributes attributes) override;
virtual BOOL SetItemAccessors(DynamicObject* instance, uint32 index, Var getter, Var setter) override;
virtual BOOL DeleteItem(DynamicObject* instance, uint32 index, PropertyOperationFlags flags) override;
virtual BOOL GetItem(DynamicObject* instance, Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
virtual DescriptorFlags GetItemSetter(DynamicObject* instance, uint32 index, Var* setterValue, ScriptContext* requestContext) override;
virtual BOOL IsEnumerable(DynamicObject* instance, PropertyId propertyId) override;
virtual BOOL IsWritable(DynamicObject* instance, PropertyId propertyId) override;
virtual BOOL IsConfigurable(DynamicObject* instance, PropertyId propertyId) override;
virtual BOOL IsFrozen(DynamicObject *instance) override;
virtual BOOL IsSealed(DynamicObject *instance) override;
virtual BOOL SetEnumerable(DynamicObject* instance, PropertyId propertyId, BOOL value) override;
virtual BOOL SetWritable(DynamicObject* instance, PropertyId propertyId, BOOL value) override;
virtual BOOL SetConfigurable(DynamicObject* instance, PropertyId propertyId, BOOL value) override;
virtual BOOL SetAccessors(DynamicObject* instance, PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags = PropertyOperation_None) override;
_Check_return_ _Success_(return) virtual BOOL GetAccessors(DynamicObject* instance, PropertyId propertyId, _Outptr_result_maybenull_ Var* getter, _Outptr_result_maybenull_ Var* setter) override;
virtual BOOL PreventExtensions(DynamicObject *instance) override;
virtual BOOL Seal(DynamicObject *instance) override;
virtual BOOL SetPropertyWithAttributes(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags = PropertyOperation_None, SideEffects possibleSideEffects = SideEffects_Any) override;
virtual BOOL SetAttributes(DynamicObject* instance, PropertyId propertyId, PropertyAttributes attributes) override;
virtual BOOL GetAttributesWithPropertyIndex(DynamicObject * instance, PropertyId propertyId, BigPropertyIndex index, PropertyAttributes * attributes) override;
virtual DynamicTypeHandler* ConvertToTypeWithItemAttributes(DynamicObject* instance) override;
virtual void SetIsPrototype(DynamicObject* instance) override;
#if DBG
virtual bool SupportsPrototypeInstances() const { return isPrototypeTemplate; }
#endif
private:
static DeferredTypeHandler defaultInstance;
Field(DeferredTypeInitializer) m_initializer;
bool EnsureObjectReady(DynamicObject* instance, DeferredInitializeMode mode);
virtual BOOL FreezeImpl(DynamicObject *instance, bool isConvertedType) override;
#if DBG_DUMP
public:
void Dump(unsigned indent = 0) const override
{
Output::Print(_u("%*sDeferredTypeHandler (0x%p): Dump unimplemented\n"), indent, _u(""), this);
}
#endif
};
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots> DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::defaultInstance;
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DynamicTypeHandler * DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::Clone(Recycler * recycler)
{
return RecyclerNew(recycler, DeferredTypeHandler, this);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
int DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetPropertyCount()
{
return 0;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
PropertyId DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetPropertyId(ScriptContext* scriptContext, PropertyIndex index)
{
Assert(false);
return Constants::NoProperty;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
PropertyId DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetPropertyId(ScriptContext* scriptContext, BigPropertyIndex index)
{
Assert(false);
return Constants::NoProperty;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::FindNextProperty(ScriptContext* scriptContext, PropertyIndex& index,
__out JavascriptString** propertyString, __out PropertyId* propertyId, __out_opt PropertyAttributes* attributes, Type* type, DynamicType *typeToEnumerate, EnumeratorFlags flags, DynamicObject* instance, PropertyValueInfo* info)
{
Assert(false);
return FALSE;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
PropertyIndex DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetPropertyIndex(PropertyRecord const* propertyRecord)
{
return Constants::NoSlot;
}
#if ENABLE_NATIVE_CODEGEN
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
bool DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetPropertyEquivalenceInfo(PropertyRecord const* propertyRecord, PropertyEquivalenceInfo& info)
{
info.slotIndex = Constants::NoSlot;
info.isAuxSlot = false;
info.isWritable = false;
return false;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
bool DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsObjTypeSpecEquivalent(const Type* type, const TypeEquivalenceRecord& record, uint& failedPropertyIndex)
{
uint propertyCount = record.propertyCount;
EquivalentPropertyEntry* properties = record.properties;
for (uint pi = 0; pi < propertyCount; pi++)
{
const EquivalentPropertyEntry* refInfo = &properties[pi];
if (!this->DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsObjTypeSpecEquivalent(type, refInfo))
{
failedPropertyIndex = pi;
return false;
}
}
return true;
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
bool DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsObjTypeSpecEquivalent(const Type* type, const EquivalentPropertyEntry* entry)
{
if (!DeferredTypeFilter::HasFilter())
{
return false;
}
if (entry->slotIndex != Constants::NoSlot || entry->mustBeWritable || DeferredTypeFilter::HasProperty(entry->propertyId))
{
return false;
}
return true;
}
#endif
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
bool DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::EnsureObjectReady(DynamicObject* instance)
{
return EnsureObjectReady(instance, DeferredInitializeMode_Default);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
bool DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::EnsureObjectReady(DynamicObject* instance, DeferredInitializeMode mode)
{
Assert(initializer == m_initializer);
return m_initializer(instance, this, mode);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::HasProperty(DynamicObject* instance, PropertyId propertyId, __out_opt bool *noRedecl, _Inout_opt_ PropertyValueInfo* info)
{
if (noRedecl != nullptr)
{
*noRedecl = false;
}
if (DeferredTypeFilter::HasFilter() && DeferredTypeFilter::HasProperty(propertyId))
{
return TRUE;
}
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->HasProperty(instance, propertyId, noRedecl, info);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::HasProperty(DynamicObject* instance, JavascriptString* propertyNameString)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->HasProperty(instance, propertyNameString);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetProperty(DynamicObject* instance, Var originalInstance,
PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
{
if (DeferredTypeFilter::HasFilter() && !DeferredTypeFilter::HasProperty(propertyId))
{
*value = requestContext->GetMissingPropertyResult();
return FALSE;
}
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
*value = requestContext->GetMissingPropertyResult();
// Return true so that we stop walking the prototype
return TRUE;
}
return GetCurrentTypeHandler(instance)->GetProperty(instance, originalInstance, propertyId, value, info, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetProperty(DynamicObject* instance, Var originalInstance,
JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
*value = requestContext->GetMissingPropertyResult();
// Return true so that we stop walking the prototype
return TRUE;
}
return GetCurrentTypeHandler(instance)->GetProperty(instance, originalInstance, propertyNameString, value, info, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetProperty(instance, propertyId, value, flags, info);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetProperty(DynamicObject* instance, JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetProperty(instance, propertyNameString, value, flags, info);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetInternalProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyOperationFlags flags)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetInternalProperty(instance, propertyId, value, flags);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DescriptorFlags DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetSetter(DynamicObject* instance, PropertyId propertyId, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext)
{
if (setterValue != nullptr)
{
*setterValue = nullptr;
}
if (DeferredTypeFilter::HasFilter() && !DeferredTypeFilter::HasProperty(propertyId))
{
return DescriptorFlags::None;
}
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return DescriptorFlags::None;
}
return GetCurrentTypeHandler(instance)->GetSetter(instance, propertyId, setterValue, info, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DescriptorFlags DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetSetter(DynamicObject* instance, JavascriptString* propertyNameString, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext)
{
if (setterValue != nullptr)
{
*setterValue = nullptr;
}
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return DescriptorFlags::None;
}
return GetCurrentTypeHandler(instance)->GetSetter(instance, propertyNameString, setterValue, info, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::DeleteProperty(DynamicObject* instance, PropertyId propertyId, PropertyOperationFlags flags)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->DeleteProperty(instance, propertyId, flags);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::HasItem(DynamicObject* instance, uint32 index)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->HasItem(instance, index);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetItem(DynamicObject* instance, uint32 index, Var value, PropertyOperationFlags flags)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetItem(instance, index, value, flags);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetItemWithAttributes(DynamicObject* instance, uint32 index, Var value, PropertyAttributes attributes)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetItemWithAttributes(instance, index, value, attributes);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetItemAttributes(DynamicObject* instance, uint32 index, PropertyAttributes attributes)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetItemAttributes(instance, index, attributes);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetItemAccessors(DynamicObject* instance, uint32 index, Var getter, Var setter)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetItemAccessors(instance, index, getter, setter);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::DeleteItem(DynamicObject* instance, uint32 index, PropertyOperationFlags flags)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->DeleteItem(instance, index, flags);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetItem(DynamicObject* instance, Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
*value = requestContext->GetMissingItemResult();
return TRUE;
}
return GetCurrentTypeHandler(instance)->GetItem(instance, originalInstance, index, value, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DescriptorFlags DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetItemSetter(DynamicObject* instance, uint32 index, Var* setterValue, ScriptContext* requestContext)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return DescriptorFlags::None;
}
return GetCurrentTypeHandler(instance)->GetItemSetter(instance, index, setterValue, requestContext);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsEnumerable(DynamicObject* instance, PropertyId propertyId)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->IsEnumerable(instance, propertyId);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsWritable(DynamicObject* instance, PropertyId propertyId)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->IsWritable(instance, propertyId);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsConfigurable(DynamicObject* instance, PropertyId propertyId)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->IsConfigurable(instance, propertyId);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetEnumerable(DynamicObject* instance, PropertyId propertyId, BOOL value)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetEnumerable(instance, propertyId, value);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetWritable(DynamicObject* instance, PropertyId propertyId, BOOL value)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetWritable(instance, propertyId, value);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetConfigurable(DynamicObject* instance, PropertyId propertyId, BOOL value)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetConfigurable(instance, propertyId, value);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetAccessors(DynamicObject* instance, PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_SetAccessors))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetAccessors(instance, propertyId, getter, setter, flags);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
_Check_return_ _Success_(return) BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetAccessors(DynamicObject* instance, PropertyId propertyId, _Outptr_result_maybenull_ Var* getter, _Outptr_result_maybenull_ Var* setter)
{
if (getter != nullptr)
{
*getter = nullptr;
}
if (setter != nullptr)
{
*setter = nullptr;
}
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->GetAccessors(instance, propertyId, getter, setter);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsSealed(DynamicObject *instance)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->IsSealed(instance);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::IsFrozen(DynamicObject *instance)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->IsFrozen(instance);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::PreventExtensions(DynamicObject* instance)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Extensions))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->PreventExtensions(instance);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::Seal(DynamicObject* instance)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Extensions))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->Seal(instance);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::FreezeImpl(DynamicObject* instance, bool isConvertedType)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Extensions))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->Freeze(instance, true);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetPropertyWithAttributes(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetPropertyWithAttributes(instance, propertyId, value, attributes, info, flags, possibleSideEffects);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetAttributes(DynamicObject* instance, PropertyId propertyId, PropertyAttributes attributes)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
return TRUE;
}
return GetCurrentTypeHandler(instance)->SetAttributes(instance, propertyId, attributes);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
BOOL DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::GetAttributesWithPropertyIndex(DynamicObject * instance, PropertyId propertyId, BigPropertyIndex index, PropertyAttributes * attributes)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Default))
{
if (attributes)
{
*attributes = PropertyDynamicTypeDefaults;
}
return TRUE;
}
return GetCurrentTypeHandler(instance)->GetAttributesWithPropertyIndex(instance, propertyId, index, attributes);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
DynamicTypeHandler* DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::ConvertToTypeWithItemAttributes(DynamicObject* instance)
{
if (!EnsureObjectReady(instance, DeferredInitializeMode_Set))
{
AssertOrFailFastMsg(false, "Is this a valid scenario?");
return nullptr;
}
return GetCurrentTypeHandler(instance)->ConvertToTypeWithItemAttributes(instance);
}
template <DeferredTypeInitializer initializer, typename DeferredTypeFilter, bool isPrototypeTemplate, uint16 _inlineSlotCapacity, uint16 _offsetOfInlineSlots>
void DeferredTypeHandler<initializer, DeferredTypeFilter, isPrototypeTemplate, _inlineSlotCapacity, _offsetOfInlineSlots>::SetIsPrototype(DynamicObject* instance)
{
if (!isPrototypeTemplate)
{
// We don't force a type transition even when ChangeTypeOnProto() == true, because objects with NullTypeHandlers don't
// have any properties, so there is nothing to invalidate. Types with NullTypeHandlers also aren't cached in typeWithoutProperty
// caches, so there will be no fast property add path that could skip prototype cache invalidation.
DeferredTypeHandlerBase* protoTypeHandler = DeferredTypeHandler<initializer, DeferredTypeFilter, true, _inlineSlotCapacity, _offsetOfInlineSlots>::GetDefaultInstance();
AssertMsg(protoTypeHandler->GetFlags() == (GetFlags() | IsPrototypeFlag), "Why did we change the flags of a DeferredTypeHandler?");
Assert(this->GetIsInlineSlotCapacityLocked() == protoTypeHandler->GetIsInlineSlotCapacityLocked());
protoTypeHandler->SetPropertyTypes(PropertyTypesWritableDataOnly | PropertyTypesWritableDataOnlyDetection | PropertyTypesHasSpecialProperties, GetPropertyTypes());
SetInstanceTypeHandler(instance, protoTypeHandler);
}
}
}