JsrtSourceHolder.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #pragma once
  6. class ISourceHolder;
  7. namespace Js
  8. {
  9. template <typename TLoadCallback, typename TUnloadCallback>
  10. class JsrtSourceHolder sealed : public ISourceHolder
  11. {
  12. private:
  13. enum MapRequestFor { Source = 1, Length = 2 };
  14. FieldNoBarrier(TLoadCallback) scriptLoadCallback;
  15. FieldNoBarrier(TUnloadCallback) scriptUnloadCallback;
  16. Field(JsSourceContext) sourceContext;
  17. #ifndef NTBUILD
  18. Field(JsValueRef) mappedScriptValue;
  19. Field(DetachedStateBase*) mappedSerializedScriptValue;
  20. #endif
  21. Field(utf8char_t const *) mappedSource;
  22. Field(size_t) mappedSourceByteLength;
  23. Field(size_t) mappedAllocLength;
  24. // Wrapper methods with Asserts to ensure that we aren't trying to access unmapped source
  25. utf8char_t const * GetMappedSource()
  26. {
  27. AssertMsg(mappedSource != nullptr, "Our mapped source is nullptr, isSourceMapped (Assert above) should be false.");
  28. AssertMsg(scriptUnloadCallback != nullptr, "scriptUnloadCallback is null, this means that this object has been finalized.");
  29. return mappedSource;
  30. };
  31. size_t GetMappedSourceLength()
  32. {
  33. AssertMsg(mappedSource != nullptr, "Our mapped source is nullptr, isSourceMapped (Assert above) should be false.");
  34. AssertMsg(scriptUnloadCallback != nullptr, "scriptUnloadCallback is null, this means that this object has been finalized.");
  35. return mappedSourceByteLength;
  36. };
  37. void EnsureSource(MapRequestFor requestedFor, const WCHAR* reasonString);
  38. public:
  39. JsrtSourceHolder(_In_ TLoadCallback scriptLoadCallback,
  40. _In_ TUnloadCallback scriptUnloadCallback,
  41. _In_ JsSourceContext sourceContext,
  42. Js::ArrayBuffer* serializedScriptValue = nullptr) :
  43. scriptLoadCallback(scriptLoadCallback),
  44. scriptUnloadCallback(scriptUnloadCallback),
  45. sourceContext(sourceContext),
  46. #ifndef NTBUILD
  47. mappedScriptValue(nullptr),
  48. mappedSerializedScriptValue(serializedScriptValue == nullptr ? nullptr : serializedScriptValue->DetachAndGetState(false /*queueForDelayFree*/)),
  49. #endif
  50. mappedSourceByteLength(0),
  51. mappedSource(nullptr)
  52. {
  53. AssertMsg(scriptLoadCallback != nullptr, "script load callback given is null.");
  54. AssertMsg(scriptUnloadCallback != nullptr, "script unload callback given is null.");
  55. };
  56. virtual bool IsEmpty() override
  57. {
  58. return false;
  59. }
  60. // Following two methods do not attempt any source mapping
  61. LPCUTF8 GetSourceUnchecked()
  62. {
  63. return this->GetMappedSource();
  64. }
  65. // Following two methods are calls to EnsureSource before attempting to get the source
  66. virtual LPCUTF8 GetSource(const WCHAR* reasonString) override
  67. {
  68. this->EnsureSource(MapRequestFor::Source, reasonString);
  69. return this->GetMappedSource();
  70. }
  71. virtual size_t GetByteLength(const WCHAR* reasonString) override
  72. {
  73. this->EnsureSource(MapRequestFor::Length, reasonString);
  74. return this->GetMappedSourceLength();
  75. }
  76. virtual void Finalize(bool isShutdown) override;
  77. virtual void Dispose(bool isShutdown) override
  78. {
  79. #ifndef NTBUILD
  80. if (this->mappedSerializedScriptValue != nullptr)
  81. {
  82. // We have to extend the buffer data's lifetime until Dispose because
  83. // it might be used during finalization of other objects, such as
  84. // FunctionEntryPointInfo which wants to log its name.
  85. this->mappedSerializedScriptValue->CleanUp();
  86. }
  87. #endif
  88. }
  89. virtual void Mark(Recycler * recycler) override
  90. {
  91. }
  92. virtual void Unload() override;
  93. virtual bool Equals(ISourceHolder* other) override
  94. {
  95. return this == other ||
  96. (this->GetByteLength(_u("Equal Comparison")) == other->GetByteLength(_u("Equal Comparison"))
  97. && (this->GetSource(_u("Equal Comparison")) == other->GetSource(_u("Equal Comparison"))
  98. || memcmp(this->GetSource(_u("Equal Comparison")), other->GetSource(_u("Equal Comparison")), this->GetByteLength(_u("Equal Comparison"))) == 0));
  99. }
  100. virtual hash_t GetHashCode() override
  101. {
  102. LPCUTF8 source = GetSource(_u("Hash Code Calculation"));
  103. size_t byteLength = GetByteLength(_u("Hash Code Calculation"));
  104. Assert(byteLength < MAXUINT32);
  105. return JsUtil::CharacterBuffer<utf8char_t>::StaticGetHashCode(source, (charcount_t)byteLength);
  106. }
  107. virtual bool IsDeferrable() override
  108. {
  109. return !PHASE_OFF1(Js::DeferSourceLoadPhase);
  110. }
  111. };
  112. }