| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- //-------------------------------------------------------------------------------------------------------
- // 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 ArgumentsObject : public DynamicObject
- {
- private:
- static PropertyId specialPropertyIds[];
- protected:
- DEFINE_VTABLE_CTOR_ABSTRACT(ArgumentsObject, DynamicObject);
- public:
- ArgumentsObject(DynamicType * type) : DynamicObject(type)
- {
- Assert(type->GetTypeId() == TypeIds_Arguments);
- }
- static bool Is(Var aValue);
- virtual BOOL GetDiagValueString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
- virtual BOOL GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
- virtual BOOL GetEnumerator(JavascriptStaticEnumerator * enumerator, EnumeratorFlags flags, ScriptContext* requestContext, EnumeratorCache * enumeratorCache = nullptr) override;
- virtual uint32 GetNumberOfArguments() const = 0;
- virtual uint32 GetNextFormalArgIndex(uint32 index, BOOL enumNonEnumerable = FALSE, PropertyAttributes* attributes = nullptr) const = 0;
- virtual Var GetHeapArguments() = 0;
- virtual void SetHeapArguments(HeapArgumentsObject *args) = 0;
- virtual BOOL AdvanceWalkerToArgsFrame(JavascriptStackWalker *walker) = 0;
- };
- class ES5HeapArgumentsObject;
- // The arguments passed to a function are cached as follows:
- // 1) any formal (i.e. named) arguments are copied to the ActivationObject hung off
- // a HeapArgumentObject where they can be referenced by name
- // 2) any additional actual arguments are stored as an index property on that HeapArgumentObject
- //
- // See JavascriptOperators::LoadHeapArguments for details of HeapArgumentObject creation.
- //
- // If a function has named arguments, the array elements of the Arguments object are synonymous for
- // the local variables that hold the function arguments. This no longer holds true, however, if an
- // array element of the Argument object is deleted.
- class HeapArgumentsObject : public ArgumentsObject
- {
- friend class ::ActiveScriptProfilerHeapEnum;
- protected:
- DEFINE_VTABLE_CTOR(HeapArgumentsObject, ArgumentsObject);
- private:
- // We currently support only 2^24 arguments
- Field(uint32) numOfArguments:31;
- Field(uint32) callerDeleted:1;
- DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(HeapArgumentsObject);
- protected:
- Field(uint32) formalCount;
- Field(ActivationObject*) frameObject;
- Field(BVSparse<Recycler>*) deletedArgs;
- public:
- HeapArgumentsObject(DynamicType * type);
- HeapArgumentsObject(Recycler *recycler, ActivationObject* obj, uint32 formalCount, DynamicType * type);
- void SetNumberOfArguments(uint32 len);
- static HeapArgumentsObject* As(Var aValue);
- BOOL HasItemAt(uint32 index);
- virtual BOOL GetItemAt(uint32 index, Var *value, ScriptContext * scriptContext);
- virtual BOOL SetItemAt(uint32 index, Var value);
- virtual BOOL DeleteItemAt(uint32 index);
- virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
- virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
- virtual BOOL SetProperty(JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
- virtual PropertyQueryFlags HasItemQuery(uint32 index) override;
- virtual PropertyQueryFlags GetItemQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
- virtual PropertyQueryFlags GetItemReferenceQuery(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
- virtual BOOL SetItem(uint32 index, Var value, PropertyOperationFlags flags) override;
- virtual BOOL DeleteItem(uint32 index, PropertyOperationFlags flags) override;
- virtual uint32 GetNumberOfArguments() const override;
- virtual uint32 GetNextFormalArgIndex(uint32 index, BOOL enumNonEnumerable = FALSE, PropertyAttributes* attributes = nullptr) const override;
- virtual Var GetHeapArguments() { return this; }
- virtual void SetHeapArguments(HeapArgumentsObject *args)
- {
- AssertMsg(false, "Should never get here");
- }
- virtual BOOL AdvanceWalkerToArgsFrame(JavascriptStackWalker *walker) override;
- virtual BOOL SetConfigurable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetEnumerable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetWritable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetAccessors(PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags = PropertyOperation_None) override;
- virtual BOOL SetPropertyWithAttributes(PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags = PropertyOperation_None, SideEffects possibleSideEffects = SideEffects_Any) override;
- virtual BOOL PreventExtensions() override;
- virtual BOOL Seal() override;
- virtual BOOL Freeze() override;
- uint32 GetFormalCount() const
- {
- return this->formalCount;
- }
- void SetFormalCount(uint32 value)
- {
- this->formalCount = value;
- }
- ES5HeapArgumentsObject* ConvertToUnmappedArgumentsObject(bool overwriteArgsUsingFrameObject = true);
- const ActivationObject* const GetFrameObject() { return frameObject; }
- void SetFrameObject(ActivationObject * value)
- {
- AssertMsg(frameObject == nullptr, "Setting the frame object again?");
- Assert(!value || ActivationObject::Is(value));
- frameObject = value;
- }
- private:
- ES5HeapArgumentsObject* ConvertToES5HeapArgumentsObject(bool overwriteArgsUsingFrameObject = true);
- protected:
- BOOL IsFormalArgument(uint32 index);
- BOOL IsFormalArgument(PropertyId propertyId);
- BOOL IsFormalArgument(PropertyId propertyId, uint32* pIndex); // Checks whether property is numeric, and on success sets that index.
- BOOL IsArgumentDeleted(uint32 index) const;
- #if ENABLE_TTD
- public:
- virtual void MarkVisitKindSpecificPtrs(TTD::SnapshotExtractor* extractor) override;
- virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
- virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
- template <TTD::NSSnapObjects::SnapObjectType argsKind>
- void ExtractSnapObjectDataInto_Helper(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc);
- ES5HeapArgumentsObject* ConvertToES5HeapArgumentsObject_TTD();
- #endif
- };
- // ES5 version of the HeapArgumentsObject: support for attributes on formal arguments.
- // - Unless the user deals with SetWritable/Enumerable/Configurable/Accessors, regular HeapArgumentsObject is used.
- // - When SetWritable/Enumerable/Configurable/Accessors is called, convert HeapArgumentsObject to ES5HeapArgumentsObject by swapping vtable.
- // - Override GetItemAt/SetItemAt -- for disconnected items force GetItem/SetItem to use "this" rather than from frameObject.
- // - Override GetEnumerator -- take care of enumerable = false arguments.
- // - The "disconnect" happens when (as ES5 spec says) setting writable to false and setting accessors.
- // Note: This implementation depends on v-table swapping so that HeapArgumentsObject instance can be
- // converted to ES5HeapArgumentsObject at runtime when ES5 attribute/getter/setter support is needed.
- // Thus, CAUTION: as a result, this class can't add any new instance fields,
- // as the size of the instance must be same.
- class ES5HeapArgumentsObject : public HeapArgumentsObject
- {
- friend struct AutoObjectArrayItemExistsValidator;
- friend class ES5ArgumentsObjectEnumerator;
- // Helper class to make sure that object array item exists for ES5HeapArgumentsObject
- // and remove the item to roll back to original state if something fails/throws.
- struct AutoObjectArrayItemExistsValidator
- {
- ES5HeapArgumentsObject* m_args;
- bool m_isReleaseItemNeeded;
- uint32 m_index;
- AutoObjectArrayItemExistsValidator(ES5HeapArgumentsObject* args, uint32 index);
- ~AutoObjectArrayItemExistsValidator();
- };
- private:
- DEFINE_VTABLE_CTOR(ES5HeapArgumentsObject, HeapArgumentsObject);
- DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(ES5HeapArgumentsObject);
- uint32 GetNextFormalArgIndexHelper(uint32 index, BOOL enumNonEnumerable, PropertyAttributes* attributes = nullptr) const;
- public:
- ES5HeapArgumentsObject(Recycler *recycler, ActivationObject* obj, uint32 formalCount, DynamicType * type)
- : HeapArgumentsObject(recycler, obj, formalCount, type)
- {
- }
- virtual BOOL SetConfigurable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetEnumerable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetWritable(PropertyId propertyId, BOOL value) override;
- virtual BOOL SetAccessors(PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags) override;
- virtual BOOL SetPropertyWithAttributes(PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags = PropertyOperation_None, SideEffects possibleSideEffects = SideEffects_Any) override;
- virtual BOOL GetEnumerator(JavascriptStaticEnumerator * enumerator, EnumeratorFlags flags, ScriptContext* requestContext, EnumeratorCache * enumeratorCache = nullptr) override;
- virtual BOOL PreventExtensions() override;
- virtual BOOL Seal() override;
- virtual BOOL Freeze() override;
- virtual uint32 GetNextFormalArgIndex(uint32 index, BOOL enumNonEnumerable = FALSE, PropertyAttributes* attributes = nullptr) const override;
- virtual BOOL GetItemAt(uint32 index, Var *value, ScriptContext * scriptContext) override;
- virtual BOOL SetItemAt(uint32 index, Var value) override;
- virtual BOOL DeleteItemAt(uint32 index) override;
- void DisconnectFormalFromNamedArgument(uint32 index);
- BOOL IsFormalDisconnectedFromNamedArgument(uint32 index);
- BOOL IsEnumerableByIndex(uint32 index);
- BOOL SetConfigurableForFormal(uint32 index, PropertyId propertyId, BOOL value);
- BOOL SetEnumerableForFormal(uint32 index, PropertyId propertyId, BOOL value);
- BOOL SetWritableForFormal(uint32 index, PropertyId propertyId, BOOL value);
- BOOL SetAccessorsForFormal(uint32 index, PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags = PropertyOperation_None);
- BOOL SetPropertyWithAttributesForFormal(uint32 index, PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags = PropertyOperation_None, SideEffects possibleSideEffects = SideEffects_Any);
- #if ENABLE_TTD
- public:
- virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
- virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
- #endif
- };
- }
|