blob: 1a01c3d663805f879837c72377790afb853574ee [file]
//-------------------------------------------------------------------------------------------------------
// 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 RootObjectInlineCache
{
public:
RootObjectInlineCache(InlineCacheAllocator * allocator);
uint AddRef() { return ++refCount; }
uint Release() { Assert(refCount != 0); return --refCount; }
Js::InlineCache * GetInlineCache() const { return inlineCache; }
uint GetRefCount() { return refCount; }
private:
Field(uint) refCount;
Field(Js::InlineCache *) inlineCache;
};
class RootObjectBase: public DynamicObject
{
public:
HostObjectBase * GetHostObject() const;
void SetHostObject(HostObjectBase * hostObject);
Js::InlineCache * GetInlineCache(Js::PropertyRecord const* propertyRecord, bool isLoadMethod, bool isStore);
Js::RootObjectInlineCache * GetRootInlineCache(Js::PropertyRecord const* propertyRecord, bool isLoadMethod, bool isStore);
void ReleaseInlineCache(PropertyId propertyId, bool isLoadMethod, bool isStore, bool isShutdown);
virtual BOOL EnsureProperty(PropertyId propertyId) override;
virtual BOOL EnsureNoRedeclProperty(PropertyId propertyId) override sealed;
virtual BOOL HasOwnPropertyCheckNoRedecl(PropertyId propertyId) override sealed;
// These are special "Root" versions of the property APIs that allow access
// to global let and const variables, which are stored as properties on the
// root object, but are hidden from normal property API access.
virtual BOOL HasRootProperty(PropertyId propertyId);
virtual BOOL GetRootProperty(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext);
virtual BOOL GetRootPropertyReference(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext);
virtual BOOL SetRootProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info);
virtual DescriptorFlags GetRootSetter(PropertyId propertyId, Var *setterValue, PropertyValueInfo* info, ScriptContext* requestContext);
virtual BOOL DeleteRootProperty(PropertyId propertyId, PropertyOperationFlags flags);
PropertyIndex GetRootPropertyIndex(PropertyId propertyId);
void EnsureNoProperty(PropertyId propertyId);
template <typename Fn>
void MapLetConstGlobals(Fn fn);
#if DBG
bool IsLetConstGlobal(PropertyId propertyId);
#endif
static bool Is(Var var);
static bool Is(RecyclableObject * obj);
static RootObjectBase * FromVar(Var var);
protected:
DEFINE_VTABLE_CTOR(RootObjectBase, DynamicObject);
// We shouldn't create an instance of this object, only derive from it, hide the constructor
RootObjectBase(DynamicType * type);
RootObjectBase(DynamicType * type, ScriptContext* scriptContext);
Field(HostObjectBase *) hostObject;
typedef JsUtil::BaseDictionary<PropertyRecord const *, RootObjectInlineCache *, Recycler> RootObjectInlineCacheMap;
Field(RootObjectInlineCacheMap *) loadInlineCacheMap;
Field(RootObjectInlineCacheMap *) loadMethodInlineCacheMap;
Field(RootObjectInlineCacheMap *) storeInlineCacheMap;
};
template <typename Fn>
void
RootObjectBase::MapLetConstGlobals(Fn fn)
{
int index = 0;
const PropertyRecord* propertyRecord;
Var value;
bool isConst;
while (GetTypeHandler()->NextLetConstGlobal(index, this, &propertyRecord, &value, &isConst))
{
fn(propertyRecord, value, isConst);
}
}
};