JavascriptProxy.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. // Implements JavascriptProxy.
  6. //----------------------------------------------------------------------------
  7. #pragma once
  8. namespace Js
  9. {
  10. // Host should keep the same object in cross-site scenario.
  11. class JavascriptProxy : public DynamicObject
  12. {
  13. friend class JavascriptOperators;
  14. protected:
  15. DEFINE_VTABLE_CTOR(JavascriptProxy, DynamicObject);
  16. DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JavascriptProxy);
  17. private:
  18. RecyclableObject* handler;
  19. RecyclableObject* target;
  20. void RevokeObject();
  21. public:
  22. static const uint32 MAX_STACK_CALL_ARGUMENT_COUNT = 20;
  23. class EntryInfo
  24. {
  25. public:
  26. static FunctionInfo NewInstance;
  27. static FunctionInfo Revocable;
  28. static FunctionInfo Revoke;
  29. };
  30. typedef enum SetPropertyTrapKind {
  31. SetItemOnTaggedNumberKind,
  32. SetPropertyOnTaggedNumberKind,
  33. SetPropertyKind,
  34. SetItemKind,
  35. SetPropertyWPCacheKind,
  36. } SetPropertyTrapKind;
  37. typedef enum KeysTrapKind {
  38. GetOwnPropertyNamesKind,
  39. GetOwnPropertySymbolKind,
  40. KeysKind
  41. };
  42. typedef enum IntegrityLevel {
  43. IntegrityLevel_sealed,
  44. IntegrityLevel_frozen
  45. };
  46. JavascriptProxy(DynamicType * type);
  47. JavascriptProxy(DynamicType * type, ScriptContext * scriptContext, RecyclableObject* target, RecyclableObject* handler);
  48. static BOOL Is(Var obj);
  49. static JavascriptProxy* FromVar(Var obj) { Assert(Is(obj)); return static_cast<JavascriptProxy*>(obj); }
  50. RecyclableObject* GetTarget() const { return target; }
  51. RecyclableObject* GetHandler() const { return handler; }
  52. static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...);
  53. static Var EntryRevocable(RecyclableObject* function, CallInfo callInfo, ...);
  54. static Var EntryRevoke(RecyclableObject* function, CallInfo callInfo, ...);
  55. static Var FunctionCallTrap(RecyclableObject* function, CallInfo callInfo, ...);
  56. static JavascriptProxy* Create(ScriptContext* scriptContext, Arguments args);
  57. static BOOL GetOwnPropertyDescriptor(RecyclableObject* obj, PropertyId propertyId, ScriptContext* scriptContext, PropertyDescriptor* propertyDescriptor);
  58. static BOOL DefineOwnPropertyDescriptor(RecyclableObject* obj, PropertyId propId, const PropertyDescriptor& descriptor, bool throwOnError, ScriptContext* scriptContext);
  59. static DWORD GetOffsetOfTarget() { return offsetof(JavascriptProxy, target); }
  60. virtual BOOL HasProperty(PropertyId propertyId) override;
  61. virtual BOOL HasOwnProperty(PropertyId propertyId) override;
  62. virtual BOOL HasOwnPropertyNoHostObject(PropertyId propertyId) override;
  63. virtual BOOL HasOwnPropertyCheckNoRedecl(PropertyId propertyId) override;
  64. virtual BOOL UseDynamicObjectForNoHostObjectAccess() override;
  65. virtual DescriptorFlags GetSetter(PropertyId propertyId, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
  66. virtual DescriptorFlags GetSetter(JavascriptString* propertyNameString, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
  67. virtual BOOL GetProperty(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
  68. virtual BOOL GetProperty(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
  69. virtual BOOL GetInternalProperty(Var instance, PropertyId internalPropertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
  70. virtual BOOL GetAccessors(PropertyId propertyId, Var* getter, Var* setter, ScriptContext * requestContext) override;
  71. virtual BOOL GetPropertyReference(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
  72. virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
  73. virtual BOOL SetProperty(JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
  74. virtual BOOL SetInternalProperty(PropertyId internalPropertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
  75. virtual BOOL InitProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags = PropertyOperation_None, PropertyValueInfo* info = NULL) override;
  76. virtual BOOL EnsureProperty(PropertyId propertyId) override;
  77. virtual BOOL EnsureNoRedeclProperty(PropertyId propertyId) override;
  78. virtual BOOL SetPropertyWithAttributes(PropertyId propertyId, Var value, PropertyAttributes attributes, PropertyValueInfo* info, PropertyOperationFlags flags = PropertyOperation_None, SideEffects possibleSideEffects = SideEffects_Any) override;
  79. virtual BOOL InitPropertyScoped(PropertyId propertyId, Var value) override;
  80. virtual BOOL InitFuncScoped(PropertyId propertyId, Var value) override;
  81. virtual BOOL DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags) override;
  82. virtual BOOL IsFixedProperty(PropertyId propertyId) override;
  83. virtual BOOL HasItem(uint32 index) override;
  84. virtual BOOL HasOwnItem(uint32 index) override;
  85. virtual BOOL GetItem(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
  86. virtual BOOL GetItemReference(Var originalInstance, uint32 index, Var* value, ScriptContext * requestContext) override;
  87. virtual DescriptorFlags GetItemSetter(uint32 index, Var* setterValue, ScriptContext* requestContext) override;
  88. virtual BOOL SetItem(uint32 index, Var value, PropertyOperationFlags flags) override;
  89. virtual BOOL DeleteItem(uint32 index, PropertyOperationFlags flags) override;
  90. virtual BOOL GetEnumerator(BOOL enumNonEnumerable, Var* enumerator, ScriptContext * requestContext, bool preferSnapshotSemantics = true, bool enumSymbols = false) override;
  91. virtual BOOL SetAccessors(PropertyId propertyId, Var getter, Var setter, PropertyOperationFlags flags = PropertyOperation_None) override;
  92. virtual BOOL Equals(Var other, BOOL* value, ScriptContext* requestContext) override;
  93. virtual BOOL StrictEquals(Var other, BOOL* value, ScriptContext* requestContext) override;
  94. virtual BOOL IsWritable(PropertyId propertyId) override;
  95. virtual BOOL IsConfigurable(PropertyId propertyId) override;
  96. virtual BOOL IsEnumerable(PropertyId propertyId) override;
  97. virtual BOOL IsExtensible() override;
  98. virtual BOOL PreventExtensions() override;
  99. virtual void ThrowIfCannotDefineProperty(PropertyId propId, PropertyDescriptor descriptor) { }
  100. virtual void ThrowIfCannotGetOwnPropertyDescriptor(PropertyId propId) {};
  101. virtual BOOL GetDefaultPropertyDescriptor(PropertyDescriptor& descriptor) override;
  102. virtual BOOL Seal() override;
  103. virtual BOOL Freeze() override;
  104. virtual BOOL IsSealed() override;
  105. virtual BOOL IsFrozen() override;
  106. virtual BOOL SetWritable(PropertyId propertyId, BOOL value) override;
  107. virtual BOOL SetConfigurable(PropertyId propertyId, BOOL value) override;
  108. virtual BOOL SetEnumerable(PropertyId propertyId, BOOL value) override;
  109. virtual BOOL SetAttributes(PropertyId propertyId, PropertyAttributes attributes) override;
  110. virtual BOOL GetSpecialPropertyName(uint32 index, Var *propertyName, ScriptContext * requestContext) { return false; }
  111. virtual uint GetSpecialPropertyCount() const { return 0; }
  112. virtual PropertyId const * GetSpecialPropertyIds() const { return nullptr; }
  113. virtual BOOL HasInstance(Var instance, ScriptContext* scriptContext, IsInstInlineCache* inlineCache = NULL) override;
  114. // This is used for external object only; should not be called for proxy
  115. virtual RecyclableObject* GetConfigurablePrototype(ScriptContext * requestContext) override;
  116. virtual RecyclableObject* GetPrototypeSpecial() override;
  117. // for external object. don't need it here.
  118. virtual Js::JavascriptString* GetClassName(ScriptContext * requestContext) override;
  119. #if DBG
  120. virtual bool CanStorePropertyValueDirectly(PropertyId propertyId, bool allowLetConst) { Assert(false); return false; };
  121. #endif
  122. virtual void RemoveFromPrototype(ScriptContext * requestContext) override;
  123. virtual void AddToPrototype(ScriptContext * requestContext) override;
  124. virtual void SetPrototype(RecyclableObject* newPrototype) override;
  125. BOOL SetPrototypeTrap(RecyclableObject* newPrototype, bool showThrow);
  126. Var ToString(Js::ScriptContext* scriptContext);
  127. // proxy does not support IDispatch stuff.
  128. virtual Var GetNamespaceParent(Js::Var aChild) { AssertMsg(false, "Shouldn't call this implementation."); return nullptr; }
  129. virtual HRESULT QueryObjectInterface(REFIID riid, void **ppvObj) { AssertMsg(false, "Shouldn't call this implementation."); return E_NOTIMPL; }
  130. virtual BOOL GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
  131. virtual RecyclableObject* ToObject(ScriptContext * requestContext) override;
  132. virtual Var GetTypeOfString(ScriptContext* requestContext) override;
  133. BOOL SetPropertyTrap(Var receiver, SetPropertyTrapKind setPropertyTrapKind, PropertyId propertyId, Var newValue, ScriptContext* requestContext, BOOL skipPrototypeCheck = FALSE);
  134. BOOL SetPropertyTrap(Var receiver, SetPropertyTrapKind setPropertyTrapKind, Js::JavascriptString * propertyString, Var newValue, ScriptContext* requestContext);
  135. void PropertyIdFromInt(uint32 index, PropertyRecord const** propertyRecord);
  136. Var PropertyKeysTrap(KeysTrapKind keysTrapKind);
  137. template <class Fn>
  138. void GetOwnPropertyKeysHelper(ScriptContext* scriptContext, RecyclableObject* trapResultArray, uint32 len, JavascriptArray* trapResult,
  139. JsUtil::BaseDictionary<Js::PropertyId, bool, ArenaAllocator>& targetToTrapResultMap, Fn fn)
  140. {
  141. Var element;
  142. const PropertyRecord* propertyRecord;
  143. uint32 trapResultIndex = 0;
  144. PropertyId propertyId;
  145. for (uint32 i = 0; i < len; i++)
  146. {
  147. if (!JavascriptOperators::GetItem(trapResultArray, i, &element, scriptContext))
  148. continue;
  149. if (!(JavascriptString::Is(element) || JavascriptSymbol::Is(element)))
  150. {
  151. JavascriptError::ThrowTypeError(scriptContext, JSERR_InconsistentTrapResult, L"ownKeys");
  152. }
  153. JavascriptConversion::ToPropertyKey(element, scriptContext, &propertyRecord);
  154. propertyId = propertyRecord->GetPropertyId();
  155. if (propertyId != Constants::NoProperty)
  156. {
  157. targetToTrapResultMap.Add(propertyId, true);
  158. }
  159. if (fn(propertyRecord))
  160. {
  161. trapResult->DirectSetItemAt(trapResultIndex++, element);
  162. }
  163. }
  164. }
  165. Var ConstructorTrap(Arguments args, ScriptContext* scriptContext, const Js::AuxArray<uint32> *spreadIndices);
  166. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  167. static PropertyId EnsureHandlerPropertyId(ScriptContext* scriptContext);
  168. static RecyclableObject* AutoProxyWrapper(Var obj);
  169. #endif
  170. private:
  171. JavascriptFunction* GetMethodHelper(PropertyId methodId, ScriptContext* requestContext);
  172. Var GetValueFromDescriptor(RecyclableObject* instance, PropertyDescriptor propertyDescriptor, ScriptContext* requestContext);
  173. static Var GetName(ScriptContext* requestContext, PropertyId propertyId);
  174. static BOOL TestIntegrityLevel(IntegrityLevel integrityLevel, RecyclableObject* obj, ScriptContext* scriptContext);
  175. static BOOL SetIntegrityLevel(IntegrityLevel integrityLevel, RecyclableObject* obj, ScriptContext* scriptContext);
  176. template <class Fn, class GetPropertyIdFunc>
  177. BOOL HasPropertyTrap(Fn fn, GetPropertyIdFunc getPropertyId);
  178. template <class Fn, class GetPropertyIdFunc>
  179. BOOL GetPropertyTrap(Var instance, PropertyDescriptor* propertyDescriptor, Fn fn, GetPropertyIdFunc getPropertyId, ScriptContext* requestContext);
  180. template <class Fn, class GetPropertyIdFunc>
  181. BOOL GetPropertyDescriptorTrap(Var originalInstance, Fn fn, GetPropertyIdFunc getPropertyId, PropertyDescriptor* resultDescriptor, ScriptContext* requestContext);
  182. };
  183. }