text: //-------------------------------------------------------------------------------------------------------
  // 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 NullTypeHandlerBase : public DynamicTypeHandler
      {
      protected:
          NullTypeHandlerBase(bool isPrototype) :
              DynamicTypeHandler(0, 0, 0, DefaultFlags | IsLockedFlag | MayBecomeSharedFlag | IsSharedFlag | (isPrototype ? IsPrototypeFlag : 0)),
              isPrototype(isPrototype) {}
  
          NullTypeHandlerBase(NullTypeHandlerBase* typeHandler, bool isPrototype) :
              DynamicTypeHandler(typeHandler), isPrototype(typeHandler->isPrototype)
          {}
  
          DEFINE_VTABLE_CTOR_NO_REGISTER(NullTypeHandlerBase, DynamicTypeHandler);
  
          FieldNoBarrier(bool) isPrototype;
  
      public:
          DEFINE_GETCPPNAME();
  
      public:
          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 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 BOOL DeleteProperty(DynamicObject* instance, PropertyId propertyId, PropertyOperationFlags flags) 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 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;
          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 void SetAllPropertiesToUndefined(DynamicObject* instance, bool invalidateFixedFields) override {};
          virtual void MarshalAllPropertiesToScriptContext(DynamicObject* instance, ScriptContext* targetScriptContext, bool invalidateFixedFields) override {};
          virtual DynamicTypeHandler* ConvertToTypeWithItemAttributes(DynamicObject* instance) override;
  
          virtual void SetIsPrototype(DynamicObject* instance) override;
  
  #if DBG
          virtual bool SupportsPrototypeInstances() const override { return this->isPrototype; }
          virtual bool RespectsIsolatePrototypes() const { return false; }
          virtual bool RespectsChangeTypeOnProto() const { return false; }
  #endif
  
      private:
          template <typename T>
          T* ConvertToTypeHandler(DynamicObject* instance);
  
          SimpleTypeHandler<1>* ConvertToSimpleType(DynamicObject* instance);
          SimpleDictionaryTypeHandler * ConvertToSimpleDictionaryType(DynamicObject* instance);
          DictionaryTypeHandler * ConvertToDictionaryType(DynamicObject* instance);
          ES5ArrayTypeHandler * ConvertToES5ArrayType(DynamicObject* instance);
  
          BOOL AddProperty(DynamicObject* instance, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags, SideEffects possibleSideEffects);
          virtual BOOL FreezeImpl(DynamicObject* instance, bool isConvertedType) override;
      };
  
      template <bool IsPrototypeTemplate>
      class NullTypeHandler : public NullTypeHandlerBase
      {
      public:
          DEFINE_GETCPPNAME();
  
      private:
          NullTypeHandler() : NullTypeHandlerBase(IsPrototypeTemplate) {}
          NullTypeHandler(NullTypeHandler * typeHandler) : NullTypeHandlerBase(typeHandler) {}
  
          DEFINE_VTABLE_CTOR_NO_REGISTER(NullTypeHandler, NullTypeHandlerBase);
  
          static NullTypeHandler defaultInstance;
  
      public:
          static NullTypeHandler * GetDefaultInstance();
          virtual DynamicTypeHandler * Clone(Recycler * recycler);
  
  #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
  #if DBG_DUMP
      public:
          void Dump(unsigned indent = 0) const override;
  #endif
      };
  }
  